blob: 37cdc25f641f5be1e49f0275fdf44abdd2024e3f [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Manjunathappa Prakash71140072019-01-31 09:40:23 -08002 * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019/**
20 * DOC: HDD WMM
21 *
22 * This module (wlan_hdd_wmm.h interface + wlan_hdd_wmm.c implementation)
23 * houses all the logic for WMM in HDD.
24 *
25 * On the control path, it has the logic to setup QoS, modify QoS and delete
26 * QoS (QoS here refers to a TSPEC). The setup QoS comes in two flavors: an
27 * explicit application invoked and an internal HDD invoked. The implicit QoS
28 * is for applications that do NOT call the custom QCT WLAN OIDs for QoS but
29 * which DO mark their traffic for priortization. It also has logic to start,
30 * update and stop the U-APSD trigger frame generation. It also has logic to
31 * read WMM related config parameters from the registry.
32 *
33 * On the data path, it has the logic to figure out the WMM AC of an egress
34 * packet and when to signal TL to serve a particular AC queue. It also has the
35 * logic to retrieve a packet based on WMM priority in response to a fetch from
36 * TL.
37 *
38 * The remaining functions are utility functions for information hiding.
39 */
40
41/* Include files */
42#include <linux/netdevice.h>
43#include <linux/skbuff.h>
44#include <linux/etherdevice.h>
45#include <linux/if_vlan.h>
46#include <linux/ip.h>
47#include <linux/semaphore.h>
Govind Singhb7ab5772015-10-08 16:38:37 +053048#include <linux/ipv6.h>
Dustin Brown6725e272019-03-06 12:29:47 -080049#include "osif_sync.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080050#include <wlan_hdd_tx_rx.h>
51#include <wlan_hdd_wmm.h>
52#include <wlan_hdd_ether.h>
53#include <wlan_hdd_hostapd.h>
54#include <wlan_hdd_softap_tx_rx.h>
55#include <cds_sched.h>
yeshwanth sriram guntukaa1ba9a22017-02-28 16:17:32 +053056#include "sme_api.h"
Abhinav Kumar18b45cd2018-09-21 12:35:22 +053057#include "wlan_mlme_ucfg_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080058
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080059#define WLAN_HDD_MAX_DSCP 0x3f
60
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080061#define HDD_WMM_UP_TO_AC_MAP_SIZE 8
62
63const uint8_t hdd_wmm_up_to_ac_map[] = {
64 SME_AC_BE,
65 SME_AC_BK,
66 SME_AC_BK,
67 SME_AC_BE,
68 SME_AC_VI,
69 SME_AC_VI,
70 SME_AC_VO,
71 SME_AC_VO
72};
73
74/**
75 * enum hdd_wmm_linuxac: AC/Queue Index values for Linux Qdisc to
76 * operate on different traffic.
77 */
78#ifdef QCA_LL_TX_FLOW_CONTROL_V2
Jeff Johnson5b8b67d2017-08-29 14:16:53 -070079void wlan_hdd_process_peer_unauthorised_pause(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080080{
81 /* Enable HI_PRIO queue */
82 netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VO);
83 netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VI);
84 netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BE);
85 netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BK);
86 netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_HI_PRIO);
87
88}
89#else
Jeff Johnson5b8b67d2017-08-29 14:16:53 -070090void wlan_hdd_process_peer_unauthorised_pause(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080091{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080092}
93#endif
94
95/* Linux based UP -> AC Mapping */
96const uint8_t hdd_linux_up_to_ac_map[HDD_WMM_UP_TO_AC_MAP_SIZE] = {
97 HDD_LINUX_AC_BE,
98 HDD_LINUX_AC_BK,
99 HDD_LINUX_AC_BK,
100 HDD_LINUX_AC_BE,
101 HDD_LINUX_AC_VI,
102 HDD_LINUX_AC_VI,
103 HDD_LINUX_AC_VO,
104 HDD_LINUX_AC_VO
105};
106
107#ifndef WLAN_MDM_CODE_REDUCTION_OPT
108/**
109 * hdd_wmm_enable_tl_uapsd() - function which decides whether and
110 * how to update UAPSD parameters in TL
111 *
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800112 * @qos_context: [in] the pointer the QoS instance control block
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800113 *
114 * Return: None
115 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800116static void hdd_wmm_enable_tl_uapsd(struct hdd_wmm_qos_context *qos_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800117{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800118 struct hdd_adapter *adapter = qos_context->adapter;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800119 sme_ac_enum_type ac_type = qos_context->ac_type;
Jeff Johnson12e12332019-03-08 23:29:23 -0800120 struct hdd_wmm_ac_status *ac = &adapter->hdd_wmm_status.ac_status[ac_type];
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700121 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530122 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800123 uint32_t service_interval;
124 uint32_t suspension_interval;
Abhishek Singh12be60f2017-08-11 13:52:42 +0530125 enum sme_qos_wmm_dir_type direction;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800126 bool psb;
Abhinav Kumarc8c21502018-12-05 15:17:39 +0530127 uint32_t delayed_trgr_frm_int;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800128
129 /* The TSPEC must be valid */
Jeff Johnson0698e662019-03-09 14:24:32 -0800130 if (ac->is_tspec_valid == false) {
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700131 hdd_err("Invoked with invalid TSPEC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800132 return;
133 }
134 /* determine the service interval */
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800135 if (ac->tspec.min_service_interval) {
136 service_interval = ac->tspec.min_service_interval;
137 } else if (ac->tspec.max_service_interval) {
138 service_interval = ac->tspec.max_service_interval;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800139 } else {
140 /* no service interval is present in the TSPEC */
141 /* this is OK, there just won't be U-APSD */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700142 hdd_debug("No service interval supplied");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800143 service_interval = 0;
144 }
145
146 /* determine the suspension interval & direction */
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800147 suspension_interval = ac->tspec.suspension_interval;
148 direction = ac->tspec.ts_info.direction;
149 psb = ac->tspec.ts_info.psb;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800150
151 /* if we have previously enabled U-APSD, have any params changed? */
Jeff Johnsonfd297092019-03-09 14:29:20 -0800152 if ((ac->is_uapsd_info_valid) &&
Jeff Johnsone8f3a772019-03-09 14:36:12 -0800153 (ac->uapsd_service_interval == service_interval) &&
Jeff Johnson48fffec2019-03-09 14:37:27 -0800154 (ac->uapsd_suspension_interval == suspension_interval) &&
Jeff Johnson68a8a9a2019-03-09 14:39:51 -0800155 (ac->uapsd_direction == direction) &&
Jeff Johnsona86be852019-03-09 14:34:25 -0800156 (ac->is_uapsd_enabled == psb)) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700157 hdd_debug("No change in U-APSD parameters");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800158 return;
159 }
Abhinav Kumarc8c21502018-12-05 15:17:39 +0530160
161 ucfg_mlme_get_tl_delayed_trgr_frm_int(hdd_ctx->psoc,
162 &delayed_trgr_frm_int);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800163 /* everything is in place to notify TL */
164 status =
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700165 sme_enable_uapsd_for_ac((WLAN_HDD_GET_STATION_CTX_PTR(adapter))->
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800166 conn_info.sta_id[0], ac_type,
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800167 ac->tspec.ts_info.tid,
168 ac->tspec.ts_info.up,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800169 service_interval, suspension_interval,
Jeff Johnson9597f3b2019-02-04 14:27:56 -0800170 direction, psb, adapter->vdev_id,
Abhinav Kumarc8c21502018-12-05 15:17:39 +0530171 delayed_trgr_frm_int);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800172
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530173 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800174 hdd_err("Failed to enable U-APSD for AC=%d", ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800175 return;
176 }
177 /* stash away the parameters that were used */
Jeff Johnsonfd297092019-03-09 14:29:20 -0800178 ac->is_uapsd_info_valid = true;
Jeff Johnsone8f3a772019-03-09 14:36:12 -0800179 ac->uapsd_service_interval = service_interval;
Jeff Johnson48fffec2019-03-09 14:37:27 -0800180 ac->uapsd_suspension_interval = suspension_interval;
Jeff Johnson68a8a9a2019-03-09 14:39:51 -0800181 ac->uapsd_direction = direction;
Jeff Johnsona86be852019-03-09 14:34:25 -0800182 ac->is_uapsd_enabled = psb;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800183
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700184 hdd_debug("Enabled UAPSD in TL srv_int=%d susp_int=%d dir=%d AC=%d",
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800185 service_interval, suspension_interval, direction, ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800186
187}
188
189/**
190 * hdd_wmm_disable_tl_uapsd() - function which decides whether
191 * to disable UAPSD parameters in TL
192 *
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800193 * @qos_context: [in] the pointer the QoS instance control block
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800194 *
195 * Return: None
196 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800197static void hdd_wmm_disable_tl_uapsd(struct hdd_wmm_qos_context *qos_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800198{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800199 struct hdd_adapter *adapter = qos_context->adapter;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800200 sme_ac_enum_type ac_type = qos_context->ac_type;
Jeff Johnson12e12332019-03-08 23:29:23 -0800201 struct hdd_wmm_ac_status *ac = &adapter->hdd_wmm_status.ac_status[ac_type];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530202 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800203
204 /* have we previously enabled UAPSD? */
Jeff Johnsonfd297092019-03-09 14:29:20 -0800205 if (ac->is_uapsd_info_valid == true) {
Sreelakshmi Konamkie1ce5622015-11-23 15:04:05 +0530206 status =
Jeff Johnsona1e92612017-09-24 15:33:44 -0700207 sme_disable_uapsd_for_ac((WLAN_HDD_GET_STATION_CTX_PTR
Jeff Johnson0a082d92019-03-04 12:25:49 -0800208 (adapter))->conn_info.sta_id[0],
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800209 ac_type, adapter->vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800210
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530211 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800212 hdd_err("Failed to disable U-APSD for AC=%d", ac_type);
Sreelakshmi Konamkie1ce5622015-11-23 15:04:05 +0530213 } else {
214 /* TL no longer has valid UAPSD info */
Jeff Johnsonfd297092019-03-09 14:29:20 -0800215 ac->is_uapsd_info_valid = false;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800216 hdd_debug("Disabled UAPSD in TL for AC=%d", ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800217 }
218 }
219}
220
221#endif
222
223/**
224 * hdd_wmm_free_context() - function which frees a QoS context
225 *
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800226 * @qos_context: [in] the pointer the QoS instance control block
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800227 *
228 * Return: None
229 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800230static void hdd_wmm_free_context(struct hdd_wmm_qos_context *qos_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800231{
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700232 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800233
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800234 hdd_debug("Entered, context %pK", qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800235
Jeff Johnsond36fa332019-03-18 13:42:25 -0700236 if (unlikely((!qos_context) ||
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800237 (HDD_WMM_CTX_MAGIC != qos_context->magic))) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800238 /* must have been freed in another thread */
239 return;
240 }
241 /* get pointer to the adapter context */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800242 adapter = qos_context->adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800243
Jeff Johnson12e12332019-03-08 23:29:23 -0800244 /* take the mutex since we're manipulating the context list */
245 mutex_lock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800246
247 /* make sure nobody thinks this is a valid context */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800248 qos_context->magic = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800249
250 /* unlink the context */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800251 list_del(&qos_context->node);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800252
253 /* done manipulating the list */
Jeff Johnson12e12332019-03-08 23:29:23 -0800254 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800255
256 /* reclaim memory */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800257 qdf_mem_free(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800258
259}
260
261#ifndef WLAN_MDM_CODE_REDUCTION_OPT
262/**
263 * hdd_wmm_notify_app() - function which notifies an application
264 * of changes in state of it flow
265 *
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800266 * @qos_context: [in] the pointer the QoS instance control block
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800267 *
268 * Return: None
269 */
270#define MAX_NOTIFY_LEN 50
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800271static void hdd_wmm_notify_app(struct hdd_wmm_qos_context *qos_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800272{
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700273 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800274 union iwreq_data wrqu;
275 char buf[MAX_NOTIFY_LEN + 1];
276
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800277 hdd_debug("Entered, context %pK", qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800278
Jeff Johnsond36fa332019-03-18 13:42:25 -0700279 if (unlikely((!qos_context) ||
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800280 (HDD_WMM_CTX_MAGIC != qos_context->magic))) {
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700281 hdd_err("Invalid QoS Context");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800282 return;
283 }
284
285 /* create the event */
286 memset(&wrqu, 0, sizeof(wrqu));
287 memset(buf, 0, sizeof(buf));
288
289 snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]",
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800290 (unsigned int)qos_context->handle,
Jeff Johnson5b052512019-03-08 19:32:14 -0800291 (unsigned int)qos_context->status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800292
293 wrqu.data.pointer = buf;
294 wrqu.data.length = strlen(buf);
295
296 /* get pointer to the adapter */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800297 adapter = qos_context->adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800298
299 /* send the event */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700300 hdd_debug("Sending [%s]", buf);
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700301 wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu, buf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800302}
303
304#ifdef FEATURE_WLAN_ESE
305/**
306 * hdd_wmm_inactivity_timer_cb() - inactivity timer callback function
307 *
308 * @user_data: opaque user data registered with the timer. In the
309 * case of this timer, the associated wmm QoS context is registered.
310 *
311 * This timer handler function is called for every inactivity interval
312 * per AC. This function gets the current transmitted packets on the
313 * given AC, and checks if there was any TX activity from the previous
314 * interval. If there was no traffic then it would delete the TS that
315 * was negotiated on that AC.
316 *
317 * Return: None
318 */
319static void hdd_wmm_inactivity_timer_cb(void *user_data)
320{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800321 struct hdd_wmm_qos_context *qos_context = user_data;
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700322 struct hdd_adapter *adapter;
Jeff Johnson4d209002019-03-08 20:27:25 -0800323 struct hdd_wmm_ac_status *ac;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800324 hdd_wlan_wmm_status_e status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530325 QDF_STATUS qdf_status;
Jeff Johnson15bf1b12019-03-09 14:59:58 -0800326 uint32_t traffic_count = 0;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800327 sme_ac_enum_type ac_type;
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530328
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800329 if (!qos_context) {
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530330 hdd_err("invalid user data");
331 return;
332 }
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800333 ac_type = qos_context->ac_type;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800334
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800335 adapter = qos_context->adapter;
Jeff Johnsond36fa332019-03-18 13:42:25 -0700336 if ((!adapter) ||
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700337 (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
338 hdd_err("invalid adapter: %pK", adapter);
c_hpothud5009242016-08-18 12:10:36 +0530339 return;
340 }
341
Jeff Johnson12e12332019-03-08 23:29:23 -0800342 ac = &adapter->hdd_wmm_status.ac_status[ac_type];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800343
344 /* Get the Tx stats for this AC. */
Jeff Johnson15bf1b12019-03-09 14:59:58 -0800345 traffic_count =
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800346 adapter->hdd_stats.tx_rx_stats.tx_classified_ac[qos_context->
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800347 ac_type];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800348
Jeff Johnsonde474b42019-03-09 14:58:07 -0800349 hdd_warn("WMM inactivity check for AC=%d, count=%u, last=%u",
Jeff Johnson15bf1b12019-03-09 14:59:58 -0800350 ac_type, traffic_count, ac->last_traffic_count);
351 if (ac->last_traffic_count == traffic_count) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800352 /* there is no traffic activity, delete the TSPEC for this AC */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800353 status = hdd_wmm_delts(adapter, qos_context->handle);
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700354 hdd_warn("Deleted TS on AC %d, due to inactivity with status = %d!!!",
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800355 ac_type, status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800356 } else {
Jeff Johnson15bf1b12019-03-09 14:59:58 -0800357 ac->last_traffic_count = traffic_count;
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800358 if (ac->inactivity_timer.state == QDF_TIMER_STATE_STOPPED) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800359 /* Restart the timer */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530360 qdf_status =
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800361 qdf_mc_timer_start(&ac->inactivity_timer,
Jeff Johnson154193b2019-03-09 14:42:58 -0800362 ac->inactivity_time);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530363 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700364 hdd_err("Restarting inactivity timer failed on AC %d",
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800365 ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800366 }
367 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530368 QDF_ASSERT(qdf_mc_timer_get_current_state
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800369 (&ac->inactivity_timer) ==
Anurag Chouhan210db072016-02-22 18:42:15 +0530370 QDF_TIMER_STATE_STOPPED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800371 }
372 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800373}
374
375/**
376 * hdd_wmm_enable_inactivity_timer() -
377 * function to enable the traffic inactivity timer for the given AC
378 *
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800379 * @qos_context: [in] pointer to qos_context
Jeff Johnson0a12bbc2019-03-09 15:14:30 -0800380 * @inactivity_time: [in] value of the inactivity interval in millisecs
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800381 *
382 * When a QoS-Tspec is successfully setup, if the inactivity interval
383 * time specified in the AddTS parameters is non-zero, this function
384 * is invoked to start a traffic inactivity timer for the given AC.
385 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530386 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800387 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530388static QDF_STATUS
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800389hdd_wmm_enable_inactivity_timer(struct hdd_wmm_qos_context *qos_context,
Jeff Johnson0a12bbc2019-03-09 15:14:30 -0800390 uint32_t inactivity_time)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800391{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530392 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800393 struct hdd_adapter *adapter = qos_context->adapter;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800394 sme_ac_enum_type ac_type = qos_context->ac_type;
Jeff Johnson4d209002019-03-08 20:27:25 -0800395 struct hdd_wmm_ac_status *ac;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800396
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800397 adapter = qos_context->adapter;
Jeff Johnson12e12332019-03-08 23:29:23 -0800398 ac = &adapter->hdd_wmm_status.ac_status[ac_type];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800399
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800400 qdf_status = qdf_mc_timer_init(&ac->inactivity_timer,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530401 QDF_TIMER_TYPE_SW,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800402 hdd_wmm_inactivity_timer_cb,
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800403 qos_context);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530404 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700405 hdd_err("Initializing inactivity timer failed on AC %d",
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800406 ac_type);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530407 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800408 }
409 /* Start the inactivity timer */
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800410 qdf_status = qdf_mc_timer_start(&ac->inactivity_timer,
Jeff Johnson0a12bbc2019-03-09 15:14:30 -0800411 inactivity_time);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530412 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700413 hdd_err("Starting inactivity timer failed on AC %d",
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800414 ac_type);
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800415 qdf_status = qdf_mc_timer_destroy(&ac->inactivity_timer);
Srinivas Girigowda576b2352017-08-25 14:44:26 -0700416 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800417 hdd_err("Failed to destroy inactivity timer");
Srinivas Girigowda576b2352017-08-25 14:44:26 -0700418
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530419 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800420 }
Jeff Johnson0a12bbc2019-03-09 15:14:30 -0800421 ac->inactivity_time = inactivity_time;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800422 /* Initialize the current tx traffic count on this AC */
Jeff Johnsonde474b42019-03-09 14:58:07 -0800423 ac->last_traffic_count =
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800424 adapter->hdd_stats.tx_rx_stats.tx_classified_ac[qos_context->
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800425 ac_type];
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800426 qos_context->is_inactivity_timer_running = true;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530427 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800428}
429
430/**
431 * hdd_wmm_disable_inactivity_timer() -
432 * function to disable the traffic inactivity timer for the given AC.
433 *
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800434 * @qos_context: [in] pointer to qos_context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800435 *
436 * This function is invoked to disable the traffic inactivity timer
437 * for the given AC. This is normally done when the TS is deleted.
438 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530439 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800440 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530441static QDF_STATUS
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800442hdd_wmm_disable_inactivity_timer(struct hdd_wmm_qos_context *qos_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800443{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800444 struct hdd_adapter *adapter = qos_context->adapter;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800445 sme_ac_enum_type ac_type = qos_context->ac_type;
Jeff Johnson12e12332019-03-08 23:29:23 -0800446 struct hdd_wmm_ac_status *ac = &adapter->hdd_wmm_status.ac_status[ac_type];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530447 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800448
449 /* Clear the timer and the counter */
Jeff Johnson154193b2019-03-09 14:42:58 -0800450 ac->inactivity_time = 0;
Jeff Johnsonde474b42019-03-09 14:58:07 -0800451 ac->last_traffic_count = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800452
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800453 if (qos_context->is_inactivity_timer_running == true) {
454 qos_context->is_inactivity_timer_running = false;
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800455 qdf_status = qdf_mc_timer_stop(&ac->inactivity_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530456 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800457 hdd_err("Failed to stop inactivity timer");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530458 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800459 }
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800460 qdf_status = qdf_mc_timer_destroy(&ac->inactivity_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530461 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800462 hdd_err("Failed to destroy inactivity timer:Timer started");
463 }
464
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530465 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800466}
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530467#else
468
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530469static QDF_STATUS
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800470hdd_wmm_disable_inactivity_timer(struct hdd_wmm_qos_context *qos_context)
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530471{
472 return QDF_STATUS_SUCCESS;
473}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800474#endif /* FEATURE_WLAN_ESE */
475
476/**
477 * hdd_wmm_sme_callback() - callback for QoS notifications
478 *
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -0700479 * @mac_handle: [in] the MAC handle
480 * @context : [in] the HDD callback context
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800481 * @tspec_info : [in] the TSPEC params
Jeff Johnson2059fd72019-03-08 20:06:59 -0800482 * @sme_status : [in] the QoS related SME status
Jeff Johnson104f70e2019-03-08 19:29:33 -0800483 * @flow_id: [in] the unique identifier of the flow
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800484 *
485 * This callback is registered by HDD with SME for receiving QoS
486 * notifications. Even though this function has a static scope it
487 * gets called externally through some function pointer magic (so
488 * there is a need for rigorous parameter checking).
489 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530490 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800491 */
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -0700492static QDF_STATUS hdd_wmm_sme_callback(mac_handle_t mac_handle,
493 void *context,
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800494 struct sme_qos_wmmtspecinfo *tspec_info,
Jeff Johnson2059fd72019-03-08 20:06:59 -0800495 enum sme_qos_statustype sme_status,
Jeff Johnson104f70e2019-03-08 19:29:33 -0800496 uint32_t flow_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800497{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800498 struct hdd_wmm_qos_context *qos_context = context;
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700499 struct hdd_adapter *adapter;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800500 sme_ac_enum_type ac_type;
Jeff Johnson4d209002019-03-08 20:27:25 -0800501 struct hdd_wmm_ac_status *ac;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800502
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800503 hdd_debug("Entered, context %pK", qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800504
Jeff Johnsond36fa332019-03-18 13:42:25 -0700505 if (unlikely((!qos_context) ||
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800506 (HDD_WMM_CTX_MAGIC != qos_context->magic))) {
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700507 hdd_err("Invalid QoS Context");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530508 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800509 }
510
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800511 adapter = qos_context->adapter;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800512 ac_type = qos_context->ac_type;
Jeff Johnson12e12332019-03-08 23:29:23 -0800513 ac = &adapter->hdd_wmm_status.ac_status[ac_type];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800514
Jeff Johnson36e74c42017-09-18 08:15:42 -0700515 hdd_debug("status %d flowid %d info %pK",
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800516 sme_status, flow_id, tspec_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800517
Jeff Johnson2059fd72019-03-08 20:06:59 -0800518 switch (sme_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800519
520 case SME_QOS_STATUS_SETUP_SUCCESS_IND:
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +0530521 hdd_debug("Setup is complete");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800522
523 /* there will always be a TSPEC returned with this
524 * status, even if a TSPEC is not exchanged OTA
525 */
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800526 if (tspec_info) {
Jeff Johnson0698e662019-03-09 14:24:32 -0800527 ac->is_tspec_valid = true;
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800528 memcpy(&ac->tspec,
529 tspec_info, sizeof(ac->tspec));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800530 }
Jeff Johnsona5548972019-03-09 14:22:18 -0800531 ac->is_access_allowed = true;
Jeff Johnsonc77123d2019-03-09 14:18:34 -0800532 ac->was_access_granted = true;
Jeff Johnsone5b75be2019-03-09 14:07:35 -0800533 ac->is_access_pending = false;
Jeff Johnson1b48ccb2019-03-09 14:15:57 -0800534 ac->has_access_failed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800535
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800536 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800537
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700538 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800539
540 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800541 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800542 HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800543 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800544 }
545
546#ifdef FEATURE_WLAN_ESE
547 /* Check if the inactivity interval is specified */
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800548 if (tspec_info && tspec_info->inactivity_interval) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700549 hdd_debug("Inactivity timer value = %d for AC=%d",
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800550 tspec_info->inactivity_interval, ac_type);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800551 hdd_wmm_enable_inactivity_timer(qos_context,
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800552 tspec_info->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800553 inactivity_interval);
554 }
555#endif /* FEATURE_WLAN_ESE */
556
557 /* notify TL to enable trigger frames if necessary */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800558 hdd_wmm_enable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800559
560 break;
561
562 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700563 hdd_debug("Setup is complete (U-APSD set previously)");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800564
Jeff Johnsona5548972019-03-09 14:22:18 -0800565 ac->is_access_allowed = true;
Jeff Johnsonc77123d2019-03-09 14:18:34 -0800566 ac->was_access_granted = true;
Jeff Johnsone5b75be2019-03-09 14:07:35 -0800567 ac->is_access_pending = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800568
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800569 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800570
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700571 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800572
573 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800574 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800575 HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800576 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800577 }
578
579 break;
580
581 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700582 hdd_err("Setup failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800583 /* QoS setup failed */
584
Jeff Johnsone5b75be2019-03-09 14:07:35 -0800585 ac->is_access_pending = false;
Jeff Johnson1b48ccb2019-03-09 14:15:57 -0800586 ac->has_access_failed = true;
Jeff Johnsona5548972019-03-09 14:22:18 -0800587 ac->is_access_allowed = false;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800588 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800589
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700590 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800591
592 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800593 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800594 HDD_WLAN_WMM_STATUS_SETUP_FAILED;
595
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800596 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800597 }
598
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530599 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800600 hdd_wmm_disable_inactivity_timer(qos_context);
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530601
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800602 /* Setting up QoS Failed, QoS context can be released.
603 * SME is releasing this flow information and if HDD
604 * doesn't release this context, next time if
605 * application uses the same handle to set-up QoS, HDD
606 * (as it has QoS context for this handle) will issue
607 * Modify QoS request to SME but SME will reject as now
608 * it has no information for this flow.
609 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800610 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800611 break;
612
613 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700614 hdd_err("Setup Invalid Params, notify TL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800615 /* QoS setup failed */
Jeff Johnsona5548972019-03-09 14:22:18 -0800616 ac->is_access_allowed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800617
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800618 if (HDD_WMM_HANDLE_IMPLICIT == qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800619
620 /* we note the failure, but we also mark
621 * access as allowed so that the packets will
622 * flow. Note that the MAC will "do the right
623 * thing"
624 */
Jeff Johnsone5b75be2019-03-09 14:07:35 -0800625 ac->is_access_pending = false;
Jeff Johnson1b48ccb2019-03-09 14:15:57 -0800626 ac->has_access_failed = true;
Jeff Johnsona5548972019-03-09 14:22:18 -0800627 ac->is_access_allowed = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800628
629 } else {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700630 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800631
632 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800633 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800634 HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800635 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800636 }
637 break;
638
639 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700640 hdd_err("Setup failed, not a QoS AP");
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800641 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Dustin Brown5e89ef82018-03-14 11:50:23 -0700642 hdd_info("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800643
644 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800645 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800646 HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800647 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800648 }
649 break;
650
651 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700652 hdd_debug("Setup pending");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800653 /* not a callback status -- ignore if we get it */
654 break;
655
656 case SME_QOS_STATUS_SETUP_MODIFIED_IND:
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700657 hdd_debug("Setup modified");
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800658 if (tspec_info) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800659 /* update the TSPEC */
Jeff Johnson0698e662019-03-09 14:24:32 -0800660 ac->is_tspec_valid = true;
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800661 memcpy(&ac->tspec,
662 tspec_info, sizeof(ac->tspec));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800663
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800664 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700665 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800666
667 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800668 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800669 HDD_WLAN_WMM_STATUS_MODIFIED;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800670 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800671 }
672 /* need to tell TL to update its UAPSD handling */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800673 hdd_wmm_enable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800674 }
675 break;
676
677 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800678 if (HDD_WMM_HANDLE_IMPLICIT == qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800679
680 /* this was triggered by implicit QoS so we
681 * know packets are pending
682 */
Jeff Johnsone5b75be2019-03-09 14:07:35 -0800683 ac->is_access_pending = false;
Jeff Johnsonc77123d2019-03-09 14:18:34 -0800684 ac->was_access_granted = true;
Jeff Johnsona5548972019-03-09 14:22:18 -0800685 ac->is_access_allowed = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800686
687 } else {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700688 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800689
690 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800691 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800692 HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800693 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800694 }
695 break;
696
697 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
698 /* nothing to do for now */
699 break;
700
701 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED:
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700702 hdd_err("Setup successful but U-APSD failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800703
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800704 if (HDD_WMM_HANDLE_IMPLICIT == qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800705
706 /* QoS setup was successful but setting U=APSD
707 * failed. Since the OTA part of the request
708 * was successful, we don't mark this as a
709 * failure. the packets will flow. Note that
Jeff Johnson1677bbb2017-01-12 08:39:19 -0800710 * the MAC will "do the right thing"
711 */
Jeff Johnsonc77123d2019-03-09 14:18:34 -0800712 ac->was_access_granted = true;
Jeff Johnsona5548972019-03-09 14:22:18 -0800713 ac->is_access_allowed = true;
Jeff Johnson1b48ccb2019-03-09 14:15:57 -0800714 ac->has_access_failed = false;
Jeff Johnsone5b75be2019-03-09 14:07:35 -0800715 ac->is_access_pending = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800716
717 } else {
Dustin Brown5e89ef82018-03-14 11:50:23 -0700718 hdd_info("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800719
720 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800721 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800722 HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800723 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800724 }
725
726 /* Since U-APSD portion failed disabled trigger frame
727 * generation
728 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800729 hdd_wmm_disable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800730
731 break;
732
733 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700734 hdd_debug("Release is complete");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800735
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800736 if (tspec_info) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700737 hdd_debug("flows still active");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800738
739 /* there is still at least one flow active for
740 * this AC so update the AC state
741 */
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800742 memcpy(&ac->tspec,
743 tspec_info, sizeof(ac->tspec));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800744
745 /* need to tell TL to update its UAPSD handling */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800746 hdd_wmm_enable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800747 } else {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700748 hdd_debug("last flow");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800749
750 /* this is the last flow active for this AC so
751 * update the AC state
752 */
Jeff Johnson0698e662019-03-09 14:24:32 -0800753 ac->is_tspec_valid = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800754
755 /* DELTS is successful, do not allow */
Jeff Johnsona5548972019-03-09 14:22:18 -0800756 ac->is_access_allowed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800757
758 /* need to tell TL to update its UAPSD handling */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800759 hdd_wmm_disable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800760 }
761
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800762 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700763 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800764
765 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800766 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800767 HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800768 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800769 }
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530770 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800771 hdd_wmm_disable_inactivity_timer(qos_context);
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530772
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800773 /* we are done with this flow */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800774 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800775 break;
776
777 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700778 hdd_debug("Release failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800779
780 /* we don't need to update our state or TL since
781 * nothing has changed
782 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800783 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700784 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800785
786 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800787 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800788 HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800789 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800790 }
791
792 break;
793
794 case SME_QOS_STATUS_RELEASE_QOS_LOST_IND:
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700795 hdd_debug("QOS Lost indication received");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800796
797 /* current TSPEC is no longer valid */
Jeff Johnson0698e662019-03-09 14:24:32 -0800798 ac->is_tspec_valid = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800799 /* AP has sent DELTS, do not allow */
Jeff Johnsona5548972019-03-09 14:22:18 -0800800 ac->is_access_allowed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800801
802 /* need to tell TL to update its UAPSD handling */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800803 hdd_wmm_disable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800804
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800805 if (HDD_WMM_HANDLE_IMPLICIT == qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800806 /* we no longer have implicit access granted */
Jeff Johnsonc77123d2019-03-09 14:18:34 -0800807 ac->was_access_granted = false;
Jeff Johnson1b48ccb2019-03-09 14:15:57 -0800808 ac->has_access_failed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800809 } else {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700810 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800811
812 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800813 qos_context->status = HDD_WLAN_WMM_STATUS_LOST;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800814 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800815 }
816
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530817 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800818 hdd_wmm_disable_inactivity_timer(qos_context);
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530819
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800820 /* we are done with this flow */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800821 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800822 break;
823
824 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +0530825 hdd_debug("Release pending");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800826 /* not a callback status -- ignore if we get it */
827 break;
828
829 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700830 hdd_err("Release Invalid Params");
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800831 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800832 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800833 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800834 HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800835 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800836 }
837 break;
838
839 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND:
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +0530840 hdd_debug("Modification is complete, notify TL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800841
842 /* there will always be a TSPEC returned with this
843 * status, even if a TSPEC is not exchanged OTA
844 */
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800845 if (tspec_info) {
Jeff Johnson0698e662019-03-09 14:24:32 -0800846 ac->is_tspec_valid = true;
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800847 memcpy(&ac->tspec,
848 tspec_info, sizeof(ac->tspec));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800849 }
850
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800851 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800852 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800853 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800854 HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800855 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800856 }
857 /* notify TL to enable trigger frames if necessary */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800858 hdd_wmm_enable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800859
860 break;
861
862 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800863 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800864 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800865 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800866 HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800867 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800868 }
869 break;
870
871 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
872 /* the flow modification failed so we'll leave in
873 * place whatever existed beforehand
874 */
875
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800876 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800877 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800878 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800879 HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800880 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800881 }
882 break;
883
884 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +0530885 hdd_debug("modification pending");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800886 /* not a callback status -- ignore if we get it */
887 break;
888
889 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
890 /* the flow modification was successful but no QoS
891 * changes required
892 */
893
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800894 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800895 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800896 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800897 HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800898 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800899 }
900 break;
901
902 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
903 /* invalid params -- notify the application */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800904 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800905 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800906 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800907 HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800908 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800909 }
910 break;
911
912 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING:
913 /* nothing to do for now. when APSD is established we'll have work to do */
914 break;
915
916 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED:
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700917 hdd_err("Modify successful but U-APSD failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800918
919 /* QoS modification was successful but setting U=APSD
920 * failed. This will always be an explicit QoS
921 * instance, so all we can do is notify the
922 * application and let it clean up.
923 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800924 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800926 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800927 HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800928 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800929 }
930 /* Since U-APSD portion failed disabled trigger frame
931 * generation
932 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800933 hdd_wmm_disable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800934
935 break;
936
937 case SME_QOS_STATUS_HANDING_OFF:
938 /* no roaming so we won't see this */
939 break;
940
941 case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND:
942 /* need to tell TL to stop trigger frame generation */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800943 hdd_wmm_disable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800944 break;
945
946 case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND:
947 /* need to tell TL to start sending trigger frames again */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800948 hdd_wmm_enable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800949 break;
950
951 default:
Jeff Johnson2059fd72019-03-08 20:06:59 -0800952 hdd_err("unexpected SME Status=%d", sme_status);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530953 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800954 }
955
956 /* if Tspec only allows downstream traffic then access is not
957 * allowed
958 */
Jeff Johnson0698e662019-03-09 14:24:32 -0800959 if (ac->is_tspec_valid &&
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800960 (ac->tspec.ts_info.direction ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800961 SME_QOS_WMM_TS_DIR_DOWNLINK)) {
Jeff Johnsona5548972019-03-09 14:22:18 -0800962 ac->is_access_allowed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800963 }
964 /* if we have valid Tpsec or if ACM bit is not set, allow access */
Jeff Johnson0698e662019-03-09 14:24:32 -0800965 if ((ac->is_tspec_valid &&
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800966 (ac->tspec.ts_info.direction !=
Jeff Johnson30ac84f2019-03-09 13:57:57 -0800967 SME_QOS_WMM_TS_DIR_DOWNLINK)) || !ac->is_access_required) {
Jeff Johnsona5548972019-03-09 14:22:18 -0800968 ac->is_access_allowed = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800969 }
970
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700971 hdd_debug("complete, access for TL AC %d is%sallowed",
Jeff Johnsona5548972019-03-09 14:22:18 -0800972 ac_type, ac->is_access_allowed ? " " : " not ");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800973
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530974 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800975}
976#endif
977
978/**
979 * hdd_wmmps_helper() - Function to set uapsd psb dynamically
980 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700981 * @adapter: [in] pointer to adapter structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800982 * @ptr: [in] pointer to command buffer
983 *
984 * Return: Zero on success, appropriate error on failure.
985 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700986int hdd_wmmps_helper(struct hdd_adapter *adapter, uint8_t *ptr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800987{
Jeff Johnsond36fa332019-03-18 13:42:25 -0700988 if (!adapter) {
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700989 hdd_err("adapter is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800990 return -EINVAL;
991 }
Jeff Johnsond36fa332019-03-18 13:42:25 -0700992 if (!ptr) {
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700993 hdd_err("ptr is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800994 return -EINVAL;
995 }
996 /* convert ASCII to integer */
Jeff Johnson137c8ee2017-10-28 13:06:48 -0700997 adapter->configured_psb = ptr[9] - '0';
998 adapter->psb_changed = HDD_PSB_CHANGED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800999
1000 return 0;
1001}
1002
1003/**
1004 * __hdd_wmm_do_implicit_qos() - Function which will attempt to setup
Dustin Brown6725e272019-03-06 12:29:47 -08001005 * QoS for any AC requiring it.
1006 * @qos_context: the QoS context to operate against
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001007 *
1008 * Return: none
1009 */
Dustin Brown6725e272019-03-06 12:29:47 -08001010static void __hdd_wmm_do_implicit_qos(struct hdd_wmm_qos_context *qos_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001011{
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001012 struct hdd_adapter *adapter;
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001013 sme_ac_enum_type ac_type;
Jeff Johnson4d209002019-03-08 20:27:25 -08001014 struct hdd_wmm_ac_status *ac;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001015#ifndef WLAN_MDM_CODE_REDUCTION_OPT
Jeff Johnson2059fd72019-03-08 20:06:59 -08001016 enum sme_qos_statustype sme_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001017#endif
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001018 struct sme_qos_wmmtspecinfo tspec;
Jeff Johnson1083b6e2017-08-28 11:35:22 -07001019 struct hdd_context *hdd_ctx;
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07001020 mac_handle_t mac_handle;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301021 QDF_STATUS status = QDF_STATUS_SUCCESS;
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05301022 uint8_t dir_ac, mask = 0;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301023 uint16_t nom_msdu_size_ac = 0;
1024 uint32_t rate_ac = 0;
1025 uint16_t sba_ac = 0;
1026 uint32_t uapsd_value = 0;
Abhinav Kumarab576712018-11-05 14:32:49 +05301027 bool is_ts_burst_enable;
1028 enum mlme_ts_info_ack_policy ack_policy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001029
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001030 hdd_debug("Entered, context %pK", qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001031
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001032 adapter = qos_context->adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001033
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001034 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05301035 if (wlan_hdd_validate_context(hdd_ctx))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001036 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001037
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07001038 mac_handle = hdd_ctx->mac_handle;
1039
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001040 ac_type = qos_context->ac_type;
Jeff Johnson12e12332019-03-08 23:29:23 -08001041 ac = &adapter->hdd_wmm_status.ac_status[ac_type];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001042
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001043 hdd_debug("adapter %pK ac_type %d", adapter, ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001044
Jeff Johnson12ccaf62019-03-09 13:59:53 -08001045 if (!ac->is_access_needed) {
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001046 hdd_err("AC %d doesn't need service", ac_type);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001047 qos_context->magic = 0;
1048 qdf_mem_free(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001049 return;
1050 }
1051
Jeff Johnsone5b75be2019-03-09 14:07:35 -08001052 ac->is_access_pending = true;
Jeff Johnson12ccaf62019-03-09 13:59:53 -08001053 ac->is_access_needed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001054
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001055 memset(&tspec, 0, sizeof(tspec));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001056
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001057 tspec.ts_info.psb = adapter->configured_psb;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001058
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001059 switch (ac_type) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001060 case SME_AC_VO:
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001061 tspec.ts_info.up = SME_QOS_WMM_UP_VO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001062 /* Check if there is any valid configuration from framework */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001063 if (HDD_PSB_CFG_INVALID == adapter->configured_psb) {
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05301064 status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc,
1065 &mask);
1066 if (!QDF_IS_STATUS_SUCCESS(status)) {
1067 hdd_err("Get uapsd_mask failed");
1068 return;
1069 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001070 tspec.ts_info.psb = (mask & SME_QOS_UAPSD_VO) ? 1 : 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001071 }
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301072 status = ucfg_mlme_get_wmm_dir_ac_vo(hdd_ctx->psoc,
1073 &dir_ac);
1074 if (!QDF_IS_STATUS_SUCCESS(status)) {
1075 hdd_err("Get infra_dir_ac_vo failed");
1076 return;
1077 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001078 tspec.ts_info.direction = dir_ac;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301079
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001080 tspec.ts_info.tid = 255;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301081
1082 status = ucfg_mlme_get_wmm_uapsd_vo_srv_intv(hdd_ctx->psoc,
1083 &uapsd_value);
1084 if (QDF_IS_STATUS_ERROR(status)) {
1085 hdd_err("Get uapsd_srv_intv failed");
1086 return;
1087 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001088 tspec.min_service_interval = uapsd_value;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301089
1090 status = ucfg_mlme_get_wmm_uapsd_vo_sus_intv(hdd_ctx->psoc,
1091 &uapsd_value);
1092 if (QDF_IS_STATUS_ERROR(status)) {
1093 hdd_err("Get uapsd_vo_sus_intv failed");
1094 return;
1095 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001096 tspec.suspension_interval = uapsd_value;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301097
1098 status = ucfg_mlme_get_wmm_mean_data_rate_ac_vo(hdd_ctx->psoc,
1099 &rate_ac);
1100 if (QDF_IS_STATUS_ERROR(status)) {
1101 hdd_err("Get mean_data_rate_ac_vo failed");
1102 return;
1103 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001104 tspec.mean_data_rate = rate_ac;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301105
1106 status = ucfg_mlme_get_wmm_min_phy_rate_ac_vo(hdd_ctx->psoc,
1107 &rate_ac);
1108 if (QDF_IS_STATUS_ERROR(status)) {
1109 hdd_err("Get min_phy_rate_ac_vo failed");
1110 return;
1111 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001112 tspec.min_phy_rate = rate_ac;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301113
1114 status = ucfg_mlme_get_wmm_nom_msdu_size_ac_vo(hdd_ctx->psoc,
1115 &nom_msdu_size_ac);
1116 if (QDF_IS_STATUS_ERROR(status)) {
1117 hdd_err("Get nom_msdu_size_ac_vo failed");
1118 return;
1119 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001120 tspec.nominal_msdu_size = nom_msdu_size_ac;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301121
1122 status = ucfg_mlme_get_wmm_sba_ac_vo(hdd_ctx->psoc,
1123 &sba_ac);
1124 if (!QDF_IS_STATUS_SUCCESS(status)) {
1125 hdd_err("Get sba_ac_vo failed");
1126 return;
1127 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001128 tspec.surplus_bw_allowance = sba_ac;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301129
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001130 break;
1131 case SME_AC_VI:
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001132 tspec.ts_info.up = SME_QOS_WMM_UP_VI;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001133 /* Check if there is any valid configuration from framework */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001134 if (HDD_PSB_CFG_INVALID == adapter->configured_psb) {
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05301135 status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc,
1136 &mask);
1137 if (!QDF_IS_STATUS_SUCCESS(status)) {
1138 hdd_err("Get uapsd_mask failed");
1139 return;
1140 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001141 tspec.ts_info.psb = (mask & SME_QOS_UAPSD_VI) ? 1 : 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001142 }
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301143 status = ucfg_mlme_get_wmm_dir_ac_vi(
1144 hdd_ctx->psoc, &dir_ac);
1145 if (!QDF_IS_STATUS_SUCCESS(status)) {
1146 hdd_err("Get infra_dir_ac_vi failed");
1147 return;
1148 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001149 tspec.ts_info.direction = dir_ac;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301150
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001151 tspec.ts_info.tid = 255;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301152 status = ucfg_mlme_get_wmm_uapsd_vi_srv_intv(
1153 hdd_ctx->psoc, &uapsd_value);
1154 if (!QDF_IS_STATUS_SUCCESS(status)) {
1155 hdd_err("Get uapsd_vi_srv_intv failed");
1156 return;
1157 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001158 tspec.min_service_interval = uapsd_value;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301159
1160 status = ucfg_mlme_get_wmm_uapsd_vi_sus_intv(
1161 hdd_ctx->psoc, &uapsd_value);
1162 if (!QDF_IS_STATUS_SUCCESS(status)) {
1163 hdd_err("Get uapsd_vi_sus_intv failed");
1164 return;
1165 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001166 tspec.suspension_interval = uapsd_value;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301167
1168 status = ucfg_mlme_get_wmm_mean_data_rate_ac_vi(
1169 hdd_ctx->psoc, &rate_ac);
1170 if (!QDF_IS_STATUS_SUCCESS(status)) {
1171 hdd_err("Get mean_data_rate_ac_vi failed");
1172 return;
1173 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001174 tspec.mean_data_rate = rate_ac;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301175
1176 status = ucfg_mlme_get_wmm_min_phy_rate_ac_vi(
1177 hdd_ctx->psoc, &rate_ac);
1178 if (!QDF_IS_STATUS_SUCCESS(status)) {
1179 hdd_err("Get min_phy_rate_ac_vi failed");
1180 return;
1181 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001182 tspec.min_phy_rate = rate_ac;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301183
1184 status = ucfg_mlme_get_wmm_nom_msdu_size_ac_vi(
1185 hdd_ctx->psoc, &nom_msdu_size_ac);
1186 if (!QDF_IS_STATUS_SUCCESS(status)) {
1187 hdd_err("Get nom_msdu_size_ac_vi failed");
1188 return;
1189 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001190 tspec.nominal_msdu_size = nom_msdu_size_ac;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301191
1192 status = ucfg_mlme_get_wmm_sba_ac_vi(
1193 hdd_ctx->psoc, &sba_ac);
1194 if (!QDF_IS_STATUS_SUCCESS(status)) {
1195 hdd_err("Get sba_ac_vi failed");
1196 return;
1197 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001198 tspec.surplus_bw_allowance = sba_ac;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301199
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001200 break;
1201 default:
1202 case SME_AC_BE:
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001203 tspec.ts_info.up = SME_QOS_WMM_UP_BE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001204 /* Check if there is any valid configuration from framework */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001205 if (HDD_PSB_CFG_INVALID == adapter->configured_psb) {
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05301206 status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc,
1207 &mask);
1208 if (!QDF_IS_STATUS_SUCCESS(status)) {
1209 hdd_err("Get uapsd_mask failed");
1210 return;
1211 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001212 tspec.ts_info.psb = (mask & SME_QOS_UAPSD_BE) ? 1 : 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001213 }
Abhinav Kumare94f2482018-08-19 12:37:36 +05301214 status = ucfg_mlme_get_wmm_dir_ac_be(hdd_ctx->psoc, &dir_ac);
1215 if (!QDF_IS_STATUS_SUCCESS(status)) {
1216 hdd_err("Get infra_dir_ac_be failed");
1217 return;
1218 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001219 tspec.ts_info.direction = dir_ac;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301220
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001221 tspec.ts_info.tid = 255;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301222 status = ucfg_mlme_get_wmm_uapsd_be_srv_intv(hdd_ctx->psoc,
1223 &uapsd_value);
1224 if (!QDF_IS_STATUS_SUCCESS(status)) {
1225 hdd_err("Get uapsd_vi_srv_intv failed");
1226 return;
1227 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001228 tspec.min_service_interval = uapsd_value;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301229
1230 status = ucfg_mlme_get_wmm_uapsd_be_sus_intv(hdd_ctx->psoc,
1231 &uapsd_value);
1232 if (!QDF_IS_STATUS_SUCCESS(status)) {
1233 hdd_err("Get uapsd_vi_sus_intv failed");
1234 return;
1235 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001236 tspec.suspension_interval = uapsd_value;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301237
1238 status = ucfg_mlme_get_wmm_mean_data_rate_ac_be(hdd_ctx->psoc,
1239 &rate_ac);
1240 if (!QDF_IS_STATUS_SUCCESS(status)) {
1241 hdd_err("Get mean_data_rate_ac_be failed");
1242 return;
1243 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001244 tspec.mean_data_rate = rate_ac;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301245
1246 status = ucfg_mlme_get_wmm_min_phy_rate_ac_be(hdd_ctx->psoc,
1247 &rate_ac);
1248 if (!QDF_IS_STATUS_SUCCESS(status)) {
1249 hdd_err("Get min_phy_rate_ac_be failed");
1250 return;
1251 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001252 tspec.min_phy_rate = rate_ac;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301253
1254 status = ucfg_mlme_get_wmm_nom_msdu_size_ac_be(hdd_ctx->psoc,
1255 &nom_msdu_size_ac);
1256 if (!QDF_IS_STATUS_SUCCESS(status)) {
1257 hdd_err("Get nom_msdu_size_ac_be failed");
1258 return;
1259 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001260 tspec.nominal_msdu_size = nom_msdu_size_ac;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301261
1262 status = ucfg_mlme_get_wmm_sba_ac_be(hdd_ctx->psoc, &sba_ac);
1263 if (!QDF_IS_STATUS_SUCCESS(status)) {
1264 hdd_err("Get sba_ac_be failed");
1265 return;
1266 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001267 tspec.surplus_bw_allowance = sba_ac;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301268
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001269 break;
1270 case SME_AC_BK:
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001271 tspec.ts_info.up = SME_QOS_WMM_UP_BK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001272 /* Check if there is any valid configuration from framework */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001273 if (HDD_PSB_CFG_INVALID == adapter->configured_psb) {
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05301274 status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc,
1275 &mask);
1276 if (!QDF_IS_STATUS_SUCCESS(status)) {
1277 hdd_err("Get uapsd_mask failed");
1278 return;
1279 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001280 tspec.ts_info.psb = (mask & SME_QOS_UAPSD_BK) ? 1 : 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001281 }
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301282
1283 status = ucfg_mlme_get_wmm_dir_ac_bk(hdd_ctx->psoc, &dir_ac);
1284 if (!QDF_IS_STATUS_SUCCESS(status)) {
1285 hdd_err("Get infra_dir_ac_bk failed");
1286 return;
1287 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001288 tspec.ts_info.direction = dir_ac;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301289
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001290 tspec.ts_info.tid = 255;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301291 status = ucfg_mlme_get_wmm_uapsd_bk_srv_intv(hdd_ctx->psoc,
1292 &uapsd_value);
1293 if (!QDF_IS_STATUS_SUCCESS(status)) {
1294 hdd_err("Get uapsd_bk_srv_intv failed");
1295 return;
1296 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001297 tspec.min_service_interval = uapsd_value;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301298
1299 status = ucfg_mlme_get_wmm_uapsd_bk_sus_intv(hdd_ctx->psoc,
1300 &uapsd_value);
1301 if (!QDF_IS_STATUS_SUCCESS(status)) {
1302 hdd_err("Get uapsd_bk_sus_intv failed");
1303 return;
1304 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001305 tspec.suspension_interval = uapsd_value;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301306
1307 status = ucfg_mlme_get_wmm_mean_data_rate_ac_bk(hdd_ctx->psoc,
1308 &rate_ac);
1309 if (!QDF_IS_STATUS_SUCCESS(status)) {
1310 hdd_err("Get mean_data_rate_ac_bk failed");
1311 return;
1312 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001313 tspec.mean_data_rate = rate_ac;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301314
1315 status = ucfg_mlme_get_wmm_min_phy_rate_ac_bk(hdd_ctx->psoc,
1316 &rate_ac);
1317 if (!QDF_IS_STATUS_SUCCESS(status)) {
1318 hdd_err("Get min_phy_rate_ac_bk failed");
1319 return;
1320 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001321 tspec.min_phy_rate = rate_ac;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301322
1323 status =
1324 ucfg_mlme_get_wmm_nom_msdu_size_ac_bk(hdd_ctx->psoc,
1325 &nom_msdu_size_ac);
1326 if (!QDF_IS_STATUS_SUCCESS(status)) {
1327 hdd_err("Get nom_msdu_size_ac_bk failed");
1328 return;
1329 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001330 tspec.nominal_msdu_size = nom_msdu_size_ac;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301331
1332 status = ucfg_mlme_get_wmm_sba_ac_bk(hdd_ctx->psoc, &sba_ac);
1333 if (!QDF_IS_STATUS_SUCCESS(status)) {
1334 hdd_err("Get sba_ac_bk failed");
1335 return;
1336 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001337 tspec.surplus_bw_allowance = sba_ac;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301338
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001339 break;
1340 }
1341#ifdef FEATURE_WLAN_ESE
Abhinav Kumarab576712018-11-05 14:32:49 +05301342 ucfg_mlme_get_inactivity_interval(hdd_ctx->psoc, &uapsd_value);
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001343 tspec.inactivity_interval = uapsd_value;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344#endif
Abhinav Kumarab576712018-11-05 14:32:49 +05301345 ucfg_mlme_get_is_ts_burst_size_enable(hdd_ctx->psoc,
1346 &is_ts_burst_enable);
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001347 tspec.ts_info.burst_size_defn = is_ts_burst_enable;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001348
Abhinav Kumarab576712018-11-05 14:32:49 +05301349 ucfg_mlme_get_ts_info_ack_policy(hdd_ctx->psoc, &ack_policy);
1350 switch (ack_policy) {
1351 case TS_INFO_ACK_POLICY_NORMAL_ACK:
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001352 tspec.ts_info.ack_policy =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001353 SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1354 break;
1355
Abhinav Kumarab576712018-11-05 14:32:49 +05301356 case TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001357 tspec.ts_info.ack_policy =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001358 SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
1359 break;
1360
1361 default:
1362 /* unknown */
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001363 tspec.ts_info.ack_policy =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001364 SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1365 }
1366
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001367 if (tspec.ts_info.ack_policy ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001368 SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK) {
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001369 if (!sme_qos_is_ts_info_ack_policy_valid(mac_handle, &tspec,
Jeff Johnson9597f3b2019-02-04 14:27:56 -08001370 adapter->vdev_id)) {
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001371 tspec.ts_info.ack_policy =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001372 SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1373 }
1374 }
1375
Jeff Johnson12e12332019-03-08 23:29:23 -08001376 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnson8f656c62019-03-09 08:48:27 -08001377 list_add(&qos_context->node, &adapter->hdd_wmm_status.context_list);
Jeff Johnson12e12332019-03-08 23:29:23 -08001378 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001379
1380#ifndef WLAN_MDM_CODE_REDUCTION_OPT
Jeff Johnson2059fd72019-03-08 20:06:59 -08001381 sme_status = sme_qos_setup_req(mac_handle,
1382 adapter->vdev_id,
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001383 &tspec,
Jeff Johnson2059fd72019-03-08 20:06:59 -08001384 hdd_wmm_sme_callback,
1385 qos_context,
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001386 tspec.ts_info.up,
Jeff Johnson2059fd72019-03-08 20:06:59 -08001387 &qos_context->flow_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001388
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001389 hdd_debug("sme_qos_setup_req returned %d flowid %d",
Jeff Johnson2059fd72019-03-08 20:06:59 -08001390 sme_status, qos_context->flow_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001391
1392 /* need to check the return values and act appropriately */
Jeff Johnson2059fd72019-03-08 20:06:59 -08001393 switch (sme_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001394 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
1395 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
1396 /* setup is pending, so no more work to do now. all
1397 * further work will be done in hdd_wmm_sme_callback()
1398 */
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +05301399 hdd_debug("Setup is pending, no further work");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001400
1401 break;
1402
1403 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05301404 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001405 hdd_wmm_disable_inactivity_timer(qos_context);
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05301406
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001407 /* we can't tell the difference between when a request
1408 * fails because AP rejected it versus when SME
1409 * encountered an internal error. in either case SME
1410 * won't ever reference this context so free the
1411 * record
1412 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001413 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001414
1415 /* fall through and start packets flowing */
1416 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1417 /* no ACM in effect, no need to setup U-APSD */
1418 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
1419 /* no ACM in effect, U-APSD is desired but was already setup */
1420
1421 /* for these cases everything is already setup so we
1422 * can signal TL that it has work to do
1423 */
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +05301424 hdd_debug("Setup is complete, notify TL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001425
Jeff Johnsona5548972019-03-09 14:22:18 -08001426 ac->is_access_allowed = true;
Jeff Johnsonc77123d2019-03-09 14:18:34 -08001427 ac->was_access_granted = true;
Jeff Johnsone5b75be2019-03-09 14:07:35 -08001428 ac->is_access_pending = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001429
1430 break;
1431
1432 default:
Jeff Johnson2059fd72019-03-08 20:06:59 -08001433 hdd_err("unexpected SME Status=%d", sme_status);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301434 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001435 }
1436#endif
1437
1438}
1439
1440/**
1441 * hdd_wmm_do_implicit_qos() - SSR wraper function for hdd_wmm_do_implicit_qos
1442 * @work: pointer to work_struct
1443 *
1444 * Return: none
1445 */
1446static void hdd_wmm_do_implicit_qos(struct work_struct *work)
1447{
Dustin Brown6725e272019-03-06 12:29:47 -08001448 struct hdd_wmm_qos_context *qos_ctx =
1449 container_of(work, struct hdd_wmm_qos_context,
Jeff Johnson7d4a0b52019-03-08 22:06:32 -08001450 implicit_qos_work);
Dustin Brown6725e272019-03-06 12:29:47 -08001451 struct osif_vdev_sync *vdev_sync;
1452
1453 if (qos_ctx->magic != HDD_WMM_CTX_MAGIC) {
1454 hdd_err("Invalid QoS Context");
1455 return;
1456 }
1457
1458 if (osif_vdev_sync_op_start(qos_ctx->adapter->dev, &vdev_sync))
1459 return;
1460
1461 __hdd_wmm_do_implicit_qos(qos_ctx);
1462
1463 osif_vdev_sync_op_stop(vdev_sync);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001464}
1465
1466/**
1467 * hdd_wmm_init() - initialize the WMM DSCP configuation
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001468 * @adapter : [in] pointer to Adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001469 *
1470 * This function will initialize the WMM DSCP configuation of an
1471 * adapter to an initial state. The configuration can later be
1472 * overwritten via application APIs or via QoS Map sent OTA.
1473 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301474 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001475 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001476QDF_STATUS hdd_wmm_init(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001477{
Jeff Johnson6b51b6a2017-11-02 20:31:25 -07001478 enum sme_qos_wmmuptype *dscp_to_up_map = adapter->dscp_to_up_map;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001479 uint8_t dscp;
1480
Dustin Brown491d54b2018-03-14 12:39:11 -07001481 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001482
1483 /* DSCP to User Priority Lookup Table
1484 * By default use the 3 Precedence bits of DSCP as the User Priority
1485 */
Srinivas Girigowda576b2352017-08-25 14:44:26 -07001486 for (dscp = 0; dscp <= WLAN_HDD_MAX_DSCP; dscp++)
Jeff Johnson6b51b6a2017-11-02 20:31:25 -07001487 dscp_to_up_map[dscp] = dscp >> 3;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001488
1489 /* Special case for Expedited Forwarding (DSCP 46) */
Jeff Johnson6b51b6a2017-11-02 20:31:25 -07001490 dscp_to_up_map[46] = SME_QOS_WMM_UP_VO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001491
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301492 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001493}
1494
1495/**
1496 * hdd_wmm_adapter_init() - initialize the WMM configuration of an adapter
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001497 * @adapter: [in] pointer to Adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001498 *
1499 * This function will initialize the WMM configuation and status of an
1500 * adapter to an initial state. The configuration can later be
1501 * overwritten via application APIs
1502 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301503 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001504 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001505QDF_STATUS hdd_wmm_adapter_init(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001506{
Jeff Johnsond37476e2019-03-08 20:20:30 -08001507 struct hdd_wmm_ac_status *ac_status;
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001508 sme_ac_enum_type ac_type;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001509
Dustin Brown491d54b2018-03-14 12:39:11 -07001510 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001511
Jeff Johnson26ef71e2019-03-08 23:24:29 -08001512 adapter->hdd_wmm_status.qap = false;
Jeff Johnson8f656c62019-03-09 08:48:27 -08001513 INIT_LIST_HEAD(&adapter->hdd_wmm_status.context_list);
Jeff Johnson12e12332019-03-08 23:29:23 -08001514 mutex_init(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001515
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001516 for (ac_type = 0; ac_type < WLAN_MAX_AC; ac_type++) {
Jeff Johnson12e12332019-03-08 23:29:23 -08001517 ac_status = &adapter->hdd_wmm_status.ac_status[ac_type];
Jeff Johnson30ac84f2019-03-09 13:57:57 -08001518 ac_status->is_access_required = false;
Jeff Johnson12ccaf62019-03-09 13:59:53 -08001519 ac_status->is_access_needed = false;
Jeff Johnsone5b75be2019-03-09 14:07:35 -08001520 ac_status->is_access_pending = false;
Jeff Johnson1b48ccb2019-03-09 14:15:57 -08001521 ac_status->has_access_failed = false;
Jeff Johnsonc77123d2019-03-09 14:18:34 -08001522 ac_status->was_access_granted = false;
Jeff Johnsona5548972019-03-09 14:22:18 -08001523 ac_status->is_access_allowed = false;
Jeff Johnson0698e662019-03-09 14:24:32 -08001524 ac_status->is_tspec_valid = false;
Jeff Johnsonfd297092019-03-09 14:29:20 -08001525 ac_status->is_uapsd_info_valid = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001526 }
1527 /* Invalid value(0xff) to indicate psb not configured through
1528 * framework initially.
1529 */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001530 adapter->configured_psb = HDD_PSB_CFG_INVALID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001531
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301532 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001533}
1534
1535/**
1536 * hdd_wmm_adapter_clear() - Function which will clear the WMM status
1537 * for all the ACs
1538 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001539 * @adapter: [in] pointer to Adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001540 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301541 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001542 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001543QDF_STATUS hdd_wmm_adapter_clear(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001544{
Jeff Johnsond37476e2019-03-08 20:20:30 -08001545 struct hdd_wmm_ac_status *ac_status;
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001546 sme_ac_enum_type ac_type;
Jeff Johnson5ae20e92016-08-19 13:51:48 -07001547
Dustin Brown491d54b2018-03-14 12:39:11 -07001548 hdd_enter();
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001549 for (ac_type = 0; ac_type < WLAN_MAX_AC; ac_type++) {
Jeff Johnson12e12332019-03-08 23:29:23 -08001550 ac_status = &adapter->hdd_wmm_status.ac_status[ac_type];
Jeff Johnson30ac84f2019-03-09 13:57:57 -08001551 ac_status->is_access_required = false;
Jeff Johnson12ccaf62019-03-09 13:59:53 -08001552 ac_status->is_access_needed = false;
Jeff Johnsone5b75be2019-03-09 14:07:35 -08001553 ac_status->is_access_pending = false;
Jeff Johnson1b48ccb2019-03-09 14:15:57 -08001554 ac_status->has_access_failed = false;
Jeff Johnsonc77123d2019-03-09 14:18:34 -08001555 ac_status->was_access_granted = false;
Jeff Johnsona5548972019-03-09 14:22:18 -08001556 ac_status->is_access_allowed = false;
Jeff Johnson0698e662019-03-09 14:24:32 -08001557 ac_status->is_tspec_valid = false;
Jeff Johnsonfd297092019-03-09 14:29:20 -08001558 ac_status->is_uapsd_info_valid = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001559 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301560 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001561}
1562
1563/**
1564 * hdd_wmm_close() - WMM close function
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001565 * @adapter: [in] pointer to adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001566 *
1567 * Function which will perform any necessary work to to clean up the
1568 * WMM functionality prior to the kernel module unload.
1569 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301570 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001571 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001572QDF_STATUS hdd_wmm_adapter_close(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001573{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001574 struct hdd_wmm_qos_context *qos_context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001575
Dustin Brown491d54b2018-03-14 12:39:11 -07001576 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001577
1578 /* free any context records that we still have linked */
Jeff Johnson8f656c62019-03-09 08:48:27 -08001579 while (!list_empty(&adapter->hdd_wmm_status.context_list)) {
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001580 qos_context =
Jeff Johnson8f656c62019-03-09 08:48:27 -08001581 list_first_entry(&adapter->hdd_wmm_status.context_list,
Srinivas Girigowdaea32d6a2017-03-25 00:03:12 -07001582 struct hdd_wmm_qos_context, node);
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05301583
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001584 hdd_wmm_disable_inactivity_timer(qos_context);
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05301585
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001586 if (qos_context->handle == HDD_WMM_HANDLE_IMPLICIT
1587 && qos_context->magic == HDD_WMM_CTX_MAGIC)
Jeff Johnson7d4a0b52019-03-08 22:06:32 -08001588 cds_flush_work(&qos_context->implicit_qos_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001589
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001590 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001591 }
1592
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301593 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001594}
1595
1596/**
1597 * hdd_wmm_classify_pkt() - Function which will classify an OS packet
Govind Singhb7ab5772015-10-08 16:38:37 +05301598 * into a WMM AC based on DSCP
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001599 *
Govind Singhb7ab5772015-10-08 16:38:37 +05301600 * @adapter: adapter upon which the packet is being transmitted
1601 * @skb: pointer to network buffer
1602 * @user_pri: user priority of the OS packet
1603 * @is_eapol: eapol packet flag
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001604 *
1605 * Return: None
1606 */
1607static
Jeff Johnson5b8b67d2017-08-29 14:16:53 -07001608void hdd_wmm_classify_pkt(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001609 struct sk_buff *skb,
Abhishek Singh12be60f2017-08-11 13:52:42 +05301610 enum sme_qos_wmmuptype *user_pri,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001611 bool *is_eapol)
1612{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001613 unsigned char dscp;
Govind Singhb7ab5772015-10-08 16:38:37 +05301614 unsigned char tos;
1615 union generic_ethhdr *eth_hdr;
1616 struct iphdr *ip_hdr;
1617 struct ipv6hdr *ipv6hdr;
1618 unsigned char *pkt;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001619
1620 /* this code is executed for every packet therefore
1621 * all debug code is kept conditional
1622 */
1623
1624#ifdef HDD_WMM_DEBUG
Dustin Brown491d54b2018-03-14 12:39:11 -07001625 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001626#endif /* HDD_WMM_DEBUG */
1627
Govind Singhb7ab5772015-10-08 16:38:37 +05301628 pkt = skb->data;
1629 eth_hdr = (union generic_ethhdr *)pkt;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001630
1631#ifdef HDD_WMM_DEBUG
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001632 hdd_debug("proto is 0x%04x", skb->protocol);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001633#endif /* HDD_WMM_DEBUG */
1634
Govind Singhb7ab5772015-10-08 16:38:37 +05301635 if (eth_hdr->eth_II.h_proto == htons(ETH_P_IP)) {
1636 /* case 1: Ethernet II IP packet */
1637 ip_hdr = (struct iphdr *)&pkt[sizeof(eth_hdr->eth_II)];
1638 tos = ip_hdr->tos;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001639#ifdef HDD_WMM_DEBUG
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001640 hdd_debug("Ethernet II IP Packet, tos is %d", tos);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001641#endif /* HDD_WMM_DEBUG */
1642
Govind Singhb7ab5772015-10-08 16:38:37 +05301643 } else if (eth_hdr->eth_II.h_proto == htons(ETH_P_IPV6)) {
1644 ipv6hdr = ipv6_hdr(skb);
1645 tos = ntohs(*(const __be16 *)ipv6hdr) >> 4;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001646#ifdef HDD_WMM_DEBUG
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001647 hdd_debug("Ethernet II IPv6 Packet, tos is %d", tos);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001648#endif /* HDD_WMM_DEBUG */
Govind Singhb7ab5772015-10-08 16:38:37 +05301649 } else if ((ntohs(eth_hdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
1650 (eth_hdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
1651 (eth_hdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
1652 (eth_hdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1653 (eth_hdr->eth_8023.h_proto == htons(ETH_P_IP))) {
1654 /* case 2: 802.3 LLC/SNAP IP packet */
1655 ip_hdr = (struct iphdr *)&pkt[sizeof(eth_hdr->eth_8023)];
1656 tos = ip_hdr->tos;
1657#ifdef HDD_WMM_DEBUG
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001658 hdd_debug("802.3 LLC/SNAP IP Packet, tos is %d", tos);
Govind Singhb7ab5772015-10-08 16:38:37 +05301659#endif /* HDD_WMM_DEBUG */
1660 } else if (eth_hdr->eth_II.h_proto == htons(ETH_P_8021Q)) {
1661 /* VLAN tagged */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001662
Govind Singhb7ab5772015-10-08 16:38:37 +05301663 if (eth_hdr->eth_IIv.h_vlan_encapsulated_proto ==
1664 htons(ETH_P_IP)) {
1665 /* case 3: Ethernet II vlan-tagged IP packet */
1666 ip_hdr =
1667 (struct iphdr *)
1668 &pkt[sizeof(eth_hdr->eth_IIv)];
1669 tos = ip_hdr->tos;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001670#ifdef HDD_WMM_DEBUG
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001671 hdd_debug("Ether II VLAN tagged IP Packet, tos is %d",
Jeff Johnson5ae20e92016-08-19 13:51:48 -07001672 tos);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001673#endif /* HDD_WMM_DEBUG */
Srinivas Girigowda683726a2018-09-07 15:10:40 -07001674 } else if ((ntohs(eth_hdr->eth_IIv.h_vlan_encapsulated_proto)
1675 < WLAN_MIN_PROTO) &&
1676 (eth_hdr->eth_8023v.h_snap.dsap ==
Govind Singhb7ab5772015-10-08 16:38:37 +05301677 WLAN_SNAP_DSAP)
1678 && (eth_hdr->eth_8023v.h_snap.ssap ==
1679 WLAN_SNAP_SSAP)
1680 && (eth_hdr->eth_8023v.h_snap.ctrl ==
1681 WLAN_SNAP_CTRL)
1682 && (eth_hdr->eth_8023v.h_proto ==
1683 htons(ETH_P_IP))) {
1684 /* case 4: 802.3 LLC/SNAP vlan-tagged IP packet */
1685 ip_hdr =
1686 (struct iphdr *)
1687 &pkt[sizeof(eth_hdr->eth_8023v)];
1688 tos = ip_hdr->tos;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001689#ifdef HDD_WMM_DEBUG
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001690 hdd_debug("802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
Jeff Johnson5ae20e92016-08-19 13:51:48 -07001691 tos);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001692#endif /* HDD_WMM_DEBUG */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001693 } else {
1694 /* default */
1695#ifdef HDD_WMM_DEBUG
Jeff Johnson5ae20e92016-08-19 13:51:48 -07001696 hdd_warn("VLAN tagged Unhandled Protocol, using default tos");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001697#endif /* HDD_WMM_DEBUG */
Govind Singhb7ab5772015-10-08 16:38:37 +05301698 tos = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001699 }
1700 } else {
1701 /* default */
1702#ifdef HDD_WMM_DEBUG
Jeff Johnson5ae20e92016-08-19 13:51:48 -07001703 hdd_warn("Unhandled Protocol, using default tos");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001704#endif /* HDD_WMM_DEBUG */
Govind Singhb7ab5772015-10-08 16:38:37 +05301705 /* Give the highest priority to 802.1x packet */
1706 if (eth_hdr->eth_II.h_proto ==
1707 htons(HDD_ETHERTYPE_802_1_X)) {
1708 tos = 0xC0;
1709 *is_eapol = true;
1710 } else
1711 tos = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001712 }
1713
Govind Singhb7ab5772015-10-08 16:38:37 +05301714 dscp = (tos >> 2) & 0x3f;
Jeff Johnson6b51b6a2017-11-02 20:31:25 -07001715 *user_pri = adapter->dscp_to_up_map[dscp];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001716
1717#ifdef HDD_WMM_DEBUG
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001718 hdd_debug("tos is %d, dscp is %d, up is %d", tos, dscp, *user_pri);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001719#endif /* HDD_WMM_DEBUG */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001720}
1721
Jeff Johnsone54e2ae2016-07-18 17:56:20 -07001722/**
1723 * __hdd_get_queue_index() - get queue index
1724 * @up: user priority
1725 *
1726 * Return: queue_index
1727 */
1728static uint16_t __hdd_get_queue_index(uint16_t up)
1729{
1730 if (qdf_unlikely(up >= ARRAY_SIZE(hdd_linux_up_to_ac_map)))
1731 return HDD_LINUX_AC_BE;
1732 return hdd_linux_up_to_ac_map[up];
1733}
1734
hangtianb9c91362019-06-07 10:39:38 +08001735#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || \
1736 defined(QCA_HL_NETDEV_FLOW_CONTROL) || \
1737 defined(QCA_LL_PDEV_TX_FLOW_CONTROL)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001738/**
1739 * hdd_get_queue_index() - get queue index
1740 * @up: user priority
1741 * @is_eapol: is_eapol flag
1742 *
1743 * Return: queue_index
1744 */
1745static
1746uint16_t hdd_get_queue_index(uint16_t up, bool is_eapol)
1747{
Anurag Chouhanc5548422016-02-24 18:33:27 +05301748 if (qdf_unlikely(is_eapol == true))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001749 return HDD_LINUX_AC_HI_PRIO;
Jeff Johnsone54e2ae2016-07-18 17:56:20 -07001750 return __hdd_get_queue_index(up);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001751}
1752#else
1753static
1754uint16_t hdd_get_queue_index(uint16_t up, bool is_eapol)
1755{
Jeff Johnsone54e2ae2016-07-18 17:56:20 -07001756 return __hdd_get_queue_index(up);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001757}
1758#endif
1759
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001760/**
1761 * hdd_wmm_select_queue() - Function which will classify the packet
1762 * according to linux qdisc expectation.
1763 *
1764 * @dev: [in] pointer to net_device structure
1765 * @skb: [in] pointer to os packet
1766 *
1767 * Return: Qdisc queue index
1768 */
Manjunathappa Prakash71140072019-01-31 09:40:23 -08001769static uint16_t hdd_wmm_select_queue(struct net_device *dev,
1770 struct sk_buff *skb)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001771{
Abhishek Singh12be60f2017-08-11 13:52:42 +05301772 enum sme_qos_wmmuptype up = SME_QOS_WMM_UP_BE;
Jeff Johnson55c43882019-03-09 15:59:55 -08001773 uint16_t index;
Rakesh Pillai3e534db2017-09-26 18:59:43 +05301774 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1775 bool is_crtical = false;
1776 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Mukul Sharmabfd19ba2015-10-30 20:35:35 +05301777 int status;
Rakesh Pillai3e534db2017-09-26 18:59:43 +05301778 enum qdf_proto_subtype proto_subtype;
Mukul Sharmabfd19ba2015-10-30 20:35:35 +05301779
1780 status = wlan_hdd_validate_context(hdd_ctx);
1781 if (status != 0) {
1782 skb->priority = SME_QOS_WMM_UP_BE;
1783 return HDD_LINUX_AC_BE;
1784 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001785
Govind Singhb7ab5772015-10-08 16:38:37 +05301786 /* Get the user priority from IP header */
Rakesh Pillai3e534db2017-09-26 18:59:43 +05301787 hdd_wmm_classify_pkt(adapter, skb, &up, &is_crtical);
1788 spin_lock_bh(&adapter->pause_map_lock);
1789 if ((adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL)) &&
1790 !(adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL_PRIORITY))) {
1791 if (qdf_nbuf_is_ipv4_arp_pkt(skb))
1792 is_crtical = true;
1793 else if (qdf_nbuf_is_icmpv6_pkt(skb)) {
1794 proto_subtype = qdf_nbuf_get_icmpv6_subtype(skb);
1795 switch (proto_subtype) {
1796 case QDF_PROTO_ICMPV6_NA:
1797 case QDF_PROTO_ICMPV6_NS:
1798 is_crtical = true;
1799 break;
1800 default:
1801 break;
1802 }
1803 }
1804 }
1805 spin_unlock_bh(&adapter->pause_map_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001806 skb->priority = up;
Jeff Johnson55c43882019-03-09 15:59:55 -08001807 index = hdd_get_queue_index(skb->priority, is_crtical);
Govind Singhb7ab5772015-10-08 16:38:37 +05301808
Jeff Johnson55c43882019-03-09 15:59:55 -08001809 return index;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001810}
1811
Manjunathappa Prakash666898e2019-01-31 10:01:15 -08001812#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
1813uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb,
1814 struct net_device *sb_dev,
1815 select_queue_fallback_t fallback)
Manjunathappa Prakash71140072019-01-31 09:40:23 -08001816{
1817 return hdd_wmm_select_queue(dev, skb);
1818}
Manjunathappa Prakash666898e2019-01-31 10:01:15 -08001819#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
1820uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb,
1821 void *accel_priv, select_queue_fallback_t fallback)
1822{
1823 return hdd_wmm_select_queue(dev, skb);
1824}
1825#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
1826uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb,
1827 void *accel_priv)
1828{
1829 return hdd_wmm_select_queue(dev, skb);
1830}
1831#else
1832uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb)
1833{
1834 return hdd_wmm_select_queue(dev, skb);
1835}
1836#endif
1837
Manjunathappa Prakash71140072019-01-31 09:40:23 -08001838
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001839/**
1840 * hdd_wmm_acquire_access_required() - Function which will determine
1841 * acquire admittance for a WMM AC is required or not based on psb configuration
1842 * done in framework
1843 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001844 * @adapter: [in] pointer to adapter structure
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001845 * @ac_type: [in] WMM AC type of OS packet
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001846 *
1847 * Return: void
1848 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001849void hdd_wmm_acquire_access_required(struct hdd_adapter *adapter,
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001850 sme_ac_enum_type ac_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001851{
1852 /* Each bit in the LSB nibble indicates 1 AC.
1853 * Clearing the particular bit in LSB nibble to indicate
1854 * access required
1855 */
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001856 switch (ac_type) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001857 case SME_AC_BK:
1858 /* clear first bit */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001859 adapter->psb_changed &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001860 break;
1861 case SME_AC_BE:
1862 /* clear second bit */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001863 adapter->psb_changed &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001864 break;
1865 case SME_AC_VI:
1866 /* clear third bit */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001867 adapter->psb_changed &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001868 break;
1869 case SME_AC_VO:
1870 /* clear fourth bit */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001871 adapter->psb_changed &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001872 break;
1873 default:
Jeff Johnson5ae20e92016-08-19 13:51:48 -07001874 hdd_err("Invalid AC Type");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001875 break;
1876 }
1877}
1878
1879/**
1880 * hdd_wmm_acquire_access() - Function which will attempt to acquire
1881 * admittance for a WMM AC
1882 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001883 * @adapter: [in] pointer to adapter context
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001884 * @ac_type: [in] WMM AC type of OS packet
Jeff Johnsona9f092a2019-03-08 19:17:23 -08001885 * @granted: [out] pointer to bool flag when indicates if access
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001886 * has been granted or not
1887 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301888 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001889 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001890QDF_STATUS hdd_wmm_acquire_access(struct hdd_adapter *adapter,
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001891 sme_ac_enum_type ac_type, bool *granted)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001892{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001893 struct hdd_wmm_qos_context *qos_context;
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05301894 struct hdd_context *hdd_ctx;
1895 bool enable;
1896 QDF_STATUS status = QDF_STATUS_SUCCESS;
1897
1898 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001899
Rajeev Kumar3d4b1ef2016-01-29 15:57:26 -08001900 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001901 "%s: Entered for AC %d", __func__, ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001902
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05301903 status = ucfg_mlme_get_implicit_qos_is_enabled(hdd_ctx->psoc, &enable);
1904 if (!QDF_IS_STATUS_SUCCESS(status)) {
1905 hdd_err("Get implicit_qos_is_enabled failed");
1906 }
1907 if (!hdd_wmm_is_active(adapter) || !(enable) ||
Jeff Johnson30ac84f2019-03-09 13:57:57 -08001908 !adapter->hdd_wmm_status.ac_status[ac_type].is_access_required) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001909 /* either we don't want QoS or the AP doesn't support
1910 * QoS or we don't want to do implicit QoS
1911 */
Rajeev Kumar3d4b1ef2016-01-29 15:57:26 -08001912 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001913 "%s: QoS not configured on both ends ", __func__);
1914
Jeff Johnsona9f092a2019-03-08 19:17:23 -08001915 *granted =
Jeff Johnson12e12332019-03-08 23:29:23 -08001916 adapter->hdd_wmm_status.ac_status[ac_type].
Jeff Johnsona5548972019-03-09 14:22:18 -08001917 is_access_allowed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001918
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301919 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001920 }
1921 /* do we already have an implicit QoS request pending for this AC? */
Jeff Johnson12ccaf62019-03-09 13:59:53 -08001922 if ((adapter->hdd_wmm_status.ac_status[ac_type].is_access_needed) ||
Jeff Johnsone5b75be2019-03-09 14:07:35 -08001923 (adapter->hdd_wmm_status.ac_status[ac_type].is_access_pending)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001924 /* request already pending so we need to wait for that
1925 * response
1926 */
Rajeev Kumar3d4b1ef2016-01-29 15:57:26 -08001927 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001928 "%s: Implicit QoS for TL AC %d already scheduled",
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001929 __func__, ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001930
Jeff Johnsona9f092a2019-03-08 19:17:23 -08001931 *granted = false;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301932 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001933 }
1934 /* did we already fail to establish implicit QoS for this AC?
1935 * (if so, access should have been granted when the failure
1936 * was handled)
1937 */
Jeff Johnson1b48ccb2019-03-09 14:15:57 -08001938 if (adapter->hdd_wmm_status.ac_status[ac_type].has_access_failed) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001939 /* request previously failed
1940 * allow access, but we'll be downgraded
1941 */
Rajeev Kumar3d4b1ef2016-01-29 15:57:26 -08001942 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001943 "%s: Implicit QoS for TL AC %d previously failed",
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001944 __func__, ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001945
Jeff Johnson12e12332019-03-08 23:29:23 -08001946 if (!adapter->hdd_wmm_status.ac_status[ac_type].
Jeff Johnson30ac84f2019-03-09 13:57:57 -08001947 is_access_required) {
Jeff Johnson12e12332019-03-08 23:29:23 -08001948 adapter->hdd_wmm_status.ac_status[ac_type].
Jeff Johnsona5548972019-03-09 14:22:18 -08001949 is_access_allowed = true;
Jeff Johnsona9f092a2019-03-08 19:17:23 -08001950 *granted = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001951 } else {
Jeff Johnson12e12332019-03-08 23:29:23 -08001952 adapter->hdd_wmm_status.ac_status[ac_type].
Jeff Johnsona5548972019-03-09 14:22:18 -08001953 is_access_allowed = false;
Jeff Johnsona9f092a2019-03-08 19:17:23 -08001954 *granted = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001955 }
1956
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301957 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001958 }
1959 /* we need to establish implicit QoS */
Rajeev Kumar3d4b1ef2016-01-29 15:57:26 -08001960 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001961 "%s: Need to schedule implicit QoS for TL AC %d, adapter is %pK",
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001962 __func__, ac_type, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001963
Jeff Johnson12ccaf62019-03-09 13:59:53 -08001964 adapter->hdd_wmm_status.ac_status[ac_type].is_access_needed = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001965
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001966 qos_context = qdf_mem_malloc(sizeof(*qos_context));
Jeff Johnsond36fa332019-03-18 13:42:25 -07001967 if (!qos_context) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001968 /* no memory for QoS context. Nothing we can do but
1969 * let data flow
1970 */
Jeff Johnson5ae20e92016-08-19 13:51:48 -07001971 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001972 "%s: Unable to allocate context", __func__);
Jeff Johnsona5548972019-03-09 14:22:18 -08001973 adapter->hdd_wmm_status.ac_status[ac_type].is_access_allowed =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001974 true;
Jeff Johnsona9f092a2019-03-08 19:17:23 -08001975 *granted = true;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301976 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001977 }
1978
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001979 qos_context->ac_type = ac_type;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001980 qos_context->adapter = adapter;
Jeff Johnson104f70e2019-03-08 19:29:33 -08001981 qos_context->flow_id = 0;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001982 qos_context->handle = HDD_WMM_HANDLE_IMPLICIT;
1983 qos_context->magic = HDD_WMM_CTX_MAGIC;
1984 qos_context->is_inactivity_timer_running = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001985
Jeff Johnson7d4a0b52019-03-08 22:06:32 -08001986 INIT_WORK(&qos_context->implicit_qos_work, hdd_wmm_do_implicit_qos);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001987
Rajeev Kumar3d4b1ef2016-01-29 15:57:26 -08001988 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson36e74c42017-09-18 08:15:42 -07001989 "%s: Scheduling work for AC %d, context %pK",
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001990 __func__, ac_type, qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001991
Jeff Johnson7d4a0b52019-03-08 22:06:32 -08001992 schedule_work(&qos_context->implicit_qos_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001993
1994 /* caller will need to wait until the work takes place and
1995 * TSPEC negotiation completes
1996 */
Jeff Johnsona9f092a2019-03-08 19:17:23 -08001997 *granted = false;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301998 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001999}
2000
2001/**
2002 * hdd_wmm_assoc() - Function which will handle the housekeeping
2003 * required by WMM when association takes place
2004 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002005 * @adapter: [in] pointer to adapter context
Jeff Johnsonfd060852017-10-04 10:50:51 -07002006 * @roam_info: [in] pointer to roam information
Jeff Johnsonfdb993c2019-02-27 09:38:08 -08002007 * @bss_type: [in] type of BSS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002008 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302009 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002010 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002011QDF_STATUS hdd_wmm_assoc(struct hdd_adapter *adapter,
Jeff Johnson172237b2017-11-07 15:32:59 -08002012 struct csr_roam_info *roam_info,
Jeff Johnsonfdb993c2019-02-27 09:38:08 -08002013 eCsrRoamBssType bss_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002014{
Jeff Johnsonc7776f22019-03-09 16:09:31 -08002015 uint8_t uapsd_mask;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302016 QDF_STATUS status;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05302017 uint32_t srv_value = 0;
2018 uint32_t sus_value = 0;
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002019 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Abhinav Kumarc8c21502018-12-05 15:17:39 +05302020 uint32_t delayed_trgr_frm_int;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002021
2022 /* when we associate we need to notify TL if it needs to
2023 * enable UAPSD for any access categories
2024 */
2025
Dustin Brown491d54b2018-03-14 12:39:11 -07002026 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002027
Jeff Johnsonfd060852017-10-04 10:50:51 -07002028 if (roam_info->fReassocReq) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002029 /* when we reassociate we should continue to use
2030 * whatever parameters were previously established.
2031 * if we are reassociating due to a U-APSD change for
2032 * a particular Access Category, then the change will
2033 * be communicated to HDD via the QoS callback
2034 * associated with the given flow, and U-APSD
2035 * parameters will be updated there
2036 */
2037
Varun Reddy Yeturudd51e8d2017-05-14 14:51:13 -07002038 hdd_debug("Reassoc so no work, Exiting");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002039
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302040 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002041 }
2042 /* get the negotiated UAPSD Mask */
Jeff Johnsonc7776f22019-03-09 16:09:31 -08002043 uapsd_mask =
Jeff Johnsonfd060852017-10-04 10:50:51 -07002044 roam_info->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002045
Jeff Johnsonc7776f22019-03-09 16:09:31 -08002046 hdd_debug("U-APSD mask is 0x%02x", (int)uapsd_mask);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002047
Abhinav Kumarc8c21502018-12-05 15:17:39 +05302048 ucfg_mlme_get_tl_delayed_trgr_frm_int(hdd_ctx->psoc,
2049 &delayed_trgr_frm_int);
2050
Jeff Johnsonc7776f22019-03-09 16:09:31 -08002051 if (uapsd_mask & HDD_AC_VO) {
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05302052 status = ucfg_mlme_get_wmm_uapsd_vo_srv_intv(hdd_ctx->psoc,
2053 &srv_value);
2054 if (QDF_IS_STATUS_ERROR(status)) {
2055 hdd_err("Get uapsd_srv_intv failed");
2056 return QDF_STATUS_SUCCESS;
2057 }
2058 status = ucfg_mlme_get_wmm_uapsd_vo_sus_intv(hdd_ctx->psoc,
2059 &sus_value);
2060 if (QDF_IS_STATUS_ERROR(status)) {
2061 hdd_err("Get uapsd_vo_sus_intv failed");
2062 return QDF_STATUS_SUCCESS;
2063 }
2064
2065 status = sme_enable_uapsd_for_ac(
2066 (WLAN_HDD_GET_STATION_CTX_PTR(
Jeff Johnson0a082d92019-03-04 12:25:49 -08002067 adapter))->conn_info.sta_id[0],
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05302068 SME_AC_VO, 7, 7, srv_value, sus_value,
2069 SME_QOS_WMM_TS_DIR_BOTH, 1,
Jeff Johnson9597f3b2019-02-04 14:27:56 -08002070 adapter->vdev_id,
Abhinav Kumarc8c21502018-12-05 15:17:39 +05302071 delayed_trgr_frm_int);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002072
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302073 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002074 }
2075
Jeff Johnsonc7776f22019-03-09 16:09:31 -08002076 if (uapsd_mask & HDD_AC_VI) {
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05302077 status = ucfg_mlme_get_wmm_uapsd_vi_srv_intv(
2078 hdd_ctx->psoc, &srv_value);
2079 if (!QDF_IS_STATUS_SUCCESS(status)) {
2080 hdd_err("Get uapsd_vi_srv_intv failed");
2081 return QDF_STATUS_SUCCESS;
2082 }
2083 status = ucfg_mlme_get_wmm_uapsd_vi_sus_intv(
2084 hdd_ctx->psoc, &sus_value);
2085 if (!QDF_IS_STATUS_SUCCESS(status)) {
2086 hdd_err("Get uapsd_vi_sus_intv failed");
2087 return QDF_STATUS_SUCCESS;
2088 }
2089
2090 status = sme_enable_uapsd_for_ac(
2091 (WLAN_HDD_GET_STATION_CTX_PTR(
Jeff Johnson0a082d92019-03-04 12:25:49 -08002092 adapter))->conn_info.sta_id[0],
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05302093 SME_AC_VI, 5, 5, srv_value, sus_value,
2094 SME_QOS_WMM_TS_DIR_BOTH, 1,
Jeff Johnson9597f3b2019-02-04 14:27:56 -08002095 adapter->vdev_id,
Abhinav Kumarc8c21502018-12-05 15:17:39 +05302096 delayed_trgr_frm_int);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002097
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302098 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002099 }
2100
Jeff Johnsonc7776f22019-03-09 16:09:31 -08002101 if (uapsd_mask & HDD_AC_BK) {
Abhinav Kumar2af8c122018-08-19 13:49:52 +05302102 status = ucfg_mlme_get_wmm_uapsd_bk_srv_intv(hdd_ctx->psoc,
2103 &srv_value);
2104 if (!QDF_IS_STATUS_SUCCESS(status)) {
2105 hdd_err("Get uapsd_bk_srv_intv failed");
2106 return QDF_STATUS_SUCCESS;
2107 }
2108 status = ucfg_mlme_get_wmm_uapsd_bk_sus_intv(hdd_ctx->psoc,
2109 &sus_value);
2110 if (!QDF_IS_STATUS_SUCCESS(status)) {
2111 hdd_err("Get uapsd_bk_sus_intv failed");
2112 return QDF_STATUS_SUCCESS;
2113 }
2114
2115 status = sme_enable_uapsd_for_ac(
2116 (WLAN_HDD_GET_STATION_CTX_PTR(
Jeff Johnson0a082d92019-03-04 12:25:49 -08002117 adapter))->conn_info.sta_id[0],
Abhinav Kumar2af8c122018-08-19 13:49:52 +05302118 SME_AC_BK, 2, 2, srv_value, sus_value,
2119 SME_QOS_WMM_TS_DIR_BOTH, 1,
Jeff Johnson9597f3b2019-02-04 14:27:56 -08002120 adapter->vdev_id,
Abhinav Kumarc8c21502018-12-05 15:17:39 +05302121 delayed_trgr_frm_int);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002122
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302123 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002124 }
2125
Jeff Johnsonc7776f22019-03-09 16:09:31 -08002126 if (uapsd_mask & HDD_AC_BE) {
Abhinav Kumare94f2482018-08-19 12:37:36 +05302127 status = ucfg_mlme_get_wmm_uapsd_be_srv_intv(hdd_ctx->psoc,
2128 &srv_value);
2129 if (!QDF_IS_STATUS_SUCCESS(status)) {
2130 hdd_err("Get uapsd_be_srv_intv failed");
2131 return QDF_STATUS_SUCCESS;
2132 }
2133 status = ucfg_mlme_get_wmm_uapsd_be_sus_intv(hdd_ctx->psoc,
2134 &sus_value);
2135 if (!QDF_IS_STATUS_SUCCESS(status)) {
2136 hdd_err("Get uapsd_be_sus_intv failed");
2137 return QDF_STATUS_SUCCESS;
2138 }
2139
2140 status = sme_enable_uapsd_for_ac(
2141 (WLAN_HDD_GET_STATION_CTX_PTR(
Jeff Johnson0a082d92019-03-04 12:25:49 -08002142 adapter))->conn_info.sta_id[0],
Abhinav Kumare94f2482018-08-19 12:37:36 +05302143 SME_AC_BE, 3, 3, srv_value, sus_value,
2144 SME_QOS_WMM_TS_DIR_BOTH, 1,
Jeff Johnson9597f3b2019-02-04 14:27:56 -08002145 adapter->vdev_id,
Abhinav Kumarc8c21502018-12-05 15:17:39 +05302146 delayed_trgr_frm_int);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002147
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302148 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002149 }
2150
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07002151 status = sme_update_dsc_pto_up_mapping(hdd_ctx->mac_handle,
Jeff Johnson6b51b6a2017-11-02 20:31:25 -07002152 adapter->dscp_to_up_map,
Jeff Johnson9597f3b2019-02-04 14:27:56 -08002153 adapter->vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002154
Srinivas Girigowda576b2352017-08-25 14:44:26 -07002155 if (!QDF_IS_STATUS_SUCCESS(status))
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002156 hdd_wmm_init(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002157
Dustin Browne74003f2018-03-14 12:51:58 -07002158 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002159
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302160 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002161}
2162
2163static const uint8_t acm_mask_bit[WLAN_MAX_AC] = {
2164 0x4, /* SME_AC_BK */
2165 0x8, /* SME_AC_BE */
2166 0x2, /* SME_AC_VI */
2167 0x1 /* SME_AC_VO */
2168};
2169
2170/**
2171 * hdd_wmm_connect() - Function which will handle the housekeeping
2172 * required by WMM when a connection is established
2173 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002174 * @adapter : [in] pointer to adapter context
Jeff Johnsonfd060852017-10-04 10:50:51 -07002175 * @roam_info: [in] pointer to roam information
Jeff Johnsonfdb993c2019-02-27 09:38:08 -08002176 * @bss_type : [in] type of BSS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002177 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302178 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002179 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002180QDF_STATUS hdd_wmm_connect(struct hdd_adapter *adapter,
Jeff Johnson172237b2017-11-07 15:32:59 -08002181 struct csr_roam_info *roam_info,
Jeff Johnsonfdb993c2019-02-27 09:38:08 -08002182 eCsrRoamBssType bss_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002183{
2184 int ac;
2185 bool qap;
Jeff Johnson5b980192019-03-08 23:01:20 -08002186 bool qos_connection;
Jeff Johnsonc5449d72019-03-08 22:56:08 -08002187 uint8_t acm_mask;
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07002188 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002189
Dustin Brown491d54b2018-03-14 12:39:11 -07002190 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002191
Jeff Johnsonfdb993c2019-02-27 09:38:08 -08002192 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == bss_type) &&
Jeff Johnsonfd060852017-10-04 10:50:51 -07002193 roam_info && roam_info->u.pConnectedProfile) {
2194 qap = roam_info->u.pConnectedProfile->qap;
Jeff Johnson5b980192019-03-08 23:01:20 -08002195 qos_connection = roam_info->u.pConnectedProfile->qosConnection;
Jeff Johnsonc5449d72019-03-08 22:56:08 -08002196 acm_mask = roam_info->u.pConnectedProfile->acm_mask;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002197 } else {
2198 qap = true;
Jeff Johnson5b980192019-03-08 23:01:20 -08002199 qos_connection = true;
Jeff Johnsonc5449d72019-03-08 22:56:08 -08002200 acm_mask = 0x0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002201 }
2202
Jeff Johnson5b980192019-03-08 23:01:20 -08002203 hdd_debug("qap is %d, qos_connection is %d, acm_mask is 0x%x",
2204 qap, qos_connection, acm_mask);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002205
Jeff Johnson26ef71e2019-03-08 23:24:29 -08002206 adapter->hdd_wmm_status.qap = qap;
Jeff Johnson7f63ac92019-03-08 23:26:37 -08002207 adapter->hdd_wmm_status.qos_connection = qos_connection;
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07002208 mac_handle = hdd_adapter_get_mac_handle(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002209
2210 for (ac = 0; ac < WLAN_MAX_AC; ac++) {
Jeff Johnson5b980192019-03-08 23:01:20 -08002211 if (qap && qos_connection && (acm_mask & acm_mask_bit[ac])) {
Varun Reddy Yeturudd51e8d2017-05-14 14:51:13 -07002212 hdd_debug("ac %d on", ac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002213
2214 /* admission is required */
Jeff Johnson12e12332019-03-08 23:29:23 -08002215 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnson30ac84f2019-03-09 13:57:57 -08002216 is_access_required = true;
Jeff Johnson12e12332019-03-08 23:29:23 -08002217 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnsona5548972019-03-09 14:22:18 -08002218 is_access_allowed = false;
Jeff Johnson12e12332019-03-08 23:29:23 -08002219 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnsonc77123d2019-03-09 14:18:34 -08002220 was_access_granted = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002221 /* after reassoc if we have valid tspec, allow access */
Jeff Johnson12e12332019-03-08 23:29:23 -08002222 if (adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnson0698e662019-03-09 14:24:32 -08002223 is_tspec_valid
Jeff Johnson12e12332019-03-08 23:29:23 -08002224 && (adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnson64d94dd2019-03-09 14:31:14 -08002225 tspec.ts_info.direction !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002226 SME_QOS_WMM_TS_DIR_DOWNLINK)) {
Jeff Johnson12e12332019-03-08 23:29:23 -08002227 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnsona5548972019-03-09 14:22:18 -08002228 is_access_allowed = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002229 }
Jeff Johnsonfd060852017-10-04 10:50:51 -07002230 if (!roam_info->fReassocReq &&
yeshwanth sriram guntukaa1ba9a22017-02-28 16:17:32 +05302231 !sme_neighbor_roam_is11r_assoc(
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07002232 mac_handle,
Jeff Johnson9597f3b2019-02-04 14:27:56 -08002233 adapter->vdev_id) &&
Jeff Johnsonfd060852017-10-04 10:50:51 -07002234 !sme_roam_is_ese_assoc(roam_info)) {
Jeff Johnson12e12332019-03-08 23:29:23 -08002235 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnson0698e662019-03-09 14:24:32 -08002236 is_tspec_valid = false;
Jeff Johnson12e12332019-03-08 23:29:23 -08002237 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnsona5548972019-03-09 14:22:18 -08002238 is_access_allowed = false;
yeshwanth sriram guntukaa1ba9a22017-02-28 16:17:32 +05302239 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002240 } else {
Varun Reddy Yeturudd51e8d2017-05-14 14:51:13 -07002241 hdd_debug("ac %d off", ac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002242 /* admission is not required so access is allowed */
Jeff Johnson12e12332019-03-08 23:29:23 -08002243 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnson30ac84f2019-03-09 13:57:57 -08002244 is_access_required = false;
Jeff Johnson12e12332019-03-08 23:29:23 -08002245 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnsona5548972019-03-09 14:22:18 -08002246 is_access_allowed = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002247 }
2248
2249 }
2250
Dustin Browne74003f2018-03-14 12:51:58 -07002251 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002252
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302253 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002254}
2255
2256/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002257 * hdd_wmm_is_active() - Function which will determine if WMM is
2258 * active on the current connection
2259 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002260 * @adapter: [in] pointer to adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002261 *
2262 * Return: true if WMM is enabled, false if WMM is not enabled
2263 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002264bool hdd_wmm_is_active(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002265{
Jeff Johnson7f63ac92019-03-08 23:26:37 -08002266 if ((!adapter->hdd_wmm_status.qos_connection) ||
Jeff Johnson26ef71e2019-03-08 23:24:29 -08002267 (!adapter->hdd_wmm_status.qap)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002268 return false;
2269 } else {
2270 return true;
2271 }
2272}
2273
Bala Venkateshc725a062018-10-30 15:29:35 +05302274bool hdd_wmm_is_acm_allowed(uint8_t vdev_id)
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002275{
Jeff Johnson5b8b67d2017-08-29 14:16:53 -07002276 struct hdd_adapter *adapter;
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002277 struct hdd_wmm_ac_status *wmm_ac_status;
Bala Venkateshc725a062018-10-30 15:29:35 +05302278 struct hdd_context *hdd_ctx;
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002279
Bala Venkateshc725a062018-10-30 15:29:35 +05302280 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2281 if (!hdd_ctx) {
2282 hdd_err("Unable to fetch the hdd context");
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002283 return false;
2284 }
Bala Venkateshc725a062018-10-30 15:29:35 +05302285
2286 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2287 if (hdd_validate_adapter(adapter)) {
2288 hdd_err("Invalid adapter");
2289 return false;
2290 }
2291
Jeff Johnson12e12332019-03-08 23:29:23 -08002292 wmm_ac_status = adapter->hdd_wmm_status.ac_status;
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002293
2294 if (hdd_wmm_is_active(adapter) &&
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002295 !(wmm_ac_status[QCA_WLAN_AC_VI].is_access_allowed))
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002296 return false;
2297 return true;
2298}
2299
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002300/**
2301 * hdd_wmm_addts() - Function which will add a traffic spec at the
2302 * request of an application
2303 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002304 * @adapter : [in] pointer to adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002305 * @handle : [in] handle to uniquely identify a TS
Jeff Johnson79d6e5e2019-03-07 22:26:19 -08002306 * @tspec : [in] pointer to the traffic spec
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002307 *
2308 * Return: HDD_WLAN_WMM_STATUS_*
2309 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002310hdd_wlan_wmm_status_e hdd_wmm_addts(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002311 uint32_t handle,
Jeff Johnson79d6e5e2019-03-07 22:26:19 -08002312 struct sme_qos_wmmtspecinfo *tspec)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002313{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002314 struct hdd_wmm_qos_context *qos_context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002315 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
2316#ifndef WLAN_MDM_CODE_REDUCTION_OPT
Jeff Johnson2059fd72019-03-08 20:06:59 -08002317 enum sme_qos_statustype sme_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002318#endif
2319 bool found = false;
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07002320 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002321
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002322 hdd_debug("Entered with handle 0x%x", handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002323
2324 /* see if a context already exists with the given handle */
Jeff Johnson12e12332019-03-08 23:29:23 -08002325 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002326 list_for_each_entry(qos_context,
Jeff Johnson8f656c62019-03-09 08:48:27 -08002327 &adapter->hdd_wmm_status.context_list, node) {
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002328 if (qos_context->handle == handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002329 found = true;
2330 break;
2331 }
2332 }
Jeff Johnson12e12332019-03-08 23:29:23 -08002333 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002334 if (found) {
2335 /* record with that handle already exists */
Jeff Johnson5ae20e92016-08-19 13:51:48 -07002336 hdd_err("Record already exists with handle 0x%x", handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002337
2338 /* Application is trying to modify some of the Tspec
2339 * params. Allow it
2340 */
Jeff Johnson2059fd72019-03-08 20:06:59 -08002341 sme_status = sme_qos_modify_req(mac_handle,
2342 tspec, qos_context->flow_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002343
2344 /* need to check the return value and act appropriately */
Jeff Johnson2059fd72019-03-08 20:06:59 -08002345 switch (sme_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002346 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2347 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2348 break;
2349 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2350 status =
2351 HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2352 break;
2353 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2354 status =
2355 HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2356 break;
2357 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2358 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2359 break;
2360 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2361 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2362 break;
2363 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2364 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2365 break;
2366 default:
2367 /* we didn't get back one of the
2368 * SME_QOS_STATUS_MODIFY_* status codes
2369 */
Jeff Johnson5ae20e92016-08-19 13:51:48 -07002370 hdd_err("unexpected SME Status=%d",
Jeff Johnson2059fd72019-03-08 20:06:59 -08002371 sme_status);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302372 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002373 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2374 }
2375
2376 /* we were successful, save the status */
Jeff Johnson12e12332019-03-08 23:29:23 -08002377 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002378 if (qos_context->magic == HDD_WMM_CTX_MAGIC)
Jeff Johnson5b052512019-03-08 19:32:14 -08002379 qos_context->status = status;
Jeff Johnson12e12332019-03-08 23:29:23 -08002380 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002381
2382 return status;
2383 }
2384
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002385 qos_context = qdf_mem_malloc(sizeof(*qos_context));
Jeff Johnsond36fa332019-03-18 13:42:25 -07002386 if (!qos_context) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002387 /* no memory for QoS context. Nothing we can do */
Jeff Johnson5ae20e92016-08-19 13:51:48 -07002388 hdd_err("Unable to allocate QoS context");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002389 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2390 }
2391 /* we assume the tspec has already been validated by the caller */
2392
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002393 qos_context->handle = handle;
Jeff Johnson79d6e5e2019-03-07 22:26:19 -08002394 if (tspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE)
Jeff Johnson239ff2e2019-03-08 19:26:11 -08002395 qos_context->ac_type = hdd_wmm_up_to_ac_map[tspec->ts_info.up];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002396 else {
Jeff Johnson239ff2e2019-03-08 19:26:11 -08002397 hdd_err("ts_info.up (%d) larger than max value (%d), use default ac_type (%d)",
Jeff Johnson79d6e5e2019-03-07 22:26:19 -08002398 tspec->ts_info.up,
Jeff Johnson5ae20e92016-08-19 13:51:48 -07002399 HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hdd_wmm_up_to_ac_map[0]);
Jeff Johnson239ff2e2019-03-08 19:26:11 -08002400 qos_context->ac_type = hdd_wmm_up_to_ac_map[0];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002401 }
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002402 qos_context->adapter = adapter;
Jeff Johnson104f70e2019-03-08 19:29:33 -08002403 qos_context->flow_id = 0;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002404 qos_context->magic = HDD_WMM_CTX_MAGIC;
2405 qos_context->is_inactivity_timer_running = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002406
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002407 hdd_debug("Setting up QoS, context %pK", qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002408
Jeff Johnson12e12332019-03-08 23:29:23 -08002409 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnson8f656c62019-03-09 08:48:27 -08002410 list_add(&qos_context->node, &adapter->hdd_wmm_status.context_list);
Jeff Johnson12e12332019-03-08 23:29:23 -08002411 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002412
2413#ifndef WLAN_MDM_CODE_REDUCTION_OPT
Jeff Johnson2059fd72019-03-08 20:06:59 -08002414 sme_status = sme_qos_setup_req(mac_handle,
2415 adapter->vdev_id,
2416 tspec,
2417 hdd_wmm_sme_callback,
2418 qos_context,
2419 tspec->ts_info.up,
2420 &qos_context->flow_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002421
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002422 hdd_debug("sme_qos_setup_req returned %d flowid %d",
Jeff Johnson2059fd72019-03-08 20:06:59 -08002423 sme_status, qos_context->flow_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002424
2425 /* need to check the return value and act appropriately */
Jeff Johnson2059fd72019-03-08 20:06:59 -08002426 switch (sme_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002427 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2428 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2429 break;
2430 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2431 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2432 break;
2433 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
2434 status =
2435 HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
2436 break;
2437 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
2438 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2439 break;
2440 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05302441 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002442 hdd_wmm_disable_inactivity_timer(qos_context);
2443 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002444 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
2445 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05302446 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002447 hdd_wmm_disable_inactivity_timer(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002448 /* we can't tell the difference between when a request
2449 * fails because AP rejected it versus when SME
2450 * encounterd an internal error
2451 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002452 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002453 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2454 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05302455 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002456 hdd_wmm_disable_inactivity_timer(qos_context);
2457 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002458 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2459 default:
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05302460 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002461 hdd_wmm_disable_inactivity_timer(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002462 /* we didn't get back one of the
2463 * SME_QOS_STATUS_SETUP_* status codes
2464 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002465 hdd_wmm_free_context(qos_context);
Jeff Johnson2059fd72019-03-08 20:06:59 -08002466 hdd_err("unexpected SME Status=%d", sme_status);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302467 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002468 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2469 }
2470#endif
2471
2472 /* we were successful, save the status */
Jeff Johnson12e12332019-03-08 23:29:23 -08002473 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002474 if (qos_context->magic == HDD_WMM_CTX_MAGIC)
Jeff Johnson5b052512019-03-08 19:32:14 -08002475 qos_context->status = status;
Jeff Johnson12e12332019-03-08 23:29:23 -08002476 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002477
2478 return status;
2479}
2480
2481/**
2482 * hdd_wmm_delts() - Function which will delete a traffic spec at the
2483 * request of an application
2484 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002485 * @adapter: [in] pointer to adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002486 * @handle: [in] handle to uniquely identify a TS
2487 *
2488 * Return: HDD_WLAN_WMM_STATUS_*
2489 */
Jeff Johnsonde353b82017-10-03 11:44:52 -07002490hdd_wlan_wmm_status_e hdd_wmm_delts(struct hdd_adapter *adapter,
2491 uint32_t handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002492{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002493 struct hdd_wmm_qos_context *qos_context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002494 bool found = false;
Jeff Johnson239ff2e2019-03-08 19:26:11 -08002495 sme_ac_enum_type ac_type = 0;
Jeff Johnson104f70e2019-03-08 19:29:33 -08002496 uint32_t flow_id = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002497 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
2498#ifndef WLAN_MDM_CODE_REDUCTION_OPT
Jeff Johnson2059fd72019-03-08 20:06:59 -08002499 enum sme_qos_statustype sme_status;
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07002500 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002501#endif
2502
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002503 hdd_debug("Entered with handle 0x%x", handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002504
2505 /* locate the context with the given handle */
Jeff Johnson12e12332019-03-08 23:29:23 -08002506 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002507 list_for_each_entry(qos_context,
Jeff Johnson8f656c62019-03-09 08:48:27 -08002508 &adapter->hdd_wmm_status.context_list, node) {
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002509 if (qos_context->handle == handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002510 found = true;
Jeff Johnson239ff2e2019-03-08 19:26:11 -08002511 ac_type = qos_context->ac_type;
Jeff Johnson104f70e2019-03-08 19:29:33 -08002512 flow_id = qos_context->flow_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002513 break;
2514 }
2515 }
Jeff Johnson12e12332019-03-08 23:29:23 -08002516 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002517
2518 if (false == found) {
2519 /* we didn't find the handle */
Jeff Johnson5ae20e92016-08-19 13:51:48 -07002520 hdd_info("handle 0x%x not found", handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002521 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2522 }
2523
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +05302524 hdd_debug("found handle 0x%x, flow %d, AC %d, context %pK",
Jeff Johnson104f70e2019-03-08 19:29:33 -08002525 handle, flow_id, ac_type, qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002526
2527#ifndef WLAN_MDM_CODE_REDUCTION_OPT
Jeff Johnson2059fd72019-03-08 20:06:59 -08002528 sme_status = sme_qos_release_req(mac_handle, adapter->vdev_id,
2529 flow_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002530
Jeff Johnson2059fd72019-03-08 20:06:59 -08002531 hdd_debug("SME flow %d released, SME status %d", flow_id, sme_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002532
Jeff Johnson2059fd72019-03-08 20:06:59 -08002533 switch (sme_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002534 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
2535 /* this flow is the only one on that AC, so go ahead
2536 * and update our TSPEC state for the AC
2537 */
Jeff Johnson0698e662019-03-09 14:24:32 -08002538 adapter->hdd_wmm_status.ac_status[ac_type].is_tspec_valid =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002539 false;
Jeff Johnsona5548972019-03-09 14:22:18 -08002540 adapter->hdd_wmm_status.ac_status[ac_type].is_access_allowed =
Sreelakshmi Konamki9d6b75d2016-02-10 12:17:23 +05302541 false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002542
2543 /* need to tell TL to stop trigger timer, etc */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002544 hdd_wmm_disable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002545
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002546 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002547 hdd_wmm_disable_inactivity_timer(qos_context);
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05302548
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002549 /* we are done with this context */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002550 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002551
2552 /* SME must not fire any more callbacks for this flow
2553 * since the context is no longer valid
2554 */
2555
2556 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
2557
2558 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
2559 /* do nothing as we will get a response from SME */
2560 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
2561 break;
2562
2563 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
2564 /* nothing we can do with the existing flow except leave it */
2565 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2566 break;
2567
2568 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
2569 /* nothing we can do with the existing flow except leave it */
2570 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
Yingying Tang9fad0ca2016-10-20 23:12:36 +08002571 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002572
2573 default:
2574 /* we didn't get back one of the
2575 * SME_QOS_STATUS_RELEASE_* status codes
2576 */
Jeff Johnson2059fd72019-03-08 20:06:59 -08002577 hdd_err("unexpected SME Status=%d", sme_status);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302578 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002579 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2580 }
2581
2582#endif
Jeff Johnson12e12332019-03-08 23:29:23 -08002583 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002584 if (qos_context->magic == HDD_WMM_CTX_MAGIC)
Jeff Johnson5b052512019-03-08 19:32:14 -08002585 qos_context->status = status;
Jeff Johnson12e12332019-03-08 23:29:23 -08002586 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002587
2588 return status;
2589}
2590
2591/**
2592 * hdd_wmm_checkts() - Function which will return the status of a traffic
2593 * spec at the request of an application
2594 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002595 * @adapter: [in] pointer to adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002596 * @handle: [in] handle to uniquely identify a TS
2597 *
2598 * Return: HDD_WLAN_WMM_STATUS_*
2599 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002600hdd_wlan_wmm_status_e hdd_wmm_checkts(struct hdd_adapter *adapter, uint32_t handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002601{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002602 struct hdd_wmm_qos_context *qos_context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002603 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
2604
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002605 hdd_debug("Entered with handle 0x%x", handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002606
2607 /* locate the context with the given handle */
Jeff Johnson12e12332019-03-08 23:29:23 -08002608 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002609 list_for_each_entry(qos_context,
Jeff Johnson8f656c62019-03-09 08:48:27 -08002610 &adapter->hdd_wmm_status.context_list, node) {
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002611 if (qos_context->handle == handle) {
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +05302612 hdd_debug("found handle 0x%x, context %pK",
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002613 handle, qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002614
Jeff Johnson5b052512019-03-08 19:32:14 -08002615 status = qos_context->status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002616 break;
2617 }
2618 }
Jeff Johnson12e12332019-03-08 23:29:23 -08002619 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002620 return status;
2621}