blob: 759fdbd67f083c04fc5ab38a7007186f534d41d4 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Vevek Venkatesan656edfa2020-01-28 13:08:51 +05302 * Copyright (c) 2013-2020 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"
Vevek Venkatesan656edfa2020-01-28 13:08:51 +053050#include "os_if_fwol.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080051#include <wlan_hdd_tx_rx.h>
52#include <wlan_hdd_wmm.h>
53#include <wlan_hdd_ether.h>
54#include <wlan_hdd_hostapd.h>
55#include <wlan_hdd_softap_tx_rx.h>
56#include <cds_sched.h>
yeshwanth sriram guntukaa1ba9a22017-02-28 16:17:32 +053057#include "sme_api.h"
Abhinav Kumar18b45cd2018-09-21 12:35:22 +053058#include "wlan_mlme_ucfg_api.h"
Vevek Venkatesan656edfa2020-01-28 13:08:51 +053059#include "cfg_ucfg_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080060
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080061#define HDD_WMM_UP_TO_AC_MAP_SIZE 8
Vevek Venkatesan656edfa2020-01-28 13:08:51 +053062#define DSCP(x) x
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080063
64const uint8_t hdd_wmm_up_to_ac_map[] = {
65 SME_AC_BE,
66 SME_AC_BK,
67 SME_AC_BK,
68 SME_AC_BE,
69 SME_AC_VI,
70 SME_AC_VI,
71 SME_AC_VO,
72 SME_AC_VO
73};
74
75/**
76 * enum hdd_wmm_linuxac: AC/Queue Index values for Linux Qdisc to
77 * operate on different traffic.
78 */
79#ifdef QCA_LL_TX_FLOW_CONTROL_V2
Jeff Johnson5b8b67d2017-08-29 14:16:53 -070080void wlan_hdd_process_peer_unauthorised_pause(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080081{
82 /* Enable HI_PRIO queue */
83 netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VO);
84 netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VI);
85 netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BE);
86 netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BK);
87 netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_HI_PRIO);
88
89}
90#else
Jeff Johnson5b8b67d2017-08-29 14:16:53 -070091void wlan_hdd_process_peer_unauthorised_pause(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080092{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080093}
94#endif
95
96/* Linux based UP -> AC Mapping */
97const uint8_t hdd_linux_up_to_ac_map[HDD_WMM_UP_TO_AC_MAP_SIZE] = {
98 HDD_LINUX_AC_BE,
99 HDD_LINUX_AC_BK,
100 HDD_LINUX_AC_BK,
101 HDD_LINUX_AC_BE,
102 HDD_LINUX_AC_VI,
103 HDD_LINUX_AC_VI,
104 HDD_LINUX_AC_VO,
105 HDD_LINUX_AC_VO
106};
107
108#ifndef WLAN_MDM_CODE_REDUCTION_OPT
109/**
110 * hdd_wmm_enable_tl_uapsd() - function which decides whether and
111 * how to update UAPSD parameters in TL
112 *
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800113 * @qos_context: [in] the pointer the QoS instance control block
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800114 *
115 * Return: None
116 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800117static void hdd_wmm_enable_tl_uapsd(struct hdd_wmm_qos_context *qos_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800118{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800119 struct hdd_adapter *adapter = qos_context->adapter;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800120 sme_ac_enum_type ac_type = qos_context->ac_type;
Jeff Johnson12e12332019-03-08 23:29:23 -0800121 struct hdd_wmm_ac_status *ac = &adapter->hdd_wmm_status.ac_status[ac_type];
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700122 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530123 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800124 uint32_t service_interval;
125 uint32_t suspension_interval;
Abhishek Singh12be60f2017-08-11 13:52:42 +0530126 enum sme_qos_wmm_dir_type direction;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800127 bool psb;
Abhinav Kumarc8c21502018-12-05 15:17:39 +0530128 uint32_t delayed_trgr_frm_int;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800129
130 /* The TSPEC must be valid */
Jeff Johnson0698e662019-03-09 14:24:32 -0800131 if (ac->is_tspec_valid == false) {
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700132 hdd_err("Invoked with invalid TSPEC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800133 return;
134 }
135 /* determine the service interval */
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800136 if (ac->tspec.min_service_interval) {
137 service_interval = ac->tspec.min_service_interval;
138 } else if (ac->tspec.max_service_interval) {
139 service_interval = ac->tspec.max_service_interval;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800140 } else {
141 /* no service interval is present in the TSPEC */
142 /* this is OK, there just won't be U-APSD */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700143 hdd_debug("No service interval supplied");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800144 service_interval = 0;
145 }
146
147 /* determine the suspension interval & direction */
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800148 suspension_interval = ac->tspec.suspension_interval;
149 direction = ac->tspec.ts_info.direction;
150 psb = ac->tspec.ts_info.psb;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800151
152 /* if we have previously enabled U-APSD, have any params changed? */
Jeff Johnsonfd297092019-03-09 14:29:20 -0800153 if ((ac->is_uapsd_info_valid) &&
Jeff Johnsone8f3a772019-03-09 14:36:12 -0800154 (ac->uapsd_service_interval == service_interval) &&
Jeff Johnson48fffec2019-03-09 14:37:27 -0800155 (ac->uapsd_suspension_interval == suspension_interval) &&
Jeff Johnson68a8a9a2019-03-09 14:39:51 -0800156 (ac->uapsd_direction == direction) &&
Jeff Johnsona86be852019-03-09 14:34:25 -0800157 (ac->is_uapsd_enabled == psb)) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700158 hdd_debug("No change in U-APSD parameters");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800159 return;
160 }
Abhinav Kumarc8c21502018-12-05 15:17:39 +0530161
162 ucfg_mlme_get_tl_delayed_trgr_frm_int(hdd_ctx->psoc,
163 &delayed_trgr_frm_int);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800164 /* everything is in place to notify TL */
165 status =
Sourav Mohapatraa3cf12a2019-08-19 15:40:49 +0530166 sme_enable_uapsd_for_ac(ac_type, ac->tspec.ts_info.tid,
167 ac->tspec.ts_info.up,
168 service_interval, suspension_interval,
169 direction, psb, adapter->vdev_id,
170 delayed_trgr_frm_int);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800171
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530172 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800173 hdd_err("Failed to enable U-APSD for AC=%d", ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800174 return;
175 }
176 /* stash away the parameters that were used */
Jeff Johnsonfd297092019-03-09 14:29:20 -0800177 ac->is_uapsd_info_valid = true;
Jeff Johnsone8f3a772019-03-09 14:36:12 -0800178 ac->uapsd_service_interval = service_interval;
Jeff Johnson48fffec2019-03-09 14:37:27 -0800179 ac->uapsd_suspension_interval = suspension_interval;
Jeff Johnson68a8a9a2019-03-09 14:39:51 -0800180 ac->uapsd_direction = direction;
Jeff Johnsona86be852019-03-09 14:34:25 -0800181 ac->is_uapsd_enabled = psb;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800182
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700183 hdd_debug("Enabled UAPSD in TL srv_int=%d susp_int=%d dir=%d AC=%d",
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800184 service_interval, suspension_interval, direction, ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800185
186}
187
188/**
189 * hdd_wmm_disable_tl_uapsd() - function which decides whether
190 * to disable UAPSD parameters in TL
191 *
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800192 * @qos_context: [in] the pointer the QoS instance control block
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800193 *
194 * Return: None
195 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800196static void hdd_wmm_disable_tl_uapsd(struct hdd_wmm_qos_context *qos_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800197{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800198 struct hdd_adapter *adapter = qos_context->adapter;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800199 sme_ac_enum_type ac_type = qos_context->ac_type;
Jeff Johnson12e12332019-03-08 23:29:23 -0800200 struct hdd_wmm_ac_status *ac = &adapter->hdd_wmm_status.ac_status[ac_type];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530201 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800202
203 /* have we previously enabled UAPSD? */
Jeff Johnsonfd297092019-03-09 14:29:20 -0800204 if (ac->is_uapsd_info_valid == true) {
Sourav Mohapatraa3cf12a2019-08-19 15:40:49 +0530205 status = sme_disable_uapsd_for_ac(ac_type, adapter->vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800206
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530207 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800208 hdd_err("Failed to disable U-APSD for AC=%d", ac_type);
Sreelakshmi Konamkie1ce5622015-11-23 15:04:05 +0530209 } else {
210 /* TL no longer has valid UAPSD info */
Jeff Johnsonfd297092019-03-09 14:29:20 -0800211 ac->is_uapsd_info_valid = false;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800212 hdd_debug("Disabled UAPSD in TL for AC=%d", ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800213 }
214 }
215}
216
217#endif
218
219/**
220 * hdd_wmm_free_context() - function which frees a QoS context
221 *
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800222 * @qos_context: [in] the pointer the QoS instance control block
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800223 *
224 * Return: None
225 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800226static void hdd_wmm_free_context(struct hdd_wmm_qos_context *qos_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800227{
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700228 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800229
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800230 hdd_debug("Entered, context %pK", qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800231
Jeff Johnsond36fa332019-03-18 13:42:25 -0700232 if (unlikely((!qos_context) ||
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800233 (HDD_WMM_CTX_MAGIC != qos_context->magic))) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800234 /* must have been freed in another thread */
235 return;
236 }
237 /* get pointer to the adapter context */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800238 adapter = qos_context->adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800239
Jeff Johnson12e12332019-03-08 23:29:23 -0800240 /* take the mutex since we're manipulating the context list */
241 mutex_lock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800242
243 /* make sure nobody thinks this is a valid context */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800244 qos_context->magic = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800245
246 /* unlink the context */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800247 list_del(&qos_context->node);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800248
249 /* done manipulating the list */
Jeff Johnson12e12332019-03-08 23:29:23 -0800250 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800251
252 /* reclaim memory */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800253 qdf_mem_free(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800254
255}
256
257#ifndef WLAN_MDM_CODE_REDUCTION_OPT
258/**
259 * hdd_wmm_notify_app() - function which notifies an application
260 * of changes in state of it flow
261 *
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800262 * @qos_context: [in] the pointer the QoS instance control block
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800263 *
264 * Return: None
265 */
266#define MAX_NOTIFY_LEN 50
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800267static void hdd_wmm_notify_app(struct hdd_wmm_qos_context *qos_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800268{
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700269 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800270 union iwreq_data wrqu;
271 char buf[MAX_NOTIFY_LEN + 1];
272
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800273 hdd_debug("Entered, context %pK", qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800274
Jeff Johnsond36fa332019-03-18 13:42:25 -0700275 if (unlikely((!qos_context) ||
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800276 (HDD_WMM_CTX_MAGIC != qos_context->magic))) {
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700277 hdd_err("Invalid QoS Context");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800278 return;
279 }
280
281 /* create the event */
282 memset(&wrqu, 0, sizeof(wrqu));
283 memset(buf, 0, sizeof(buf));
284
285 snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]",
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800286 (unsigned int)qos_context->handle,
Jeff Johnson5b052512019-03-08 19:32:14 -0800287 (unsigned int)qos_context->status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800288
289 wrqu.data.pointer = buf;
290 wrqu.data.length = strlen(buf);
291
292 /* get pointer to the adapter */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800293 adapter = qos_context->adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800294
295 /* send the event */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700296 hdd_debug("Sending [%s]", buf);
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700297 wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu, buf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800298}
299
300#ifdef FEATURE_WLAN_ESE
301/**
302 * hdd_wmm_inactivity_timer_cb() - inactivity timer callback function
303 *
304 * @user_data: opaque user data registered with the timer. In the
305 * case of this timer, the associated wmm QoS context is registered.
306 *
307 * This timer handler function is called for every inactivity interval
308 * per AC. This function gets the current transmitted packets on the
309 * given AC, and checks if there was any TX activity from the previous
310 * interval. If there was no traffic then it would delete the TS that
311 * was negotiated on that AC.
312 *
313 * Return: None
314 */
315static void hdd_wmm_inactivity_timer_cb(void *user_data)
316{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800317 struct hdd_wmm_qos_context *qos_context = user_data;
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700318 struct hdd_adapter *adapter;
Jeff Johnson4d209002019-03-08 20:27:25 -0800319 struct hdd_wmm_ac_status *ac;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800320 hdd_wlan_wmm_status_e status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530321 QDF_STATUS qdf_status;
Jeff Johnson15bf1b12019-03-09 14:59:58 -0800322 uint32_t traffic_count = 0;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800323 sme_ac_enum_type ac_type;
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530324
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800325 if (!qos_context) {
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530326 hdd_err("invalid user data");
327 return;
328 }
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800329 ac_type = qos_context->ac_type;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800330
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800331 adapter = qos_context->adapter;
Jeff Johnsond36fa332019-03-18 13:42:25 -0700332 if ((!adapter) ||
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700333 (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
334 hdd_err("invalid adapter: %pK", adapter);
c_hpothud5009242016-08-18 12:10:36 +0530335 return;
336 }
337
Jeff Johnson12e12332019-03-08 23:29:23 -0800338 ac = &adapter->hdd_wmm_status.ac_status[ac_type];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800339
340 /* Get the Tx stats for this AC. */
Jeff Johnson15bf1b12019-03-09 14:59:58 -0800341 traffic_count =
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800342 adapter->hdd_stats.tx_rx_stats.tx_classified_ac[qos_context->
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800343 ac_type];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800344
Jeff Johnsonde474b42019-03-09 14:58:07 -0800345 hdd_warn("WMM inactivity check for AC=%d, count=%u, last=%u",
Jeff Johnson15bf1b12019-03-09 14:59:58 -0800346 ac_type, traffic_count, ac->last_traffic_count);
347 if (ac->last_traffic_count == traffic_count) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800348 /* there is no traffic activity, delete the TSPEC for this AC */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800349 status = hdd_wmm_delts(adapter, qos_context->handle);
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700350 hdd_warn("Deleted TS on AC %d, due to inactivity with status = %d!!!",
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800351 ac_type, status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800352 } else {
Jeff Johnson15bf1b12019-03-09 14:59:58 -0800353 ac->last_traffic_count = traffic_count;
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800354 if (ac->inactivity_timer.state == QDF_TIMER_STATE_STOPPED) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800355 /* Restart the timer */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530356 qdf_status =
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800357 qdf_mc_timer_start(&ac->inactivity_timer,
Jeff Johnson154193b2019-03-09 14:42:58 -0800358 ac->inactivity_time);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530359 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700360 hdd_err("Restarting inactivity timer failed on AC %d",
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800361 ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800362 }
363 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530364 QDF_ASSERT(qdf_mc_timer_get_current_state
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800365 (&ac->inactivity_timer) ==
Anurag Chouhan210db072016-02-22 18:42:15 +0530366 QDF_TIMER_STATE_STOPPED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800367 }
368 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800369}
370
371/**
372 * hdd_wmm_enable_inactivity_timer() -
373 * function to enable the traffic inactivity timer for the given AC
374 *
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800375 * @qos_context: [in] pointer to qos_context
Jeff Johnson0a12bbc2019-03-09 15:14:30 -0800376 * @inactivity_time: [in] value of the inactivity interval in millisecs
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800377 *
378 * When a QoS-Tspec is successfully setup, if the inactivity interval
379 * time specified in the AddTS parameters is non-zero, this function
380 * is invoked to start a traffic inactivity timer for the given AC.
381 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530382 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800383 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530384static QDF_STATUS
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800385hdd_wmm_enable_inactivity_timer(struct hdd_wmm_qos_context *qos_context,
Jeff Johnson0a12bbc2019-03-09 15:14:30 -0800386 uint32_t inactivity_time)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800387{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530388 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800389 struct hdd_adapter *adapter = qos_context->adapter;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800390 sme_ac_enum_type ac_type = qos_context->ac_type;
Jeff Johnson4d209002019-03-08 20:27:25 -0800391 struct hdd_wmm_ac_status *ac;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800392
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800393 adapter = qos_context->adapter;
Jeff Johnson12e12332019-03-08 23:29:23 -0800394 ac = &adapter->hdd_wmm_status.ac_status[ac_type];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800395
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800396 qdf_status = qdf_mc_timer_init(&ac->inactivity_timer,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530397 QDF_TIMER_TYPE_SW,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800398 hdd_wmm_inactivity_timer_cb,
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800399 qos_context);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530400 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700401 hdd_err("Initializing inactivity timer failed on AC %d",
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800402 ac_type);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530403 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800404 }
405 /* Start the inactivity timer */
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800406 qdf_status = qdf_mc_timer_start(&ac->inactivity_timer,
Jeff Johnson0a12bbc2019-03-09 15:14:30 -0800407 inactivity_time);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530408 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700409 hdd_err("Starting inactivity timer failed on AC %d",
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800410 ac_type);
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800411 qdf_status = qdf_mc_timer_destroy(&ac->inactivity_timer);
Srinivas Girigowda576b2352017-08-25 14:44:26 -0700412 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800413 hdd_err("Failed to destroy inactivity timer");
Srinivas Girigowda576b2352017-08-25 14:44:26 -0700414
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530415 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800416 }
Jeff Johnson0a12bbc2019-03-09 15:14:30 -0800417 ac->inactivity_time = inactivity_time;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800418 /* Initialize the current tx traffic count on this AC */
Jeff Johnsonde474b42019-03-09 14:58:07 -0800419 ac->last_traffic_count =
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800420 adapter->hdd_stats.tx_rx_stats.tx_classified_ac[qos_context->
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800421 ac_type];
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800422 qos_context->is_inactivity_timer_running = true;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530423 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800424}
425
426/**
427 * hdd_wmm_disable_inactivity_timer() -
428 * function to disable the traffic inactivity timer for the given AC.
429 *
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800430 * @qos_context: [in] pointer to qos_context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800431 *
432 * This function is invoked to disable the traffic inactivity timer
433 * for the given AC. This is normally done when the TS is deleted.
434 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530435 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800436 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530437static QDF_STATUS
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800438hdd_wmm_disable_inactivity_timer(struct hdd_wmm_qos_context *qos_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800439{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800440 struct hdd_adapter *adapter = qos_context->adapter;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800441 sme_ac_enum_type ac_type = qos_context->ac_type;
Jeff Johnson12e12332019-03-08 23:29:23 -0800442 struct hdd_wmm_ac_status *ac = &adapter->hdd_wmm_status.ac_status[ac_type];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530443 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800444
445 /* Clear the timer and the counter */
Jeff Johnson154193b2019-03-09 14:42:58 -0800446 ac->inactivity_time = 0;
Jeff Johnsonde474b42019-03-09 14:58:07 -0800447 ac->last_traffic_count = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800448
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800449 if (qos_context->is_inactivity_timer_running == true) {
450 qos_context->is_inactivity_timer_running = false;
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800451 qdf_status = qdf_mc_timer_stop(&ac->inactivity_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530452 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800453 hdd_err("Failed to stop inactivity timer");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530454 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800455 }
Jeff Johnsona2b8b472019-03-09 14:41:59 -0800456 qdf_status = qdf_mc_timer_destroy(&ac->inactivity_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530457 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800458 hdd_err("Failed to destroy inactivity timer:Timer started");
459 }
460
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530461 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800462}
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530463#else
464
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530465static QDF_STATUS
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800466hdd_wmm_disable_inactivity_timer(struct hdd_wmm_qos_context *qos_context)
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530467{
468 return QDF_STATUS_SUCCESS;
469}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800470#endif /* FEATURE_WLAN_ESE */
471
472/**
473 * hdd_wmm_sme_callback() - callback for QoS notifications
474 *
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -0700475 * @mac_handle: [in] the MAC handle
476 * @context : [in] the HDD callback context
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800477 * @tspec_info : [in] the TSPEC params
Jeff Johnson2059fd72019-03-08 20:06:59 -0800478 * @sme_status : [in] the QoS related SME status
Jeff Johnson104f70e2019-03-08 19:29:33 -0800479 * @flow_id: [in] the unique identifier of the flow
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800480 *
481 * This callback is registered by HDD with SME for receiving QoS
482 * notifications. Even though this function has a static scope it
483 * gets called externally through some function pointer magic (so
484 * there is a need for rigorous parameter checking).
485 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530486 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800487 */
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -0700488static QDF_STATUS hdd_wmm_sme_callback(mac_handle_t mac_handle,
489 void *context,
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800490 struct sme_qos_wmmtspecinfo *tspec_info,
Jeff Johnson2059fd72019-03-08 20:06:59 -0800491 enum sme_qos_statustype sme_status,
Jeff Johnson104f70e2019-03-08 19:29:33 -0800492 uint32_t flow_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800493{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800494 struct hdd_wmm_qos_context *qos_context = context;
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700495 struct hdd_adapter *adapter;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800496 sme_ac_enum_type ac_type;
Jeff Johnson4d209002019-03-08 20:27:25 -0800497 struct hdd_wmm_ac_status *ac;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800498
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800499 hdd_debug("Entered, context %pK", qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800500
Jeff Johnsond36fa332019-03-18 13:42:25 -0700501 if (unlikely((!qos_context) ||
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800502 (HDD_WMM_CTX_MAGIC != qos_context->magic))) {
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700503 hdd_err("Invalid QoS Context");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530504 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800505 }
506
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800507 adapter = qos_context->adapter;
Jeff Johnson239ff2e2019-03-08 19:26:11 -0800508 ac_type = qos_context->ac_type;
Jeff Johnson12e12332019-03-08 23:29:23 -0800509 ac = &adapter->hdd_wmm_status.ac_status[ac_type];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800510
Jeff Johnson36e74c42017-09-18 08:15:42 -0700511 hdd_debug("status %d flowid %d info %pK",
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800512 sme_status, flow_id, tspec_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800513
Jeff Johnson2059fd72019-03-08 20:06:59 -0800514 switch (sme_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800515
516 case SME_QOS_STATUS_SETUP_SUCCESS_IND:
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +0530517 hdd_debug("Setup is complete");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800518
519 /* there will always be a TSPEC returned with this
520 * status, even if a TSPEC is not exchanged OTA
521 */
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800522 if (tspec_info) {
Jeff Johnson0698e662019-03-09 14:24:32 -0800523 ac->is_tspec_valid = true;
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800524 memcpy(&ac->tspec,
525 tspec_info, sizeof(ac->tspec));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800526 }
Jeff Johnsona5548972019-03-09 14:22:18 -0800527 ac->is_access_allowed = true;
Jeff Johnsonc77123d2019-03-09 14:18:34 -0800528 ac->was_access_granted = true;
Jeff Johnsone5b75be2019-03-09 14:07:35 -0800529 ac->is_access_pending = false;
Jeff Johnson1b48ccb2019-03-09 14:15:57 -0800530 ac->has_access_failed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800531
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800532 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800533
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700534 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800535
536 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800537 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800538 HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800539 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800540 }
541
542#ifdef FEATURE_WLAN_ESE
543 /* Check if the inactivity interval is specified */
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800544 if (tspec_info && tspec_info->inactivity_interval) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700545 hdd_debug("Inactivity timer value = %d for AC=%d",
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800546 tspec_info->inactivity_interval, ac_type);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800547 hdd_wmm_enable_inactivity_timer(qos_context,
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800548 tspec_info->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800549 inactivity_interval);
550 }
551#endif /* FEATURE_WLAN_ESE */
552
553 /* notify TL to enable trigger frames if necessary */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800554 hdd_wmm_enable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800555
556 break;
557
558 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700559 hdd_debug("Setup is complete (U-APSD set previously)");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800560
Jeff Johnsona5548972019-03-09 14:22:18 -0800561 ac->is_access_allowed = true;
Jeff Johnsonc77123d2019-03-09 14:18:34 -0800562 ac->was_access_granted = true;
Jeff Johnsone5b75be2019-03-09 14:07:35 -0800563 ac->is_access_pending = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800564
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800565 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800566
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700567 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800568
569 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800570 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800571 HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800572 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800573 }
574
575 break;
576
577 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700578 hdd_err("Setup failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800579 /* QoS setup failed */
580
Jeff Johnsone5b75be2019-03-09 14:07:35 -0800581 ac->is_access_pending = false;
Jeff Johnson1b48ccb2019-03-09 14:15:57 -0800582 ac->has_access_failed = true;
Jeff Johnsona5548972019-03-09 14:22:18 -0800583 ac->is_access_allowed = false;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800584 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800585
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700586 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800587
588 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800589 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800590 HDD_WLAN_WMM_STATUS_SETUP_FAILED;
591
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800592 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800593 }
594
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530595 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800596 hdd_wmm_disable_inactivity_timer(qos_context);
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530597
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800598 /* Setting up QoS Failed, QoS context can be released.
599 * SME is releasing this flow information and if HDD
600 * doesn't release this context, next time if
601 * application uses the same handle to set-up QoS, HDD
602 * (as it has QoS context for this handle) will issue
603 * Modify QoS request to SME but SME will reject as now
604 * it has no information for this flow.
605 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800606 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800607 break;
608
609 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700610 hdd_err("Setup Invalid Params, notify TL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800611 /* QoS setup failed */
Jeff Johnsona5548972019-03-09 14:22:18 -0800612 ac->is_access_allowed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800613
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800614 if (HDD_WMM_HANDLE_IMPLICIT == qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800615
616 /* we note the failure, but we also mark
617 * access as allowed so that the packets will
618 * flow. Note that the MAC will "do the right
619 * thing"
620 */
Jeff Johnsone5b75be2019-03-09 14:07:35 -0800621 ac->is_access_pending = false;
Jeff Johnson1b48ccb2019-03-09 14:15:57 -0800622 ac->has_access_failed = true;
Jeff Johnsona5548972019-03-09 14:22:18 -0800623 ac->is_access_allowed = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800624
625 } else {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700626 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800627
628 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800629 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800630 HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800631 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800632 }
633 break;
634
635 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700636 hdd_err("Setup failed, not a QoS AP");
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800637 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Dustin Brown5e89ef82018-03-14 11:50:23 -0700638 hdd_info("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800639
640 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800641 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800642 HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800643 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800644 }
645 break;
646
647 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700648 hdd_debug("Setup pending");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800649 /* not a callback status -- ignore if we get it */
650 break;
651
652 case SME_QOS_STATUS_SETUP_MODIFIED_IND:
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700653 hdd_debug("Setup modified");
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800654 if (tspec_info) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800655 /* update the TSPEC */
Jeff Johnson0698e662019-03-09 14:24:32 -0800656 ac->is_tspec_valid = true;
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800657 memcpy(&ac->tspec,
658 tspec_info, sizeof(ac->tspec));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800659
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800660 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700661 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800662
663 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800664 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800665 HDD_WLAN_WMM_STATUS_MODIFIED;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800666 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800667 }
668 /* need to tell TL to update its UAPSD handling */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800669 hdd_wmm_enable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800670 }
671 break;
672
673 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800674 if (HDD_WMM_HANDLE_IMPLICIT == qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800675
676 /* this was triggered by implicit QoS so we
677 * know packets are pending
678 */
Jeff Johnsone5b75be2019-03-09 14:07:35 -0800679 ac->is_access_pending = false;
Jeff Johnsonc77123d2019-03-09 14:18:34 -0800680 ac->was_access_granted = true;
Jeff Johnsona5548972019-03-09 14:22:18 -0800681 ac->is_access_allowed = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800682
683 } else {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700684 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800685
686 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800687 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800688 HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800689 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800690 }
691 break;
692
693 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
694 /* nothing to do for now */
695 break;
696
697 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED:
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700698 hdd_err("Setup successful but U-APSD failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800699
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800700 if (HDD_WMM_HANDLE_IMPLICIT == qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800701
702 /* QoS setup was successful but setting U=APSD
703 * failed. Since the OTA part of the request
704 * was successful, we don't mark this as a
705 * failure. the packets will flow. Note that
Jeff Johnson1677bbb2017-01-12 08:39:19 -0800706 * the MAC will "do the right thing"
707 */
Jeff Johnsonc77123d2019-03-09 14:18:34 -0800708 ac->was_access_granted = true;
Jeff Johnsona5548972019-03-09 14:22:18 -0800709 ac->is_access_allowed = true;
Jeff Johnson1b48ccb2019-03-09 14:15:57 -0800710 ac->has_access_failed = false;
Jeff Johnsone5b75be2019-03-09 14:07:35 -0800711 ac->is_access_pending = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800712
713 } else {
Dustin Brown5e89ef82018-03-14 11:50:23 -0700714 hdd_info("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800715
716 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800717 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800718 HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800719 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800720 }
721
722 /* Since U-APSD portion failed disabled trigger frame
723 * generation
724 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800725 hdd_wmm_disable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800726
727 break;
728
729 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700730 hdd_debug("Release is complete");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800731
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800732 if (tspec_info) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700733 hdd_debug("flows still active");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800734
735 /* there is still at least one flow active for
736 * this AC so update the AC state
737 */
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800738 memcpy(&ac->tspec,
739 tspec_info, sizeof(ac->tspec));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800740
741 /* need to tell TL to update its UAPSD handling */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800742 hdd_wmm_enable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800743 } else {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700744 hdd_debug("last flow");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800745
746 /* this is the last flow active for this AC so
747 * update the AC state
748 */
Jeff Johnson0698e662019-03-09 14:24:32 -0800749 ac->is_tspec_valid = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800750
751 /* DELTS is successful, do not allow */
Jeff Johnsona5548972019-03-09 14:22:18 -0800752 ac->is_access_allowed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800753
754 /* need to tell TL to update its UAPSD handling */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800755 hdd_wmm_disable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800756 }
757
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800758 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700759 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800760
761 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800762 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800763 HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800764 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800765 }
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530766 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800767 hdd_wmm_disable_inactivity_timer(qos_context);
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530768
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800769 /* we are done with this flow */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800770 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800771 break;
772
773 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700774 hdd_debug("Release failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800775
776 /* we don't need to update our state or TL since
777 * nothing has changed
778 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800779 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700780 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800781
782 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800783 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800784 HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800785 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800786 }
787
788 break;
789
790 case SME_QOS_STATUS_RELEASE_QOS_LOST_IND:
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700791 hdd_debug("QOS Lost indication received");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800792
793 /* current TSPEC is no longer valid */
Jeff Johnson0698e662019-03-09 14:24:32 -0800794 ac->is_tspec_valid = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800795 /* AP has sent DELTS, do not allow */
Jeff Johnsona5548972019-03-09 14:22:18 -0800796 ac->is_access_allowed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800797
798 /* need to tell TL to update its UAPSD handling */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800799 hdd_wmm_disable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800800
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800801 if (HDD_WMM_HANDLE_IMPLICIT == qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800802 /* we no longer have implicit access granted */
Jeff Johnsonc77123d2019-03-09 14:18:34 -0800803 ac->was_access_granted = false;
Jeff Johnson1b48ccb2019-03-09 14:15:57 -0800804 ac->has_access_failed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800805 } else {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700806 hdd_debug("Explicit Qos, notifying user space");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800807
808 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800809 qos_context->status = HDD_WLAN_WMM_STATUS_LOST;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800810 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800811 }
812
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530813 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800814 hdd_wmm_disable_inactivity_timer(qos_context);
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +0530815
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800816 /* we are done with this flow */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800817 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800818 break;
819
820 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +0530821 hdd_debug("Release pending");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800822 /* not a callback status -- ignore if we get it */
823 break;
824
825 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700826 hdd_err("Release Invalid Params");
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800827 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800828 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800829 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800830 HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800831 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800832 }
833 break;
834
835 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND:
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +0530836 hdd_debug("Modification is complete, notify TL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800837
838 /* there will always be a TSPEC returned with this
839 * status, even if a TSPEC is not exchanged OTA
840 */
Jeff Johnsonc4adb882019-03-08 20:17:52 -0800841 if (tspec_info) {
Jeff Johnson0698e662019-03-09 14:24:32 -0800842 ac->is_tspec_valid = true;
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800843 memcpy(&ac->tspec,
844 tspec_info, sizeof(ac->tspec));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800845 }
846
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800847 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800848 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800849 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800850 HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800851 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800852 }
853 /* notify TL to enable trigger frames if necessary */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800854 hdd_wmm_enable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800855
856 break;
857
858 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800859 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800860 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800861 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800862 HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800863 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800864 }
865 break;
866
867 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
868 /* the flow modification failed so we'll leave in
869 * place whatever existed beforehand
870 */
871
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800872 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800873 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800874 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800875 HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800876 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800877 }
878 break;
879
880 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +0530881 hdd_debug("modification pending");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800882 /* not a callback status -- ignore if we get it */
883 break;
884
885 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
886 /* the flow modification was successful but no QoS
887 * changes required
888 */
889
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800890 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800891 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800892 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800893 HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800894 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800895 }
896 break;
897
898 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
899 /* invalid params -- notify the application */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800900 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800901 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800902 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800903 HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800904 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800905 }
906 break;
907
908 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING:
909 /* nothing to do for now. when APSD is established we'll have work to do */
910 break;
911
912 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED:
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700913 hdd_err("Modify successful but U-APSD failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800914
915 /* QoS modification was successful but setting U=APSD
916 * failed. This will always be an explicit QoS
917 * instance, so all we can do is notify the
918 * application and let it clean up.
919 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800920 if (HDD_WMM_HANDLE_IMPLICIT != qos_context->handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800921 /* this was triggered by an application */
Jeff Johnson5b052512019-03-08 19:32:14 -0800922 qos_context->status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800923 HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800924 hdd_wmm_notify_app(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925 }
926 /* Since U-APSD portion failed disabled trigger frame
927 * generation
928 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800929 hdd_wmm_disable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800930
931 break;
932
933 case SME_QOS_STATUS_HANDING_OFF:
934 /* no roaming so we won't see this */
935 break;
936
937 case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND:
938 /* need to tell TL to stop trigger frame generation */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800939 hdd_wmm_disable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800940 break;
941
942 case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND:
943 /* need to tell TL to start sending trigger frames again */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -0800944 hdd_wmm_enable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800945 break;
946
947 default:
Jeff Johnson2059fd72019-03-08 20:06:59 -0800948 hdd_err("unexpected SME Status=%d", sme_status);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530949 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800950 }
951
952 /* if Tspec only allows downstream traffic then access is not
953 * allowed
954 */
Jeff Johnson0698e662019-03-09 14:24:32 -0800955 if (ac->is_tspec_valid &&
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800956 (ac->tspec.ts_info.direction ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800957 SME_QOS_WMM_TS_DIR_DOWNLINK)) {
Jeff Johnsona5548972019-03-09 14:22:18 -0800958 ac->is_access_allowed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800959 }
960 /* if we have valid Tpsec or if ACM bit is not set, allow access */
Jeff Johnson0698e662019-03-09 14:24:32 -0800961 if ((ac->is_tspec_valid &&
Jeff Johnson64d94dd2019-03-09 14:31:14 -0800962 (ac->tspec.ts_info.direction !=
Jeff Johnson30ac84f2019-03-09 13:57:57 -0800963 SME_QOS_WMM_TS_DIR_DOWNLINK)) || !ac->is_access_required) {
Jeff Johnsona5548972019-03-09 14:22:18 -0800964 ac->is_access_allowed = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800965 }
966
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -0700967 hdd_debug("complete, access for TL AC %d is%sallowed",
Jeff Johnsona5548972019-03-09 14:22:18 -0800968 ac_type, ac->is_access_allowed ? " " : " not ");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800969
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530970 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800971}
972#endif
973
974/**
975 * hdd_wmmps_helper() - Function to set uapsd psb dynamically
976 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700977 * @adapter: [in] pointer to adapter structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800978 * @ptr: [in] pointer to command buffer
979 *
980 * Return: Zero on success, appropriate error on failure.
981 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700982int hdd_wmmps_helper(struct hdd_adapter *adapter, uint8_t *ptr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800983{
Jeff Johnsond36fa332019-03-18 13:42:25 -0700984 if (!adapter) {
Jeff Johnsona7e2e002017-10-02 13:19:58 -0700985 hdd_err("adapter is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800986 return -EINVAL;
987 }
Jeff Johnsond36fa332019-03-18 13:42:25 -0700988 if (!ptr) {
Jeff Johnson5ae20e92016-08-19 13:51:48 -0700989 hdd_err("ptr is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800990 return -EINVAL;
991 }
992 /* convert ASCII to integer */
Jeff Johnson137c8ee2017-10-28 13:06:48 -0700993 adapter->configured_psb = ptr[9] - '0';
994 adapter->psb_changed = HDD_PSB_CHANGED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800995
996 return 0;
997}
998
999/**
1000 * __hdd_wmm_do_implicit_qos() - Function which will attempt to setup
Dustin Brown6725e272019-03-06 12:29:47 -08001001 * QoS for any AC requiring it.
1002 * @qos_context: the QoS context to operate against
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001003 *
1004 * Return: none
1005 */
Dustin Brown6725e272019-03-06 12:29:47 -08001006static void __hdd_wmm_do_implicit_qos(struct hdd_wmm_qos_context *qos_context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001007{
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001008 struct hdd_adapter *adapter;
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001009 sme_ac_enum_type ac_type;
Jeff Johnson4d209002019-03-08 20:27:25 -08001010 struct hdd_wmm_ac_status *ac;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001011#ifndef WLAN_MDM_CODE_REDUCTION_OPT
Jeff Johnson2059fd72019-03-08 20:06:59 -08001012 enum sme_qos_statustype sme_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001013#endif
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001014 struct sme_qos_wmmtspecinfo tspec;
Jeff Johnson1083b6e2017-08-28 11:35:22 -07001015 struct hdd_context *hdd_ctx;
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07001016 mac_handle_t mac_handle;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301017 QDF_STATUS status = QDF_STATUS_SUCCESS;
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05301018 uint8_t dir_ac, mask = 0;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301019 uint16_t nom_msdu_size_ac = 0;
1020 uint32_t rate_ac = 0;
1021 uint16_t sba_ac = 0;
1022 uint32_t uapsd_value = 0;
Abhinav Kumarab576712018-11-05 14:32:49 +05301023 bool is_ts_burst_enable;
1024 enum mlme_ts_info_ack_policy ack_policy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001025
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001026 hdd_debug("Entered, context %pK", qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001027
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001028 adapter = qos_context->adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001029
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001030 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05301031 if (wlan_hdd_validate_context(hdd_ctx))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001032 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001033
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07001034 mac_handle = hdd_ctx->mac_handle;
1035
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001036 ac_type = qos_context->ac_type;
Jeff Johnson12e12332019-03-08 23:29:23 -08001037 ac = &adapter->hdd_wmm_status.ac_status[ac_type];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001038
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001039 hdd_debug("adapter %pK ac_type %d", adapter, ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001040
Jeff Johnson12ccaf62019-03-09 13:59:53 -08001041 if (!ac->is_access_needed) {
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001042 hdd_err("AC %d doesn't need service", ac_type);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001043 qos_context->magic = 0;
1044 qdf_mem_free(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001045 return;
1046 }
1047
Jeff Johnsone5b75be2019-03-09 14:07:35 -08001048 ac->is_access_pending = true;
Jeff Johnson12ccaf62019-03-09 13:59:53 -08001049 ac->is_access_needed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001050
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001051 memset(&tspec, 0, sizeof(tspec));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001052
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001053 tspec.ts_info.psb = adapter->configured_psb;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001054
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001055 switch (ac_type) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001056 case SME_AC_VO:
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001057 tspec.ts_info.up = SME_QOS_WMM_UP_VO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001058 /* Check if there is any valid configuration from framework */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001059 if (HDD_PSB_CFG_INVALID == adapter->configured_psb) {
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05301060 status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc,
1061 &mask);
1062 if (!QDF_IS_STATUS_SUCCESS(status)) {
1063 hdd_err("Get uapsd_mask failed");
1064 return;
1065 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001066 tspec.ts_info.psb = (mask & SME_QOS_UAPSD_VO) ? 1 : 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001067 }
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301068 status = ucfg_mlme_get_wmm_dir_ac_vo(hdd_ctx->psoc,
1069 &dir_ac);
1070 if (!QDF_IS_STATUS_SUCCESS(status)) {
1071 hdd_err("Get infra_dir_ac_vo failed");
1072 return;
1073 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001074 tspec.ts_info.direction = dir_ac;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301075
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001076 tspec.ts_info.tid = 255;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301077
1078 status = ucfg_mlme_get_wmm_uapsd_vo_srv_intv(hdd_ctx->psoc,
1079 &uapsd_value);
1080 if (QDF_IS_STATUS_ERROR(status)) {
1081 hdd_err("Get uapsd_srv_intv failed");
1082 return;
1083 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001084 tspec.min_service_interval = uapsd_value;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301085
1086 status = ucfg_mlme_get_wmm_uapsd_vo_sus_intv(hdd_ctx->psoc,
1087 &uapsd_value);
1088 if (QDF_IS_STATUS_ERROR(status)) {
1089 hdd_err("Get uapsd_vo_sus_intv failed");
1090 return;
1091 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001092 tspec.suspension_interval = uapsd_value;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301093
1094 status = ucfg_mlme_get_wmm_mean_data_rate_ac_vo(hdd_ctx->psoc,
1095 &rate_ac);
1096 if (QDF_IS_STATUS_ERROR(status)) {
1097 hdd_err("Get mean_data_rate_ac_vo failed");
1098 return;
1099 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001100 tspec.mean_data_rate = rate_ac;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301101
1102 status = ucfg_mlme_get_wmm_min_phy_rate_ac_vo(hdd_ctx->psoc,
1103 &rate_ac);
1104 if (QDF_IS_STATUS_ERROR(status)) {
1105 hdd_err("Get min_phy_rate_ac_vo failed");
1106 return;
1107 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001108 tspec.min_phy_rate = rate_ac;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301109
1110 status = ucfg_mlme_get_wmm_nom_msdu_size_ac_vo(hdd_ctx->psoc,
1111 &nom_msdu_size_ac);
1112 if (QDF_IS_STATUS_ERROR(status)) {
1113 hdd_err("Get nom_msdu_size_ac_vo failed");
1114 return;
1115 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001116 tspec.nominal_msdu_size = nom_msdu_size_ac;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301117
1118 status = ucfg_mlme_get_wmm_sba_ac_vo(hdd_ctx->psoc,
1119 &sba_ac);
1120 if (!QDF_IS_STATUS_SUCCESS(status)) {
1121 hdd_err("Get sba_ac_vo failed");
1122 return;
1123 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001124 tspec.surplus_bw_allowance = sba_ac;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05301125
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001126 break;
1127 case SME_AC_VI:
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001128 tspec.ts_info.up = SME_QOS_WMM_UP_VI;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001129 /* Check if there is any valid configuration from framework */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001130 if (HDD_PSB_CFG_INVALID == adapter->configured_psb) {
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05301131 status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc,
1132 &mask);
1133 if (!QDF_IS_STATUS_SUCCESS(status)) {
1134 hdd_err("Get uapsd_mask failed");
1135 return;
1136 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001137 tspec.ts_info.psb = (mask & SME_QOS_UAPSD_VI) ? 1 : 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001138 }
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301139 status = ucfg_mlme_get_wmm_dir_ac_vi(
1140 hdd_ctx->psoc, &dir_ac);
1141 if (!QDF_IS_STATUS_SUCCESS(status)) {
1142 hdd_err("Get infra_dir_ac_vi failed");
1143 return;
1144 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001145 tspec.ts_info.direction = dir_ac;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301146
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001147 tspec.ts_info.tid = 255;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301148 status = ucfg_mlme_get_wmm_uapsd_vi_srv_intv(
1149 hdd_ctx->psoc, &uapsd_value);
1150 if (!QDF_IS_STATUS_SUCCESS(status)) {
1151 hdd_err("Get uapsd_vi_srv_intv failed");
1152 return;
1153 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001154 tspec.min_service_interval = uapsd_value;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301155
1156 status = ucfg_mlme_get_wmm_uapsd_vi_sus_intv(
1157 hdd_ctx->psoc, &uapsd_value);
1158 if (!QDF_IS_STATUS_SUCCESS(status)) {
1159 hdd_err("Get uapsd_vi_sus_intv failed");
1160 return;
1161 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001162 tspec.suspension_interval = uapsd_value;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301163
1164 status = ucfg_mlme_get_wmm_mean_data_rate_ac_vi(
1165 hdd_ctx->psoc, &rate_ac);
1166 if (!QDF_IS_STATUS_SUCCESS(status)) {
1167 hdd_err("Get mean_data_rate_ac_vi failed");
1168 return;
1169 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001170 tspec.mean_data_rate = rate_ac;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301171
1172 status = ucfg_mlme_get_wmm_min_phy_rate_ac_vi(
1173 hdd_ctx->psoc, &rate_ac);
1174 if (!QDF_IS_STATUS_SUCCESS(status)) {
1175 hdd_err("Get min_phy_rate_ac_vi failed");
1176 return;
1177 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001178 tspec.min_phy_rate = rate_ac;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301179
1180 status = ucfg_mlme_get_wmm_nom_msdu_size_ac_vi(
1181 hdd_ctx->psoc, &nom_msdu_size_ac);
1182 if (!QDF_IS_STATUS_SUCCESS(status)) {
1183 hdd_err("Get nom_msdu_size_ac_vi failed");
1184 return;
1185 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001186 tspec.nominal_msdu_size = nom_msdu_size_ac;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301187
1188 status = ucfg_mlme_get_wmm_sba_ac_vi(
1189 hdd_ctx->psoc, &sba_ac);
1190 if (!QDF_IS_STATUS_SUCCESS(status)) {
1191 hdd_err("Get sba_ac_vi failed");
1192 return;
1193 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001194 tspec.surplus_bw_allowance = sba_ac;
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05301195
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001196 break;
1197 default:
1198 case SME_AC_BE:
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001199 tspec.ts_info.up = SME_QOS_WMM_UP_BE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001200 /* Check if there is any valid configuration from framework */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001201 if (HDD_PSB_CFG_INVALID == adapter->configured_psb) {
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05301202 status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc,
1203 &mask);
1204 if (!QDF_IS_STATUS_SUCCESS(status)) {
1205 hdd_err("Get uapsd_mask failed");
1206 return;
1207 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001208 tspec.ts_info.psb = (mask & SME_QOS_UAPSD_BE) ? 1 : 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001209 }
Abhinav Kumare94f2482018-08-19 12:37:36 +05301210 status = ucfg_mlme_get_wmm_dir_ac_be(hdd_ctx->psoc, &dir_ac);
1211 if (!QDF_IS_STATUS_SUCCESS(status)) {
1212 hdd_err("Get infra_dir_ac_be failed");
1213 return;
1214 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001215 tspec.ts_info.direction = dir_ac;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301216
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001217 tspec.ts_info.tid = 255;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301218 status = ucfg_mlme_get_wmm_uapsd_be_srv_intv(hdd_ctx->psoc,
1219 &uapsd_value);
1220 if (!QDF_IS_STATUS_SUCCESS(status)) {
1221 hdd_err("Get uapsd_vi_srv_intv failed");
1222 return;
1223 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001224 tspec.min_service_interval = uapsd_value;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301225
1226 status = ucfg_mlme_get_wmm_uapsd_be_sus_intv(hdd_ctx->psoc,
1227 &uapsd_value);
1228 if (!QDF_IS_STATUS_SUCCESS(status)) {
1229 hdd_err("Get uapsd_vi_sus_intv failed");
1230 return;
1231 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001232 tspec.suspension_interval = uapsd_value;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301233
1234 status = ucfg_mlme_get_wmm_mean_data_rate_ac_be(hdd_ctx->psoc,
1235 &rate_ac);
1236 if (!QDF_IS_STATUS_SUCCESS(status)) {
1237 hdd_err("Get mean_data_rate_ac_be failed");
1238 return;
1239 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001240 tspec.mean_data_rate = rate_ac;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301241
1242 status = ucfg_mlme_get_wmm_min_phy_rate_ac_be(hdd_ctx->psoc,
1243 &rate_ac);
1244 if (!QDF_IS_STATUS_SUCCESS(status)) {
1245 hdd_err("Get min_phy_rate_ac_be failed");
1246 return;
1247 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001248 tspec.min_phy_rate = rate_ac;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301249
1250 status = ucfg_mlme_get_wmm_nom_msdu_size_ac_be(hdd_ctx->psoc,
1251 &nom_msdu_size_ac);
1252 if (!QDF_IS_STATUS_SUCCESS(status)) {
1253 hdd_err("Get nom_msdu_size_ac_be failed");
1254 return;
1255 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001256 tspec.nominal_msdu_size = nom_msdu_size_ac;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301257
1258 status = ucfg_mlme_get_wmm_sba_ac_be(hdd_ctx->psoc, &sba_ac);
1259 if (!QDF_IS_STATUS_SUCCESS(status)) {
1260 hdd_err("Get sba_ac_be failed");
1261 return;
1262 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001263 tspec.surplus_bw_allowance = sba_ac;
Abhinav Kumare94f2482018-08-19 12:37:36 +05301264
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001265 break;
1266 case SME_AC_BK:
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001267 tspec.ts_info.up = SME_QOS_WMM_UP_BK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001268 /* Check if there is any valid configuration from framework */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001269 if (HDD_PSB_CFG_INVALID == adapter->configured_psb) {
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05301270 status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc,
1271 &mask);
1272 if (!QDF_IS_STATUS_SUCCESS(status)) {
1273 hdd_err("Get uapsd_mask failed");
1274 return;
1275 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001276 tspec.ts_info.psb = (mask & SME_QOS_UAPSD_BK) ? 1 : 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001277 }
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301278
1279 status = ucfg_mlme_get_wmm_dir_ac_bk(hdd_ctx->psoc, &dir_ac);
1280 if (!QDF_IS_STATUS_SUCCESS(status)) {
1281 hdd_err("Get infra_dir_ac_bk failed");
1282 return;
1283 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001284 tspec.ts_info.direction = dir_ac;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301285
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001286 tspec.ts_info.tid = 255;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301287 status = ucfg_mlme_get_wmm_uapsd_bk_srv_intv(hdd_ctx->psoc,
1288 &uapsd_value);
1289 if (!QDF_IS_STATUS_SUCCESS(status)) {
1290 hdd_err("Get uapsd_bk_srv_intv failed");
1291 return;
1292 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001293 tspec.min_service_interval = uapsd_value;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301294
1295 status = ucfg_mlme_get_wmm_uapsd_bk_sus_intv(hdd_ctx->psoc,
1296 &uapsd_value);
1297 if (!QDF_IS_STATUS_SUCCESS(status)) {
1298 hdd_err("Get uapsd_bk_sus_intv failed");
1299 return;
1300 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001301 tspec.suspension_interval = uapsd_value;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301302
1303 status = ucfg_mlme_get_wmm_mean_data_rate_ac_bk(hdd_ctx->psoc,
1304 &rate_ac);
1305 if (!QDF_IS_STATUS_SUCCESS(status)) {
1306 hdd_err("Get mean_data_rate_ac_bk failed");
1307 return;
1308 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001309 tspec.mean_data_rate = rate_ac;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301310
1311 status = ucfg_mlme_get_wmm_min_phy_rate_ac_bk(hdd_ctx->psoc,
1312 &rate_ac);
1313 if (!QDF_IS_STATUS_SUCCESS(status)) {
1314 hdd_err("Get min_phy_rate_ac_bk failed");
1315 return;
1316 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001317 tspec.min_phy_rate = rate_ac;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301318
1319 status =
1320 ucfg_mlme_get_wmm_nom_msdu_size_ac_bk(hdd_ctx->psoc,
1321 &nom_msdu_size_ac);
1322 if (!QDF_IS_STATUS_SUCCESS(status)) {
1323 hdd_err("Get nom_msdu_size_ac_bk failed");
1324 return;
1325 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001326 tspec.nominal_msdu_size = nom_msdu_size_ac;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301327
1328 status = ucfg_mlme_get_wmm_sba_ac_bk(hdd_ctx->psoc, &sba_ac);
1329 if (!QDF_IS_STATUS_SUCCESS(status)) {
1330 hdd_err("Get sba_ac_bk failed");
1331 return;
1332 }
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001333 tspec.surplus_bw_allowance = sba_ac;
Abhinav Kumar2af8c122018-08-19 13:49:52 +05301334
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001335 break;
1336 }
1337#ifdef FEATURE_WLAN_ESE
Abhinav Kumarab576712018-11-05 14:32:49 +05301338 ucfg_mlme_get_inactivity_interval(hdd_ctx->psoc, &uapsd_value);
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001339 tspec.inactivity_interval = uapsd_value;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340#endif
Abhinav Kumarab576712018-11-05 14:32:49 +05301341 ucfg_mlme_get_is_ts_burst_size_enable(hdd_ctx->psoc,
1342 &is_ts_burst_enable);
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001343 tspec.ts_info.burst_size_defn = is_ts_burst_enable;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344
Abhinav Kumarab576712018-11-05 14:32:49 +05301345 ucfg_mlme_get_ts_info_ack_policy(hdd_ctx->psoc, &ack_policy);
1346 switch (ack_policy) {
1347 case TS_INFO_ACK_POLICY_NORMAL_ACK:
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001348 tspec.ts_info.ack_policy =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001349 SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1350 break;
1351
Abhinav Kumarab576712018-11-05 14:32:49 +05301352 case TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001353 tspec.ts_info.ack_policy =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001354 SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
1355 break;
1356
1357 default:
1358 /* unknown */
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001359 tspec.ts_info.ack_policy =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001360 SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1361 }
1362
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001363 if (tspec.ts_info.ack_policy ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001364 SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK) {
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001365 if (!sme_qos_is_ts_info_ack_policy_valid(mac_handle, &tspec,
Jeff Johnson9597f3b2019-02-04 14:27:56 -08001366 adapter->vdev_id)) {
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001367 tspec.ts_info.ack_policy =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001368 SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
1369 }
1370 }
1371
Jeff Johnson12e12332019-03-08 23:29:23 -08001372 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnson8f656c62019-03-09 08:48:27 -08001373 list_add(&qos_context->node, &adapter->hdd_wmm_status.context_list);
Jeff Johnson12e12332019-03-08 23:29:23 -08001374 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001375
1376#ifndef WLAN_MDM_CODE_REDUCTION_OPT
Jeff Johnson2059fd72019-03-08 20:06:59 -08001377 sme_status = sme_qos_setup_req(mac_handle,
1378 adapter->vdev_id,
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001379 &tspec,
Jeff Johnson2059fd72019-03-08 20:06:59 -08001380 hdd_wmm_sme_callback,
1381 qos_context,
Jeff Johnson93ca0cd2019-03-09 15:23:10 -08001382 tspec.ts_info.up,
Jeff Johnson2059fd72019-03-08 20:06:59 -08001383 &qos_context->flow_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001384
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001385 hdd_debug("sme_qos_setup_req returned %d flowid %d",
Jeff Johnson2059fd72019-03-08 20:06:59 -08001386 sme_status, qos_context->flow_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001387
1388 /* need to check the return values and act appropriately */
Jeff Johnson2059fd72019-03-08 20:06:59 -08001389 switch (sme_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001390 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
1391 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
1392 /* setup is pending, so no more work to do now. all
1393 * further work will be done in hdd_wmm_sme_callback()
1394 */
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +05301395 hdd_debug("Setup is pending, no further work");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001396
1397 break;
1398
1399 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05301400 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001401 hdd_wmm_disable_inactivity_timer(qos_context);
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05301402
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001403 /* we can't tell the difference between when a request
1404 * fails because AP rejected it versus when SME
1405 * encountered an internal error. in either case SME
1406 * won't ever reference this context so free the
1407 * record
1408 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001409 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001410
1411 /* fall through and start packets flowing */
1412 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
1413 /* no ACM in effect, no need to setup U-APSD */
1414 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
1415 /* no ACM in effect, U-APSD is desired but was already setup */
1416
1417 /* for these cases everything is already setup so we
1418 * can signal TL that it has work to do
1419 */
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +05301420 hdd_debug("Setup is complete, notify TL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001421
Jeff Johnsona5548972019-03-09 14:22:18 -08001422 ac->is_access_allowed = true;
Jeff Johnsonc77123d2019-03-09 14:18:34 -08001423 ac->was_access_granted = true;
Jeff Johnsone5b75be2019-03-09 14:07:35 -08001424 ac->is_access_pending = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001425
1426 break;
1427
1428 default:
Jeff Johnson2059fd72019-03-08 20:06:59 -08001429 hdd_err("unexpected SME Status=%d", sme_status);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301430 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001431 }
1432#endif
1433
1434}
1435
1436/**
1437 * hdd_wmm_do_implicit_qos() - SSR wraper function for hdd_wmm_do_implicit_qos
1438 * @work: pointer to work_struct
1439 *
1440 * Return: none
1441 */
1442static void hdd_wmm_do_implicit_qos(struct work_struct *work)
1443{
Dustin Brown6725e272019-03-06 12:29:47 -08001444 struct hdd_wmm_qos_context *qos_ctx =
1445 container_of(work, struct hdd_wmm_qos_context,
Jeff Johnson7d4a0b52019-03-08 22:06:32 -08001446 implicit_qos_work);
Dustin Brown6725e272019-03-06 12:29:47 -08001447 struct osif_vdev_sync *vdev_sync;
1448
1449 if (qos_ctx->magic != HDD_WMM_CTX_MAGIC) {
1450 hdd_err("Invalid QoS Context");
1451 return;
1452 }
1453
1454 if (osif_vdev_sync_op_start(qos_ctx->adapter->dev, &vdev_sync))
1455 return;
1456
1457 __hdd_wmm_do_implicit_qos(qos_ctx);
1458
1459 osif_vdev_sync_op_stop(vdev_sync);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001460}
1461
Vevek Venkatesan656edfa2020-01-28 13:08:51 +05301462QDF_STATUS hdd_send_dscp_up_map_to_fw(struct hdd_adapter *adapter)
1463{
1464 uint32_t *dscp_to_up_map = adapter->dscp_to_up_map;
1465 struct wlan_objmgr_vdev *vdev = adapter->vdev;
1466 int ret;
1467
1468 if (vdev) {
1469 /* Send DSCP to TID map table to FW */
1470 ret = os_if_fwol_send_dscp_up_map_to_fw(vdev, dscp_to_up_map);
1471 if (ret && ret != -EOPNOTSUPP)
1472 return QDF_STATUS_E_FAILURE;
1473 }
1474
1475 return QDF_STATUS_SUCCESS;
1476}
1477
1478/**
1479 * hdd_fill_dscp_to_up_map() - Fill up dscp_to_up_map table with default values
1480 * @dscp_to_up_map: Array of DSCP-to-UP map
1481 *
1482 * This function will fill up the DSCP-to-UP map table with default values.
1483 *
1484 * Return: QDF_STATUS enumeration
1485 */
1486static inline void hdd_fill_dscp_to_up_map(
1487 enum sme_qos_wmmuptype *dscp_to_up_map)
1488{
1489 uint8_t dscp;
1490
1491 /*
1492 * DSCP to User Priority Lookup Table
1493 * By default use the 3 Precedence bits of DSCP as the User Priority
1494 *
1495 * In case of changing the default map values, need to take care of
1496 * hdd_custom_dscp_up_map as well.
1497 */
1498 for (dscp = 0; dscp <= WLAN_MAX_DSCP; dscp++)
1499 dscp_to_up_map[dscp] = dscp >> 3;
1500
1501 /* Special case for Expedited Forwarding (DSCP 46) in default mapping */
1502 dscp_to_up_map[DSCP(46)] = SME_QOS_WMM_UP_VO;
1503}
1504
1505#ifdef WLAN_CUSTOM_DSCP_UP_MAP
1506/**
1507 * hdd_custom_dscp_up_map() - Customize dscp_to_up_map based on RFC8325
1508 * @dscp_to_up_map: Array of DSCP-to-UP map
1509 *
1510 * This function will customize the DSCP-to-UP map table based on RFC8325..
1511 *
1512 * Return: QDF_STATUS enumeration
1513 */
1514static inline QDF_STATUS hdd_custom_dscp_up_map(
1515 enum sme_qos_wmmuptype *dscp_to_up_map)
1516{
1517 /*
1518 * Customizing few of DSCP to UP mapping based on RFC8325,
1519 * those are different from default hdd_fill_dscp_to_up_map values.
1520 * So, below changes are always relative to hdd_fill_dscp_to_up_map.
1521 */
1522 dscp_to_up_map[DSCP(10)] = SME_QOS_WMM_UP_BE;
1523 dscp_to_up_map[DSCP(12)] = SME_QOS_WMM_UP_BE;
1524 dscp_to_up_map[DSCP(14)] = SME_QOS_WMM_UP_BE;
1525 dscp_to_up_map[DSCP(16)] = SME_QOS_WMM_UP_BE;
1526
1527 dscp_to_up_map[DSCP(18)] = SME_QOS_WMM_UP_EE;
1528 dscp_to_up_map[DSCP(20)] = SME_QOS_WMM_UP_EE;
1529 dscp_to_up_map[DSCP(22)] = SME_QOS_WMM_UP_EE;
1530
1531 dscp_to_up_map[DSCP(24)] = SME_QOS_WMM_UP_CL;
1532 dscp_to_up_map[DSCP(26)] = SME_QOS_WMM_UP_CL;
1533 dscp_to_up_map[DSCP(28)] = SME_QOS_WMM_UP_CL;
1534 dscp_to_up_map[DSCP(30)] = SME_QOS_WMM_UP_CL;
1535
1536 dscp_to_up_map[DSCP(44)] = SME_QOS_WMM_UP_VO;
1537
1538 return QDF_STATUS_SUCCESS;
1539}
1540#else
1541static inline QDF_STATUS hdd_custom_dscp_up_map(
1542 enum sme_qos_wmmuptype *dscp_to_up_map)
1543{
1544 return QDF_STATUS_E_NOSUPPORT;
1545}
1546#endif /* WLAN_CUSTOM_DSCP_UP_MAP */
1547
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001548/**
1549 * hdd_wmm_init() - initialize the WMM DSCP configuation
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001550 * @adapter : [in] pointer to Adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001551 *
1552 * This function will initialize the WMM DSCP configuation of an
1553 * adapter to an initial state. The configuration can later be
1554 * overwritten via application APIs or via QoS Map sent OTA.
1555 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301556 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001557 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001558QDF_STATUS hdd_wmm_init(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001559{
Jeff Johnson6b51b6a2017-11-02 20:31:25 -07001560 enum sme_qos_wmmuptype *dscp_to_up_map = adapter->dscp_to_up_map;
Vevek Venkatesan656edfa2020-01-28 13:08:51 +05301561 struct wlan_objmgr_psoc *psoc = adapter->hdd_ctx->psoc;
1562 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001563
Dustin Brown491d54b2018-03-14 12:39:11 -07001564 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001565
Vevek Venkatesan656edfa2020-01-28 13:08:51 +05301566 if (!psoc) {
1567 hdd_err("Invalid psoc handle");
1568 return QDF_STATUS_E_FAILURE;
1569 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001570
Vevek Venkatesan656edfa2020-01-28 13:08:51 +05301571 hdd_fill_dscp_to_up_map(dscp_to_up_map);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001572
Vevek Venkatesan656edfa2020-01-28 13:08:51 +05301573 if (hdd_custom_dscp_up_map(dscp_to_up_map) == QDF_STATUS_SUCCESS) {
1574 /* Send DSCP to TID map table to FW */
1575 status = hdd_send_dscp_up_map_to_fw(adapter);
1576 }
1577
1578 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001579}
1580
1581/**
1582 * hdd_wmm_adapter_init() - initialize the WMM configuration of an adapter
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001583 * @adapter: [in] pointer to Adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001584 *
1585 * This function will initialize the WMM configuation and status of an
1586 * adapter to an initial state. The configuration can later be
1587 * overwritten via application APIs
1588 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301589 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001590 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001591QDF_STATUS hdd_wmm_adapter_init(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001592{
Jeff Johnsond37476e2019-03-08 20:20:30 -08001593 struct hdd_wmm_ac_status *ac_status;
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001594 sme_ac_enum_type ac_type;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001595
Dustin Brown491d54b2018-03-14 12:39:11 -07001596 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001597
Jeff Johnson26ef71e2019-03-08 23:24:29 -08001598 adapter->hdd_wmm_status.qap = false;
Jeff Johnson8f656c62019-03-09 08:48:27 -08001599 INIT_LIST_HEAD(&adapter->hdd_wmm_status.context_list);
Jeff Johnson12e12332019-03-08 23:29:23 -08001600 mutex_init(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001601
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001602 for (ac_type = 0; ac_type < WLAN_MAX_AC; ac_type++) {
Jeff Johnson12e12332019-03-08 23:29:23 -08001603 ac_status = &adapter->hdd_wmm_status.ac_status[ac_type];
Jeff Johnson30ac84f2019-03-09 13:57:57 -08001604 ac_status->is_access_required = false;
Jeff Johnson12ccaf62019-03-09 13:59:53 -08001605 ac_status->is_access_needed = false;
Jeff Johnsone5b75be2019-03-09 14:07:35 -08001606 ac_status->is_access_pending = false;
Jeff Johnson1b48ccb2019-03-09 14:15:57 -08001607 ac_status->has_access_failed = false;
Jeff Johnsonc77123d2019-03-09 14:18:34 -08001608 ac_status->was_access_granted = false;
Jeff Johnsona5548972019-03-09 14:22:18 -08001609 ac_status->is_access_allowed = false;
Jeff Johnson0698e662019-03-09 14:24:32 -08001610 ac_status->is_tspec_valid = false;
Jeff Johnsonfd297092019-03-09 14:29:20 -08001611 ac_status->is_uapsd_info_valid = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001612 }
1613 /* Invalid value(0xff) to indicate psb not configured through
1614 * framework initially.
1615 */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001616 adapter->configured_psb = HDD_PSB_CFG_INVALID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001617
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301618 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001619}
1620
1621/**
1622 * hdd_wmm_adapter_clear() - Function which will clear the WMM status
1623 * for all the ACs
1624 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001625 * @adapter: [in] pointer to Adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001626 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301627 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001628 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001629QDF_STATUS hdd_wmm_adapter_clear(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001630{
Jeff Johnsond37476e2019-03-08 20:20:30 -08001631 struct hdd_wmm_ac_status *ac_status;
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001632 sme_ac_enum_type ac_type;
Jeff Johnson5ae20e92016-08-19 13:51:48 -07001633
Dustin Brown491d54b2018-03-14 12:39:11 -07001634 hdd_enter();
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001635 for (ac_type = 0; ac_type < WLAN_MAX_AC; ac_type++) {
Jeff Johnson12e12332019-03-08 23:29:23 -08001636 ac_status = &adapter->hdd_wmm_status.ac_status[ac_type];
Jeff Johnson30ac84f2019-03-09 13:57:57 -08001637 ac_status->is_access_required = false;
Jeff Johnson12ccaf62019-03-09 13:59:53 -08001638 ac_status->is_access_needed = false;
Jeff Johnsone5b75be2019-03-09 14:07:35 -08001639 ac_status->is_access_pending = false;
Jeff Johnson1b48ccb2019-03-09 14:15:57 -08001640 ac_status->has_access_failed = false;
Jeff Johnsonc77123d2019-03-09 14:18:34 -08001641 ac_status->was_access_granted = false;
Jeff Johnsona5548972019-03-09 14:22:18 -08001642 ac_status->is_access_allowed = false;
Jeff Johnson0698e662019-03-09 14:24:32 -08001643 ac_status->is_tspec_valid = false;
Jeff Johnsonfd297092019-03-09 14:29:20 -08001644 ac_status->is_uapsd_info_valid = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001645 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301646 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001647}
1648
1649/**
1650 * hdd_wmm_close() - WMM close function
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001651 * @adapter: [in] pointer to adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001652 *
1653 * Function which will perform any necessary work to to clean up the
1654 * WMM functionality prior to the kernel module unload.
1655 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301656 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001657 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001658QDF_STATUS hdd_wmm_adapter_close(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001659{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001660 struct hdd_wmm_qos_context *qos_context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001661
Dustin Brown491d54b2018-03-14 12:39:11 -07001662 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001663
1664 /* free any context records that we still have linked */
Jeff Johnson8f656c62019-03-09 08:48:27 -08001665 while (!list_empty(&adapter->hdd_wmm_status.context_list)) {
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001666 qos_context =
Jeff Johnson8f656c62019-03-09 08:48:27 -08001667 list_first_entry(&adapter->hdd_wmm_status.context_list,
Srinivas Girigowdaea32d6a2017-03-25 00:03:12 -07001668 struct hdd_wmm_qos_context, node);
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05301669
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001670 hdd_wmm_disable_inactivity_timer(qos_context);
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05301671
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001672 if (qos_context->handle == HDD_WMM_HANDLE_IMPLICIT
1673 && qos_context->magic == HDD_WMM_CTX_MAGIC)
Jeff Johnson7d4a0b52019-03-08 22:06:32 -08001674 cds_flush_work(&qos_context->implicit_qos_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001675
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001676 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001677 }
1678
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301679 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001680}
1681
1682/**
1683 * hdd_wmm_classify_pkt() - Function which will classify an OS packet
Govind Singhb7ab5772015-10-08 16:38:37 +05301684 * into a WMM AC based on DSCP
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001685 *
Govind Singhb7ab5772015-10-08 16:38:37 +05301686 * @adapter: adapter upon which the packet is being transmitted
1687 * @skb: pointer to network buffer
1688 * @user_pri: user priority of the OS packet
1689 * @is_eapol: eapol packet flag
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001690 *
1691 * Return: None
1692 */
1693static
Jeff Johnson5b8b67d2017-08-29 14:16:53 -07001694void hdd_wmm_classify_pkt(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001695 struct sk_buff *skb,
Abhishek Singh12be60f2017-08-11 13:52:42 +05301696 enum sme_qos_wmmuptype *user_pri,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001697 bool *is_eapol)
1698{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001699 unsigned char dscp;
Govind Singhb7ab5772015-10-08 16:38:37 +05301700 unsigned char tos;
1701 union generic_ethhdr *eth_hdr;
1702 struct iphdr *ip_hdr;
1703 struct ipv6hdr *ipv6hdr;
1704 unsigned char *pkt;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001705
1706 /* this code is executed for every packet therefore
1707 * all debug code is kept conditional
1708 */
1709
1710#ifdef HDD_WMM_DEBUG
Dustin Brown491d54b2018-03-14 12:39:11 -07001711 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001712#endif /* HDD_WMM_DEBUG */
1713
Govind Singhb7ab5772015-10-08 16:38:37 +05301714 pkt = skb->data;
1715 eth_hdr = (union generic_ethhdr *)pkt;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001716
1717#ifdef HDD_WMM_DEBUG
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001718 hdd_debug("proto is 0x%04x", skb->protocol);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001719#endif /* HDD_WMM_DEBUG */
1720
Govind Singhb7ab5772015-10-08 16:38:37 +05301721 if (eth_hdr->eth_II.h_proto == htons(ETH_P_IP)) {
1722 /* case 1: Ethernet II IP packet */
1723 ip_hdr = (struct iphdr *)&pkt[sizeof(eth_hdr->eth_II)];
1724 tos = ip_hdr->tos;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001725#ifdef HDD_WMM_DEBUG
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001726 hdd_debug("Ethernet II IP Packet, tos is %d", tos);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001727#endif /* HDD_WMM_DEBUG */
1728
Govind Singhb7ab5772015-10-08 16:38:37 +05301729 } else if (eth_hdr->eth_II.h_proto == htons(ETH_P_IPV6)) {
1730 ipv6hdr = ipv6_hdr(skb);
1731 tos = ntohs(*(const __be16 *)ipv6hdr) >> 4;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001732#ifdef HDD_WMM_DEBUG
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001733 hdd_debug("Ethernet II IPv6 Packet, tos is %d", tos);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001734#endif /* HDD_WMM_DEBUG */
Govind Singhb7ab5772015-10-08 16:38:37 +05301735 } else if ((ntohs(eth_hdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
1736 (eth_hdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
1737 (eth_hdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
1738 (eth_hdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
1739 (eth_hdr->eth_8023.h_proto == htons(ETH_P_IP))) {
1740 /* case 2: 802.3 LLC/SNAP IP packet */
1741 ip_hdr = (struct iphdr *)&pkt[sizeof(eth_hdr->eth_8023)];
1742 tos = ip_hdr->tos;
1743#ifdef HDD_WMM_DEBUG
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001744 hdd_debug("802.3 LLC/SNAP IP Packet, tos is %d", tos);
Govind Singhb7ab5772015-10-08 16:38:37 +05301745#endif /* HDD_WMM_DEBUG */
1746 } else if (eth_hdr->eth_II.h_proto == htons(ETH_P_8021Q)) {
1747 /* VLAN tagged */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001748
Govind Singhb7ab5772015-10-08 16:38:37 +05301749 if (eth_hdr->eth_IIv.h_vlan_encapsulated_proto ==
1750 htons(ETH_P_IP)) {
1751 /* case 3: Ethernet II vlan-tagged IP packet */
1752 ip_hdr =
1753 (struct iphdr *)
1754 &pkt[sizeof(eth_hdr->eth_IIv)];
1755 tos = ip_hdr->tos;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001756#ifdef HDD_WMM_DEBUG
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001757 hdd_debug("Ether II VLAN tagged IP Packet, tos is %d",
Jeff Johnson5ae20e92016-08-19 13:51:48 -07001758 tos);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001759#endif /* HDD_WMM_DEBUG */
Srinivas Girigowda683726a2018-09-07 15:10:40 -07001760 } else if ((ntohs(eth_hdr->eth_IIv.h_vlan_encapsulated_proto)
1761 < WLAN_MIN_PROTO) &&
1762 (eth_hdr->eth_8023v.h_snap.dsap ==
Govind Singhb7ab5772015-10-08 16:38:37 +05301763 WLAN_SNAP_DSAP)
1764 && (eth_hdr->eth_8023v.h_snap.ssap ==
1765 WLAN_SNAP_SSAP)
1766 && (eth_hdr->eth_8023v.h_snap.ctrl ==
1767 WLAN_SNAP_CTRL)
1768 && (eth_hdr->eth_8023v.h_proto ==
1769 htons(ETH_P_IP))) {
1770 /* case 4: 802.3 LLC/SNAP vlan-tagged IP packet */
1771 ip_hdr =
1772 (struct iphdr *)
1773 &pkt[sizeof(eth_hdr->eth_8023v)];
1774 tos = ip_hdr->tos;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001775#ifdef HDD_WMM_DEBUG
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001776 hdd_debug("802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
Jeff Johnson5ae20e92016-08-19 13:51:48 -07001777 tos);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001778#endif /* HDD_WMM_DEBUG */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001779 } else {
1780 /* default */
1781#ifdef HDD_WMM_DEBUG
Jeff Johnson5ae20e92016-08-19 13:51:48 -07001782 hdd_warn("VLAN tagged Unhandled Protocol, using default tos");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001783#endif /* HDD_WMM_DEBUG */
Govind Singhb7ab5772015-10-08 16:38:37 +05301784 tos = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001785 }
1786 } else {
1787 /* default */
1788#ifdef HDD_WMM_DEBUG
Jeff Johnson5ae20e92016-08-19 13:51:48 -07001789 hdd_warn("Unhandled Protocol, using default tos");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001790#endif /* HDD_WMM_DEBUG */
Govind Singhb7ab5772015-10-08 16:38:37 +05301791 /* Give the highest priority to 802.1x packet */
1792 if (eth_hdr->eth_II.h_proto ==
1793 htons(HDD_ETHERTYPE_802_1_X)) {
1794 tos = 0xC0;
1795 *is_eapol = true;
1796 } else
1797 tos = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001798 }
1799
Govind Singhb7ab5772015-10-08 16:38:37 +05301800 dscp = (tos >> 2) & 0x3f;
Jeff Johnson6b51b6a2017-11-02 20:31:25 -07001801 *user_pri = adapter->dscp_to_up_map[dscp];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001802
1803#ifdef HDD_WMM_DEBUG
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07001804 hdd_debug("tos is %d, dscp is %d, up is %d", tos, dscp, *user_pri);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001805#endif /* HDD_WMM_DEBUG */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001806}
1807
Jeff Johnsone54e2ae2016-07-18 17:56:20 -07001808/**
1809 * __hdd_get_queue_index() - get queue index
1810 * @up: user priority
1811 *
1812 * Return: queue_index
1813 */
1814static uint16_t __hdd_get_queue_index(uint16_t up)
1815{
1816 if (qdf_unlikely(up >= ARRAY_SIZE(hdd_linux_up_to_ac_map)))
1817 return HDD_LINUX_AC_BE;
1818 return hdd_linux_up_to_ac_map[up];
1819}
1820
hangtianb9c91362019-06-07 10:39:38 +08001821#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || \
1822 defined(QCA_HL_NETDEV_FLOW_CONTROL) || \
1823 defined(QCA_LL_PDEV_TX_FLOW_CONTROL)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001824/**
1825 * hdd_get_queue_index() - get queue index
1826 * @up: user priority
1827 * @is_eapol: is_eapol flag
1828 *
1829 * Return: queue_index
1830 */
1831static
1832uint16_t hdd_get_queue_index(uint16_t up, bool is_eapol)
1833{
Anurag Chouhanc5548422016-02-24 18:33:27 +05301834 if (qdf_unlikely(is_eapol == true))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001835 return HDD_LINUX_AC_HI_PRIO;
Jeff Johnsone54e2ae2016-07-18 17:56:20 -07001836 return __hdd_get_queue_index(up);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001837}
1838#else
1839static
1840uint16_t hdd_get_queue_index(uint16_t up, bool is_eapol)
1841{
Jeff Johnsone54e2ae2016-07-18 17:56:20 -07001842 return __hdd_get_queue_index(up);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001843}
1844#endif
1845
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001846/**
1847 * hdd_wmm_select_queue() - Function which will classify the packet
1848 * according to linux qdisc expectation.
1849 *
1850 * @dev: [in] pointer to net_device structure
1851 * @skb: [in] pointer to os packet
1852 *
1853 * Return: Qdisc queue index
1854 */
Manjunathappa Prakash71140072019-01-31 09:40:23 -08001855static uint16_t hdd_wmm_select_queue(struct net_device *dev,
1856 struct sk_buff *skb)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001857{
Abhishek Singh12be60f2017-08-11 13:52:42 +05301858 enum sme_qos_wmmuptype up = SME_QOS_WMM_UP_BE;
Jeff Johnson55c43882019-03-09 15:59:55 -08001859 uint16_t index;
Rakesh Pillai3e534db2017-09-26 18:59:43 +05301860 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1861 bool is_crtical = false;
1862 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Mukul Sharmabfd19ba2015-10-30 20:35:35 +05301863 int status;
Rakesh Pillai3e534db2017-09-26 18:59:43 +05301864 enum qdf_proto_subtype proto_subtype;
Mukul Sharmabfd19ba2015-10-30 20:35:35 +05301865
1866 status = wlan_hdd_validate_context(hdd_ctx);
1867 if (status != 0) {
1868 skb->priority = SME_QOS_WMM_UP_BE;
1869 return HDD_LINUX_AC_BE;
1870 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001871
Govind Singhb7ab5772015-10-08 16:38:37 +05301872 /* Get the user priority from IP header */
Rakesh Pillai3e534db2017-09-26 18:59:43 +05301873 hdd_wmm_classify_pkt(adapter, skb, &up, &is_crtical);
1874 spin_lock_bh(&adapter->pause_map_lock);
1875 if ((adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL)) &&
1876 !(adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL_PRIORITY))) {
1877 if (qdf_nbuf_is_ipv4_arp_pkt(skb))
1878 is_crtical = true;
1879 else if (qdf_nbuf_is_icmpv6_pkt(skb)) {
1880 proto_subtype = qdf_nbuf_get_icmpv6_subtype(skb);
1881 switch (proto_subtype) {
1882 case QDF_PROTO_ICMPV6_NA:
1883 case QDF_PROTO_ICMPV6_NS:
1884 is_crtical = true;
1885 break;
1886 default:
1887 break;
1888 }
1889 }
1890 }
1891 spin_unlock_bh(&adapter->pause_map_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001892 skb->priority = up;
Jeff Johnson55c43882019-03-09 15:59:55 -08001893 index = hdd_get_queue_index(skb->priority, is_crtical);
Govind Singhb7ab5772015-10-08 16:38:37 +05301894
Jeff Johnson55c43882019-03-09 15:59:55 -08001895 return index;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001896}
1897
Saket Jhaa842ded2019-11-22 15:50:11 -08001898#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
1899uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb,
1900 struct net_device *sb_dev)
1901{
1902 return hdd_wmm_select_queue(dev, skb);
1903}
1904#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
Manjunathappa Prakash666898e2019-01-31 10:01:15 -08001905uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb,
1906 struct net_device *sb_dev,
1907 select_queue_fallback_t fallback)
Manjunathappa Prakash71140072019-01-31 09:40:23 -08001908{
1909 return hdd_wmm_select_queue(dev, skb);
1910}
Manjunathappa Prakash666898e2019-01-31 10:01:15 -08001911#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
1912uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb,
1913 void *accel_priv, select_queue_fallback_t fallback)
1914{
1915 return hdd_wmm_select_queue(dev, skb);
1916}
1917#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
1918uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb,
1919 void *accel_priv)
1920{
1921 return hdd_wmm_select_queue(dev, skb);
1922}
1923#else
1924uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb)
1925{
1926 return hdd_wmm_select_queue(dev, skb);
1927}
1928#endif
1929
Manjunathappa Prakash71140072019-01-31 09:40:23 -08001930
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001931/**
1932 * hdd_wmm_acquire_access_required() - Function which will determine
1933 * acquire admittance for a WMM AC is required or not based on psb configuration
1934 * done in framework
1935 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001936 * @adapter: [in] pointer to adapter structure
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001937 * @ac_type: [in] WMM AC type of OS packet
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001938 *
1939 * Return: void
1940 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001941void hdd_wmm_acquire_access_required(struct hdd_adapter *adapter,
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001942 sme_ac_enum_type ac_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001943{
1944 /* Each bit in the LSB nibble indicates 1 AC.
1945 * Clearing the particular bit in LSB nibble to indicate
1946 * access required
1947 */
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001948 switch (ac_type) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001949 case SME_AC_BK:
1950 /* clear first bit */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001951 adapter->psb_changed &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001952 break;
1953 case SME_AC_BE:
1954 /* clear second bit */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001955 adapter->psb_changed &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001956 break;
1957 case SME_AC_VI:
1958 /* clear third bit */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001959 adapter->psb_changed &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001960 break;
1961 case SME_AC_VO:
1962 /* clear fourth bit */
Jeff Johnson137c8ee2017-10-28 13:06:48 -07001963 adapter->psb_changed &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001964 break;
1965 default:
Jeff Johnson5ae20e92016-08-19 13:51:48 -07001966 hdd_err("Invalid AC Type");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001967 break;
1968 }
1969}
1970
1971/**
1972 * hdd_wmm_acquire_access() - Function which will attempt to acquire
1973 * admittance for a WMM AC
1974 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001975 * @adapter: [in] pointer to adapter context
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001976 * @ac_type: [in] WMM AC type of OS packet
Jeff Johnsona9f092a2019-03-08 19:17:23 -08001977 * @granted: [out] pointer to bool flag when indicates if access
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001978 * has been granted or not
1979 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301980 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001981 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07001982QDF_STATUS hdd_wmm_acquire_access(struct hdd_adapter *adapter,
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001983 sme_ac_enum_type ac_type, bool *granted)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001984{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08001985 struct hdd_wmm_qos_context *qos_context;
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05301986 struct hdd_context *hdd_ctx;
1987 bool enable;
1988 QDF_STATUS status = QDF_STATUS_SUCCESS;
1989
1990 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001991
Rajeev Kumar3d4b1ef2016-01-29 15:57:26 -08001992 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson239ff2e2019-03-08 19:26:11 -08001993 "%s: Entered for AC %d", __func__, ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001994
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05301995 status = ucfg_mlme_get_implicit_qos_is_enabled(hdd_ctx->psoc, &enable);
1996 if (!QDF_IS_STATUS_SUCCESS(status)) {
1997 hdd_err("Get implicit_qos_is_enabled failed");
1998 }
1999 if (!hdd_wmm_is_active(adapter) || !(enable) ||
Jeff Johnson30ac84f2019-03-09 13:57:57 -08002000 !adapter->hdd_wmm_status.ac_status[ac_type].is_access_required) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002001 /* either we don't want QoS or the AP doesn't support
2002 * QoS or we don't want to do implicit QoS
2003 */
Rajeev Kumar3d4b1ef2016-01-29 15:57:26 -08002004 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002005 "%s: QoS not configured on both ends ", __func__);
2006
Jeff Johnsona9f092a2019-03-08 19:17:23 -08002007 *granted =
Jeff Johnson12e12332019-03-08 23:29:23 -08002008 adapter->hdd_wmm_status.ac_status[ac_type].
Jeff Johnsona5548972019-03-09 14:22:18 -08002009 is_access_allowed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002010
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302011 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002012 }
2013 /* do we already have an implicit QoS request pending for this AC? */
Jeff Johnson12ccaf62019-03-09 13:59:53 -08002014 if ((adapter->hdd_wmm_status.ac_status[ac_type].is_access_needed) ||
Jeff Johnsone5b75be2019-03-09 14:07:35 -08002015 (adapter->hdd_wmm_status.ac_status[ac_type].is_access_pending)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002016 /* request already pending so we need to wait for that
2017 * response
2018 */
Rajeev Kumar3d4b1ef2016-01-29 15:57:26 -08002019 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002020 "%s: Implicit QoS for TL AC %d already scheduled",
Jeff Johnson239ff2e2019-03-08 19:26:11 -08002021 __func__, ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002022
Jeff Johnsona9f092a2019-03-08 19:17:23 -08002023 *granted = false;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302024 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002025 }
2026 /* did we already fail to establish implicit QoS for this AC?
2027 * (if so, access should have been granted when the failure
2028 * was handled)
2029 */
Jeff Johnson1b48ccb2019-03-09 14:15:57 -08002030 if (adapter->hdd_wmm_status.ac_status[ac_type].has_access_failed) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002031 /* request previously failed
2032 * allow access, but we'll be downgraded
2033 */
Rajeev Kumar3d4b1ef2016-01-29 15:57:26 -08002034 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002035 "%s: Implicit QoS for TL AC %d previously failed",
Jeff Johnson239ff2e2019-03-08 19:26:11 -08002036 __func__, ac_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002037
Jeff Johnson12e12332019-03-08 23:29:23 -08002038 if (!adapter->hdd_wmm_status.ac_status[ac_type].
Jeff Johnson30ac84f2019-03-09 13:57:57 -08002039 is_access_required) {
Jeff Johnson12e12332019-03-08 23:29:23 -08002040 adapter->hdd_wmm_status.ac_status[ac_type].
Jeff Johnsona5548972019-03-09 14:22:18 -08002041 is_access_allowed = true;
Jeff Johnsona9f092a2019-03-08 19:17:23 -08002042 *granted = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002043 } else {
Jeff Johnson12e12332019-03-08 23:29:23 -08002044 adapter->hdd_wmm_status.ac_status[ac_type].
Jeff Johnsona5548972019-03-09 14:22:18 -08002045 is_access_allowed = false;
Jeff Johnsona9f092a2019-03-08 19:17:23 -08002046 *granted = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002047 }
2048
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302049 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002050 }
2051 /* we need to establish implicit QoS */
Rajeev Kumar3d4b1ef2016-01-29 15:57:26 -08002052 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002053 "%s: Need to schedule implicit QoS for TL AC %d, adapter is %pK",
Jeff Johnson239ff2e2019-03-08 19:26:11 -08002054 __func__, ac_type, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002055
Jeff Johnson12ccaf62019-03-09 13:59:53 -08002056 adapter->hdd_wmm_status.ac_status[ac_type].is_access_needed = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002057
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002058 qos_context = qdf_mem_malloc(sizeof(*qos_context));
Jeff Johnsond36fa332019-03-18 13:42:25 -07002059 if (!qos_context) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002060 /* no memory for QoS context. Nothing we can do but
2061 * let data flow
2062 */
Jeff Johnson5ae20e92016-08-19 13:51:48 -07002063 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002064 "%s: Unable to allocate context", __func__);
Jeff Johnsona5548972019-03-09 14:22:18 -08002065 adapter->hdd_wmm_status.ac_status[ac_type].is_access_allowed =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002066 true;
Jeff Johnsona9f092a2019-03-08 19:17:23 -08002067 *granted = true;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302068 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002069 }
2070
Jeff Johnson239ff2e2019-03-08 19:26:11 -08002071 qos_context->ac_type = ac_type;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002072 qos_context->adapter = adapter;
Jeff Johnson104f70e2019-03-08 19:29:33 -08002073 qos_context->flow_id = 0;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002074 qos_context->handle = HDD_WMM_HANDLE_IMPLICIT;
2075 qos_context->magic = HDD_WMM_CTX_MAGIC;
2076 qos_context->is_inactivity_timer_running = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002077
Jeff Johnson7d4a0b52019-03-08 22:06:32 -08002078 INIT_WORK(&qos_context->implicit_qos_work, hdd_wmm_do_implicit_qos);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002079
Rajeev Kumar3d4b1ef2016-01-29 15:57:26 -08002080 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson36e74c42017-09-18 08:15:42 -07002081 "%s: Scheduling work for AC %d, context %pK",
Jeff Johnson239ff2e2019-03-08 19:26:11 -08002082 __func__, ac_type, qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002083
Jeff Johnson7d4a0b52019-03-08 22:06:32 -08002084 schedule_work(&qos_context->implicit_qos_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002085
2086 /* caller will need to wait until the work takes place and
2087 * TSPEC negotiation completes
2088 */
Jeff Johnsona9f092a2019-03-08 19:17:23 -08002089 *granted = false;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302090 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002091}
2092
2093/**
2094 * hdd_wmm_assoc() - Function which will handle the housekeeping
2095 * required by WMM when association takes place
2096 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002097 * @adapter: [in] pointer to adapter context
Jeff Johnsonfd060852017-10-04 10:50:51 -07002098 * @roam_info: [in] pointer to roam information
Jeff Johnsonfdb993c2019-02-27 09:38:08 -08002099 * @bss_type: [in] type of BSS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002100 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302101 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002102 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002103QDF_STATUS hdd_wmm_assoc(struct hdd_adapter *adapter,
Jeff Johnson172237b2017-11-07 15:32:59 -08002104 struct csr_roam_info *roam_info,
Jeff Johnsonfdb993c2019-02-27 09:38:08 -08002105 eCsrRoamBssType bss_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002106{
Jeff Johnsonc7776f22019-03-09 16:09:31 -08002107 uint8_t uapsd_mask;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302108 QDF_STATUS status;
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05302109 uint32_t srv_value = 0;
2110 uint32_t sus_value = 0;
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002111 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Abhinav Kumarc8c21502018-12-05 15:17:39 +05302112 uint32_t delayed_trgr_frm_int;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002113
2114 /* when we associate we need to notify TL if it needs to
2115 * enable UAPSD for any access categories
2116 */
2117
Dustin Brown491d54b2018-03-14 12:39:11 -07002118 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002119
Jeff Johnsonfd060852017-10-04 10:50:51 -07002120 if (roam_info->fReassocReq) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002121 /* when we reassociate we should continue to use
2122 * whatever parameters were previously established.
2123 * if we are reassociating due to a U-APSD change for
2124 * a particular Access Category, then the change will
2125 * be communicated to HDD via the QoS callback
2126 * associated with the given flow, and U-APSD
2127 * parameters will be updated there
2128 */
2129
Varun Reddy Yeturudd51e8d2017-05-14 14:51:13 -07002130 hdd_debug("Reassoc so no work, Exiting");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002131
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302132 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002133 }
2134 /* get the negotiated UAPSD Mask */
Jeff Johnsonc7776f22019-03-09 16:09:31 -08002135 uapsd_mask =
Jeff Johnsonfd060852017-10-04 10:50:51 -07002136 roam_info->u.pConnectedProfile->modifyProfileFields.uapsd_mask;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002137
Jeff Johnsonc7776f22019-03-09 16:09:31 -08002138 hdd_debug("U-APSD mask is 0x%02x", (int)uapsd_mask);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002139
Abhinav Kumarc8c21502018-12-05 15:17:39 +05302140 ucfg_mlme_get_tl_delayed_trgr_frm_int(hdd_ctx->psoc,
2141 &delayed_trgr_frm_int);
2142
Jeff Johnsonc7776f22019-03-09 16:09:31 -08002143 if (uapsd_mask & HDD_AC_VO) {
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05302144 status = ucfg_mlme_get_wmm_uapsd_vo_srv_intv(hdd_ctx->psoc,
2145 &srv_value);
2146 if (QDF_IS_STATUS_ERROR(status)) {
2147 hdd_err("Get uapsd_srv_intv failed");
2148 return QDF_STATUS_SUCCESS;
2149 }
2150 status = ucfg_mlme_get_wmm_uapsd_vo_sus_intv(hdd_ctx->psoc,
2151 &sus_value);
2152 if (QDF_IS_STATUS_ERROR(status)) {
2153 hdd_err("Get uapsd_vo_sus_intv failed");
2154 return QDF_STATUS_SUCCESS;
2155 }
2156
2157 status = sme_enable_uapsd_for_ac(
Abhinav Kumar18b45cd2018-09-21 12:35:22 +05302158 SME_AC_VO, 7, 7, srv_value, sus_value,
2159 SME_QOS_WMM_TS_DIR_BOTH, 1,
Jeff Johnson9597f3b2019-02-04 14:27:56 -08002160 adapter->vdev_id,
Abhinav Kumarc8c21502018-12-05 15:17:39 +05302161 delayed_trgr_frm_int);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002162
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302163 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002164 }
2165
Jeff Johnsonc7776f22019-03-09 16:09:31 -08002166 if (uapsd_mask & HDD_AC_VI) {
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05302167 status = ucfg_mlme_get_wmm_uapsd_vi_srv_intv(
2168 hdd_ctx->psoc, &srv_value);
2169 if (!QDF_IS_STATUS_SUCCESS(status)) {
2170 hdd_err("Get uapsd_vi_srv_intv failed");
2171 return QDF_STATUS_SUCCESS;
2172 }
2173 status = ucfg_mlme_get_wmm_uapsd_vi_sus_intv(
2174 hdd_ctx->psoc, &sus_value);
2175 if (!QDF_IS_STATUS_SUCCESS(status)) {
2176 hdd_err("Get uapsd_vi_sus_intv failed");
2177 return QDF_STATUS_SUCCESS;
2178 }
2179
2180 status = sme_enable_uapsd_for_ac(
Abhinav Kumar4c8e0262018-10-06 16:50:27 +05302181 SME_AC_VI, 5, 5, srv_value, sus_value,
2182 SME_QOS_WMM_TS_DIR_BOTH, 1,
Jeff Johnson9597f3b2019-02-04 14:27:56 -08002183 adapter->vdev_id,
Abhinav Kumarc8c21502018-12-05 15:17:39 +05302184 delayed_trgr_frm_int);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002185
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302186 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002187 }
2188
Jeff Johnsonc7776f22019-03-09 16:09:31 -08002189 if (uapsd_mask & HDD_AC_BK) {
Abhinav Kumar2af8c122018-08-19 13:49:52 +05302190 status = ucfg_mlme_get_wmm_uapsd_bk_srv_intv(hdd_ctx->psoc,
2191 &srv_value);
2192 if (!QDF_IS_STATUS_SUCCESS(status)) {
2193 hdd_err("Get uapsd_bk_srv_intv failed");
2194 return QDF_STATUS_SUCCESS;
2195 }
2196 status = ucfg_mlme_get_wmm_uapsd_bk_sus_intv(hdd_ctx->psoc,
2197 &sus_value);
2198 if (!QDF_IS_STATUS_SUCCESS(status)) {
2199 hdd_err("Get uapsd_bk_sus_intv failed");
2200 return QDF_STATUS_SUCCESS;
2201 }
2202
2203 status = sme_enable_uapsd_for_ac(
Abhinav Kumar2af8c122018-08-19 13:49:52 +05302204 SME_AC_BK, 2, 2, srv_value, sus_value,
2205 SME_QOS_WMM_TS_DIR_BOTH, 1,
Jeff Johnson9597f3b2019-02-04 14:27:56 -08002206 adapter->vdev_id,
Abhinav Kumarc8c21502018-12-05 15:17:39 +05302207 delayed_trgr_frm_int);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002208
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302209 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002210 }
2211
Jeff Johnsonc7776f22019-03-09 16:09:31 -08002212 if (uapsd_mask & HDD_AC_BE) {
Abhinav Kumare94f2482018-08-19 12:37:36 +05302213 status = ucfg_mlme_get_wmm_uapsd_be_srv_intv(hdd_ctx->psoc,
2214 &srv_value);
2215 if (!QDF_IS_STATUS_SUCCESS(status)) {
2216 hdd_err("Get uapsd_be_srv_intv failed");
2217 return QDF_STATUS_SUCCESS;
2218 }
2219 status = ucfg_mlme_get_wmm_uapsd_be_sus_intv(hdd_ctx->psoc,
2220 &sus_value);
2221 if (!QDF_IS_STATUS_SUCCESS(status)) {
2222 hdd_err("Get uapsd_be_sus_intv failed");
2223 return QDF_STATUS_SUCCESS;
2224 }
2225
2226 status = sme_enable_uapsd_for_ac(
Abhinav Kumare94f2482018-08-19 12:37:36 +05302227 SME_AC_BE, 3, 3, srv_value, sus_value,
2228 SME_QOS_WMM_TS_DIR_BOTH, 1,
Jeff Johnson9597f3b2019-02-04 14:27:56 -08002229 adapter->vdev_id,
Abhinav Kumarc8c21502018-12-05 15:17:39 +05302230 delayed_trgr_frm_int);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002231
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302232 QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002233 }
2234
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07002235 status = sme_update_dsc_pto_up_mapping(hdd_ctx->mac_handle,
Jeff Johnson6b51b6a2017-11-02 20:31:25 -07002236 adapter->dscp_to_up_map,
Jeff Johnson9597f3b2019-02-04 14:27:56 -08002237 adapter->vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002238
Srinivas Girigowda576b2352017-08-25 14:44:26 -07002239 if (!QDF_IS_STATUS_SUCCESS(status))
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002240 hdd_wmm_init(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002241
Dustin Browne74003f2018-03-14 12:51:58 -07002242 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002243
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302244 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002245}
2246
2247static const uint8_t acm_mask_bit[WLAN_MAX_AC] = {
2248 0x4, /* SME_AC_BK */
2249 0x8, /* SME_AC_BE */
2250 0x2, /* SME_AC_VI */
2251 0x1 /* SME_AC_VO */
2252};
2253
2254/**
2255 * hdd_wmm_connect() - Function which will handle the housekeeping
2256 * required by WMM when a connection is established
2257 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002258 * @adapter : [in] pointer to adapter context
Jeff Johnsonfd060852017-10-04 10:50:51 -07002259 * @roam_info: [in] pointer to roam information
Jeff Johnsonfdb993c2019-02-27 09:38:08 -08002260 * @bss_type : [in] type of BSS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002261 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302262 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002263 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002264QDF_STATUS hdd_wmm_connect(struct hdd_adapter *adapter,
Jeff Johnson172237b2017-11-07 15:32:59 -08002265 struct csr_roam_info *roam_info,
Jeff Johnsonfdb993c2019-02-27 09:38:08 -08002266 eCsrRoamBssType bss_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002267{
2268 int ac;
2269 bool qap;
Jeff Johnson5b980192019-03-08 23:01:20 -08002270 bool qos_connection;
Jeff Johnsonc5449d72019-03-08 22:56:08 -08002271 uint8_t acm_mask;
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07002272 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002273
Dustin Brown491d54b2018-03-14 12:39:11 -07002274 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002275
Jeff Johnsonfdb993c2019-02-27 09:38:08 -08002276 if ((eCSR_BSS_TYPE_INFRASTRUCTURE == bss_type) &&
Jeff Johnsonfd060852017-10-04 10:50:51 -07002277 roam_info && roam_info->u.pConnectedProfile) {
2278 qap = roam_info->u.pConnectedProfile->qap;
Jeff Johnson5b980192019-03-08 23:01:20 -08002279 qos_connection = roam_info->u.pConnectedProfile->qosConnection;
Jeff Johnsonc5449d72019-03-08 22:56:08 -08002280 acm_mask = roam_info->u.pConnectedProfile->acm_mask;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002281 } else {
2282 qap = true;
Jeff Johnson5b980192019-03-08 23:01:20 -08002283 qos_connection = true;
Jeff Johnsonc5449d72019-03-08 22:56:08 -08002284 acm_mask = 0x0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002285 }
2286
Jeff Johnson5b980192019-03-08 23:01:20 -08002287 hdd_debug("qap is %d, qos_connection is %d, acm_mask is 0x%x",
2288 qap, qos_connection, acm_mask);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002289
Jeff Johnson26ef71e2019-03-08 23:24:29 -08002290 adapter->hdd_wmm_status.qap = qap;
Jeff Johnson7f63ac92019-03-08 23:26:37 -08002291 adapter->hdd_wmm_status.qos_connection = qos_connection;
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07002292 mac_handle = hdd_adapter_get_mac_handle(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002293
2294 for (ac = 0; ac < WLAN_MAX_AC; ac++) {
Jeff Johnson5b980192019-03-08 23:01:20 -08002295 if (qap && qos_connection && (acm_mask & acm_mask_bit[ac])) {
Varun Reddy Yeturudd51e8d2017-05-14 14:51:13 -07002296 hdd_debug("ac %d on", ac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002297
2298 /* admission is required */
Jeff Johnson12e12332019-03-08 23:29:23 -08002299 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnson30ac84f2019-03-09 13:57:57 -08002300 is_access_required = true;
Jeff Johnson12e12332019-03-08 23:29:23 -08002301 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnsona5548972019-03-09 14:22:18 -08002302 is_access_allowed = false;
Jeff Johnson12e12332019-03-08 23:29:23 -08002303 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnsonc77123d2019-03-09 14:18:34 -08002304 was_access_granted = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002305 /* after reassoc if we have valid tspec, allow access */
Jeff Johnson12e12332019-03-08 23:29:23 -08002306 if (adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnson0698e662019-03-09 14:24:32 -08002307 is_tspec_valid
Jeff Johnson12e12332019-03-08 23:29:23 -08002308 && (adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnson64d94dd2019-03-09 14:31:14 -08002309 tspec.ts_info.direction !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002310 SME_QOS_WMM_TS_DIR_DOWNLINK)) {
Jeff Johnson12e12332019-03-08 23:29:23 -08002311 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnsona5548972019-03-09 14:22:18 -08002312 is_access_allowed = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002313 }
Jeff Johnsonfd060852017-10-04 10:50:51 -07002314 if (!roam_info->fReassocReq &&
yeshwanth sriram guntukaa1ba9a22017-02-28 16:17:32 +05302315 !sme_neighbor_roam_is11r_assoc(
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07002316 mac_handle,
Jeff Johnson9597f3b2019-02-04 14:27:56 -08002317 adapter->vdev_id) &&
Jeff Johnsonfd060852017-10-04 10:50:51 -07002318 !sme_roam_is_ese_assoc(roam_info)) {
Jeff Johnson12e12332019-03-08 23:29:23 -08002319 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnson0698e662019-03-09 14:24:32 -08002320 is_tspec_valid = false;
Jeff Johnson12e12332019-03-08 23:29:23 -08002321 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnsona5548972019-03-09 14:22:18 -08002322 is_access_allowed = false;
yeshwanth sriram guntukaa1ba9a22017-02-28 16:17:32 +05302323 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002324 } else {
Varun Reddy Yeturudd51e8d2017-05-14 14:51:13 -07002325 hdd_debug("ac %d off", ac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002326 /* admission is not required so access is allowed */
Jeff Johnson12e12332019-03-08 23:29:23 -08002327 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnson30ac84f2019-03-09 13:57:57 -08002328 is_access_required = false;
Jeff Johnson12e12332019-03-08 23:29:23 -08002329 adapter->hdd_wmm_status.ac_status[ac].
Jeff Johnsona5548972019-03-09 14:22:18 -08002330 is_access_allowed = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002331 }
2332
2333 }
2334
Dustin Browne74003f2018-03-14 12:51:58 -07002335 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002336
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302337 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002338}
2339
2340/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002341 * hdd_wmm_is_active() - Function which will determine if WMM is
2342 * active on the current connection
2343 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002344 * @adapter: [in] pointer to adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002345 *
2346 * Return: true if WMM is enabled, false if WMM is not enabled
2347 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002348bool hdd_wmm_is_active(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002349{
Jeff Johnson7f63ac92019-03-08 23:26:37 -08002350 if ((!adapter->hdd_wmm_status.qos_connection) ||
Jeff Johnson26ef71e2019-03-08 23:24:29 -08002351 (!adapter->hdd_wmm_status.qap)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002352 return false;
2353 } else {
2354 return true;
2355 }
2356}
2357
Bala Venkateshc725a062018-10-30 15:29:35 +05302358bool hdd_wmm_is_acm_allowed(uint8_t vdev_id)
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002359{
Jeff Johnson5b8b67d2017-08-29 14:16:53 -07002360 struct hdd_adapter *adapter;
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002361 struct hdd_wmm_ac_status *wmm_ac_status;
Bala Venkateshc725a062018-10-30 15:29:35 +05302362 struct hdd_context *hdd_ctx;
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002363
Bala Venkateshc725a062018-10-30 15:29:35 +05302364 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2365 if (!hdd_ctx) {
2366 hdd_err("Unable to fetch the hdd context");
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002367 return false;
2368 }
Bala Venkateshc725a062018-10-30 15:29:35 +05302369
2370 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2371 if (hdd_validate_adapter(adapter)) {
2372 hdd_err("Invalid adapter");
2373 return false;
2374 }
2375
Jeff Johnson12e12332019-03-08 23:29:23 -08002376 wmm_ac_status = adapter->hdd_wmm_status.ac_status;
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002377
2378 if (hdd_wmm_is_active(adapter) &&
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002379 !(wmm_ac_status[QCA_WLAN_AC_VI].is_access_allowed))
Kabilan Kannanf56f9d52017-04-05 03:31:34 -07002380 return false;
2381 return true;
2382}
2383
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002384/**
2385 * hdd_wmm_addts() - Function which will add a traffic spec at the
2386 * request of an application
2387 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002388 * @adapter : [in] pointer to adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002389 * @handle : [in] handle to uniquely identify a TS
Jeff Johnson79d6e5e2019-03-07 22:26:19 -08002390 * @tspec : [in] pointer to the traffic spec
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002391 *
2392 * Return: HDD_WLAN_WMM_STATUS_*
2393 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002394hdd_wlan_wmm_status_e hdd_wmm_addts(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002395 uint32_t handle,
Jeff Johnson79d6e5e2019-03-07 22:26:19 -08002396 struct sme_qos_wmmtspecinfo *tspec)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002397{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002398 struct hdd_wmm_qos_context *qos_context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002399 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
2400#ifndef WLAN_MDM_CODE_REDUCTION_OPT
Jeff Johnson2059fd72019-03-08 20:06:59 -08002401 enum sme_qos_statustype sme_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002402#endif
2403 bool found = false;
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07002404 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002405
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002406 hdd_debug("Entered with handle 0x%x", handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002407
2408 /* see if a context already exists with the given handle */
Jeff Johnson12e12332019-03-08 23:29:23 -08002409 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002410 list_for_each_entry(qos_context,
Jeff Johnson8f656c62019-03-09 08:48:27 -08002411 &adapter->hdd_wmm_status.context_list, node) {
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002412 if (qos_context->handle == handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002413 found = true;
2414 break;
2415 }
2416 }
Jeff Johnson12e12332019-03-08 23:29:23 -08002417 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002418 if (found) {
2419 /* record with that handle already exists */
Jeff Johnson5ae20e92016-08-19 13:51:48 -07002420 hdd_err("Record already exists with handle 0x%x", handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002421
2422 /* Application is trying to modify some of the Tspec
2423 * params. Allow it
2424 */
Jeff Johnson2059fd72019-03-08 20:06:59 -08002425 sme_status = sme_qos_modify_req(mac_handle,
2426 tspec, qos_context->flow_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002427
2428 /* need to check the return value and act appropriately */
Jeff Johnson2059fd72019-03-08 20:06:59 -08002429 switch (sme_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002430 case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
2431 status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
2432 break;
2433 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2434 status =
2435 HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
2436 break;
2437 case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
2438 status =
2439 HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
2440 break;
2441 case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
2442 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
2443 break;
2444 case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
2445 status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2446 break;
2447 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
2448 status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2449 break;
2450 default:
2451 /* we didn't get back one of the
2452 * SME_QOS_STATUS_MODIFY_* status codes
2453 */
Jeff Johnson5ae20e92016-08-19 13:51:48 -07002454 hdd_err("unexpected SME Status=%d",
Jeff Johnson2059fd72019-03-08 20:06:59 -08002455 sme_status);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302456 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002457 return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
2458 }
2459
2460 /* we were successful, save the status */
Jeff Johnson12e12332019-03-08 23:29:23 -08002461 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002462 if (qos_context->magic == HDD_WMM_CTX_MAGIC)
Jeff Johnson5b052512019-03-08 19:32:14 -08002463 qos_context->status = status;
Jeff Johnson12e12332019-03-08 23:29:23 -08002464 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002465
2466 return status;
2467 }
2468
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002469 qos_context = qdf_mem_malloc(sizeof(*qos_context));
Jeff Johnsond36fa332019-03-18 13:42:25 -07002470 if (!qos_context) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002471 /* no memory for QoS context. Nothing we can do */
Jeff Johnson5ae20e92016-08-19 13:51:48 -07002472 hdd_err("Unable to allocate QoS context");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002473 return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
2474 }
2475 /* we assume the tspec has already been validated by the caller */
2476
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002477 qos_context->handle = handle;
Jeff Johnson79d6e5e2019-03-07 22:26:19 -08002478 if (tspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE)
Jeff Johnson239ff2e2019-03-08 19:26:11 -08002479 qos_context->ac_type = hdd_wmm_up_to_ac_map[tspec->ts_info.up];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002480 else {
Jeff Johnson239ff2e2019-03-08 19:26:11 -08002481 hdd_err("ts_info.up (%d) larger than max value (%d), use default ac_type (%d)",
Jeff Johnson79d6e5e2019-03-07 22:26:19 -08002482 tspec->ts_info.up,
Jeff Johnson5ae20e92016-08-19 13:51:48 -07002483 HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hdd_wmm_up_to_ac_map[0]);
Jeff Johnson239ff2e2019-03-08 19:26:11 -08002484 qos_context->ac_type = hdd_wmm_up_to_ac_map[0];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002485 }
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002486 qos_context->adapter = adapter;
Jeff Johnson104f70e2019-03-08 19:29:33 -08002487 qos_context->flow_id = 0;
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002488 qos_context->magic = HDD_WMM_CTX_MAGIC;
2489 qos_context->is_inactivity_timer_running = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002490
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002491 hdd_debug("Setting up QoS, context %pK", qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002492
Jeff Johnson12e12332019-03-08 23:29:23 -08002493 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnson8f656c62019-03-09 08:48:27 -08002494 list_add(&qos_context->node, &adapter->hdd_wmm_status.context_list);
Jeff Johnson12e12332019-03-08 23:29:23 -08002495 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002496
2497#ifndef WLAN_MDM_CODE_REDUCTION_OPT
Jeff Johnson2059fd72019-03-08 20:06:59 -08002498 sme_status = sme_qos_setup_req(mac_handle,
2499 adapter->vdev_id,
2500 tspec,
2501 hdd_wmm_sme_callback,
2502 qos_context,
2503 tspec->ts_info.up,
2504 &qos_context->flow_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002505
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002506 hdd_debug("sme_qos_setup_req returned %d flowid %d",
Jeff Johnson2059fd72019-03-08 20:06:59 -08002507 sme_status, qos_context->flow_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002508
2509 /* need to check the return value and act appropriately */
Jeff Johnson2059fd72019-03-08 20:06:59 -08002510 switch (sme_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002511 case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
2512 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2513 break;
2514 case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
2515 status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
2516 break;
2517 case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
2518 status =
2519 HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
2520 break;
2521 case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
2522 status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
2523 break;
2524 case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05302525 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002526 hdd_wmm_disable_inactivity_timer(qos_context);
2527 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002528 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
2529 case SME_QOS_STATUS_SETUP_FAILURE_RSP:
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05302530 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002531 hdd_wmm_disable_inactivity_timer(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002532 /* we can't tell the difference between when a request
2533 * fails because AP rejected it versus when SME
2534 * encounterd an internal error
2535 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002536 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002537 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2538 case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05302539 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002540 hdd_wmm_disable_inactivity_timer(qos_context);
2541 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002542 return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
2543 default:
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05302544 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002545 hdd_wmm_disable_inactivity_timer(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002546 /* we didn't get back one of the
2547 * SME_QOS_STATUS_SETUP_* status codes
2548 */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002549 hdd_wmm_free_context(qos_context);
Jeff Johnson2059fd72019-03-08 20:06:59 -08002550 hdd_err("unexpected SME Status=%d", sme_status);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302551 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002552 return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
2553 }
2554#endif
2555
2556 /* we were successful, save the status */
Jeff Johnson12e12332019-03-08 23:29:23 -08002557 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002558 if (qos_context->magic == HDD_WMM_CTX_MAGIC)
Jeff Johnson5b052512019-03-08 19:32:14 -08002559 qos_context->status = status;
Jeff Johnson12e12332019-03-08 23:29:23 -08002560 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002561
2562 return status;
2563}
2564
2565/**
2566 * hdd_wmm_delts() - Function which will delete a traffic spec at the
2567 * request of an application
2568 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002569 * @adapter: [in] pointer to adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002570 * @handle: [in] handle to uniquely identify a TS
2571 *
2572 * Return: HDD_WLAN_WMM_STATUS_*
2573 */
Jeff Johnsonde353b82017-10-03 11:44:52 -07002574hdd_wlan_wmm_status_e hdd_wmm_delts(struct hdd_adapter *adapter,
2575 uint32_t handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002576{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002577 struct hdd_wmm_qos_context *qos_context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002578 bool found = false;
Jeff Johnson239ff2e2019-03-08 19:26:11 -08002579 sme_ac_enum_type ac_type = 0;
Jeff Johnson104f70e2019-03-08 19:29:33 -08002580 uint32_t flow_id = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002581 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
2582#ifndef WLAN_MDM_CODE_REDUCTION_OPT
Jeff Johnson2059fd72019-03-08 20:06:59 -08002583 enum sme_qos_statustype sme_status;
Jeff Johnsoncbbc78f2018-06-12 16:25:09 -07002584 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002585#endif
2586
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002587 hdd_debug("Entered with handle 0x%x", handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002588
2589 /* locate the context with the given handle */
Jeff Johnson12e12332019-03-08 23:29:23 -08002590 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002591 list_for_each_entry(qos_context,
Jeff Johnson8f656c62019-03-09 08:48:27 -08002592 &adapter->hdd_wmm_status.context_list, node) {
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002593 if (qos_context->handle == handle) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002594 found = true;
Jeff Johnson239ff2e2019-03-08 19:26:11 -08002595 ac_type = qos_context->ac_type;
Jeff Johnson104f70e2019-03-08 19:29:33 -08002596 flow_id = qos_context->flow_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002597 break;
2598 }
2599 }
Jeff Johnson12e12332019-03-08 23:29:23 -08002600 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002601
2602 if (false == found) {
2603 /* we didn't find the handle */
Jeff Johnson5ae20e92016-08-19 13:51:48 -07002604 hdd_info("handle 0x%x not found", handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002605 return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2606 }
2607
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +05302608 hdd_debug("found handle 0x%x, flow %d, AC %d, context %pK",
Jeff Johnson104f70e2019-03-08 19:29:33 -08002609 handle, flow_id, ac_type, qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002610
2611#ifndef WLAN_MDM_CODE_REDUCTION_OPT
Jeff Johnson2059fd72019-03-08 20:06:59 -08002612 sme_status = sme_qos_release_req(mac_handle, adapter->vdev_id,
2613 flow_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002614
Jeff Johnson2059fd72019-03-08 20:06:59 -08002615 hdd_debug("SME flow %d released, SME status %d", flow_id, sme_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002616
Jeff Johnson2059fd72019-03-08 20:06:59 -08002617 switch (sme_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002618 case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
2619 /* this flow is the only one on that AC, so go ahead
2620 * and update our TSPEC state for the AC
2621 */
Jeff Johnson0698e662019-03-09 14:24:32 -08002622 adapter->hdd_wmm_status.ac_status[ac_type].is_tspec_valid =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002623 false;
Jeff Johnsona5548972019-03-09 14:22:18 -08002624 adapter->hdd_wmm_status.ac_status[ac_type].is_access_allowed =
Sreelakshmi Konamki9d6b75d2016-02-10 12:17:23 +05302625 false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002626
2627 /* need to tell TL to stop trigger timer, etc */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002628 hdd_wmm_disable_tl_uapsd(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002629
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002630 /* disable the inactivity timer */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002631 hdd_wmm_disable_inactivity_timer(qos_context);
Ashish Kumar Dhanotiya80b01b52018-05-01 12:42:46 +05302632
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002633 /* we are done with this context */
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002634 hdd_wmm_free_context(qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002635
2636 /* SME must not fire any more callbacks for this flow
2637 * since the context is no longer valid
2638 */
2639
2640 return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
2641
2642 case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
2643 /* do nothing as we will get a response from SME */
2644 status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
2645 break;
2646
2647 case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
2648 /* nothing we can do with the existing flow except leave it */
2649 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
2650 break;
2651
2652 case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
2653 /* nothing we can do with the existing flow except leave it */
2654 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
Yingying Tang9fad0ca2016-10-20 23:12:36 +08002655 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002656
2657 default:
2658 /* we didn't get back one of the
2659 * SME_QOS_STATUS_RELEASE_* status codes
2660 */
Jeff Johnson2059fd72019-03-08 20:06:59 -08002661 hdd_err("unexpected SME Status=%d", sme_status);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302662 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002663 status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
2664 }
2665
2666#endif
Jeff Johnson12e12332019-03-08 23:29:23 -08002667 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002668 if (qos_context->magic == HDD_WMM_CTX_MAGIC)
Jeff Johnson5b052512019-03-08 19:32:14 -08002669 qos_context->status = status;
Jeff Johnson12e12332019-03-08 23:29:23 -08002670 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002671
2672 return status;
2673}
2674
2675/**
2676 * hdd_wmm_checkts() - Function which will return the status of a traffic
2677 * spec at the request of an application
2678 *
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002679 * @adapter: [in] pointer to adapter context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002680 * @handle: [in] handle to uniquely identify a TS
2681 *
2682 * Return: HDD_WLAN_WMM_STATUS_*
2683 */
Jeff Johnsona7e2e002017-10-02 13:19:58 -07002684hdd_wlan_wmm_status_e hdd_wmm_checkts(struct hdd_adapter *adapter, uint32_t handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002685{
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002686 struct hdd_wmm_qos_context *qos_context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002687 hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
2688
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07002689 hdd_debug("Entered with handle 0x%x", handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002690
2691 /* locate the context with the given handle */
Jeff Johnson12e12332019-03-08 23:29:23 -08002692 mutex_lock(&adapter->hdd_wmm_status.mutex);
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002693 list_for_each_entry(qos_context,
Jeff Johnson8f656c62019-03-09 08:48:27 -08002694 &adapter->hdd_wmm_status.context_list, node) {
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002695 if (qos_context->handle == handle) {
Yeshwanth Sriram Guntuka52bc6bb2017-05-02 16:57:13 +05302696 hdd_debug("found handle 0x%x, context %pK",
Jeff Johnsond4c0ab52019-03-03 10:08:33 -08002697 handle, qos_context);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002698
Jeff Johnson5b052512019-03-08 19:32:14 -08002699 status = qos_context->status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002700 break;
2701 }
2702 }
Jeff Johnson12e12332019-03-08 23:29:23 -08002703 mutex_unlock(&adapter->hdd_wmm_status.mutex);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002704 return status;
2705}