qcacmn: Send TDLS frames with lower AC

If ACM enabled and access is not granted for AC_VI, then send
TDLS frames with lower access category instead of dropping them.

Change-Id: I2201536dc4475764f33eebce1faa0a7df0b2c454
CRs-Fixed: 2119433
diff --git a/umac/cmn_services/inc/wlan_cmn.h b/umac/cmn_services/inc/wlan_cmn.h
index ca690a8..726fc75 100644
--- a/umac/cmn_services/inc/wlan_cmn.h
+++ b/umac/cmn_services/inc/wlan_cmn.h
@@ -204,6 +204,22 @@
 #define WLAN_PHYMODE_MAX      (WLAN_PHYMODE_11AC_VHT80_80 + 1)
 
 /**
+ * enum wifi_traffic_ac - access category type
+ * @WIFI_AC_VO: Voice AC
+ * @WIFI_AC_VI: Video AC
+ * @WIFI_AC_BE: Best effort AC
+ * @WIFI_AC_BK: Background AC
+ * @WIFI_AC_MAX: MAX access category
+ */
+enum wifi_traffic_ac {
+	WIFI_AC_VO = 0,
+	WIFI_AC_VI = 1,
+	WIFI_AC_BE = 2,
+	WIFI_AC_BK = 3,
+	WIFI_AC_MAX = 4,
+};
+
+/**
  * enum wlan_peer_type  - peer type
  * @WLAN_PEER_SELF:     for AP mode, SELF PEER or AP PEER are same
  * @WLAN_PEER_AP:       BSS peer for STA mode, Self peer for AP mode
diff --git a/umac/tdls/core/src/wlan_tdls_cmds_process.c b/umac/tdls/core/src/wlan_tdls_cmds_process.c
index 3b9f1ad..6f54b08 100644
--- a/umac/tdls/core/src/wlan_tdls_cmds_process.c
+++ b/umac/tdls/core/src/wlan_tdls_cmds_process.c
@@ -648,7 +648,7 @@
 	return 0;
 }
 
-int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate)
+int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req)
 {
 	struct tdls_vdev_priv_obj *tdls_vdev;
 	struct tdls_soc_priv_obj *tdls_soc;
@@ -656,6 +656,8 @@
 	struct tdls_peer *temp_peer;
 	QDF_STATUS status;
 
+	struct tdls_validate_action_req *tdls_validate =
+		tdls_mgmt_req->chk_frame;
 
 	if (!tdls_validate || !tdls_validate->vdev)
 		return -EINVAL;
@@ -711,21 +713,15 @@
 		}
 	}
 
-	/*
-	 * Discard TDLS Discovery request and setup confirm if violates
-	 * ACM rules
-	 */
-	if ((TDLS_DISCOVERY_REQUEST == tdls_validate->action_code ||
-		TDLS_SETUP_CONFIRM == tdls_validate->action_code)) {
-		/*  call hdd_wmm_is_acm_allowed() */
-		if (!tdls_soc->tdls_wmm_cb(&tdls_vdev->vdev)) {
-			tdls_err("admission ctrl set to VI, action %d declined",
-				 tdls_validate->action_code);
-			return -EPERM;
-		}
+	/*  call hdd_wmm_is_acm_allowed() */
+	if (!tdls_soc->tdls_wmm_cb(&tdls_vdev->vdev)) {
+		tdls_debug("admission ctrl set to VI, send the frame with least AC (BK) for action %d",
+			   tdls_validate->action_code);
+		tdls_mgmt_req->use_default_ac = false;
+	} else {
+		tdls_mgmt_req->use_default_ac = true;
 	}
 
-
 	if (TDLS_SETUP_REQUEST == tdls_validate->action_code ||
 	    TDLS_SETUP_RESPONSE == tdls_validate->action_code) {
 		if (tdls_soc->max_num_tdls_sta <=
diff --git a/umac/tdls/core/src/wlan_tdls_cmds_process.h b/umac/tdls/core/src/wlan_tdls_cmds_process.h
index 5e2c035..561a40d 100644
--- a/umac/tdls/core/src/wlan_tdls_cmds_process.h
+++ b/umac/tdls/core/src/wlan_tdls_cmds_process.h
@@ -287,14 +287,6 @@
 			  enum tdls_peer_capab cap);
 
 /**
- * tdls_validate_mgmt_request() -validate mgmt request
- * @tdls_validate: action frame request
- *
- * Return: 0 for success or -EINVAL otherwise
- */
-int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate);
-
-/**
  * tdls_process_send_mgmt_rsp() - handle response for send mgmt
  * @rsp: TDLS send mgmt response
  *
@@ -355,7 +347,7 @@
  *
  * Return: 0 for success or -EINVAL otherwise
  */
-int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate);
+int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req);
 
 /**
  * tdls_set_responder() - Set/clear TDLS peer's responder role
diff --git a/umac/tdls/core/src/wlan_tdls_main.h b/umac/tdls/core/src/wlan_tdls_main.h
index bfdcb2c..95178af 100644
--- a/umac/tdls/core/src/wlan_tdls_main.h
+++ b/umac/tdls/core/src/wlan_tdls_main.h
@@ -34,7 +34,6 @@
 #include <wlan_tdls_public_structs.h>
 #include <scheduler_api.h>
 #include "wlan_serialization_api.h"
-#include "wlan_tdls_mgmt.h"
 
 /* Bit mask flag for tdls_option to FW */
 #define ENA_TDLS_OFFCHAN      (1 << 0)  /* TDLS Off Channel support */
diff --git a/umac/tdls/core/src/wlan_tdls_mgmt.c b/umac/tdls/core/src/wlan_tdls_mgmt.c
index d0bbf33..c758219 100644
--- a/umac/tdls/core/src/wlan_tdls_mgmt.c
+++ b/umac/tdls/core/src/wlan_tdls_mgmt.c
@@ -291,6 +291,10 @@
 
 	tdls_mgmt_req->length = sizeof(struct tdls_send_mgmt_request) +
 				action_req->tdls_mgmt.len;
+	if (action_req->use_default_ac)
+		tdls_mgmt_req->ac = WIFI_AC_VI;
+	else
+		tdls_mgmt_req->ac = WIFI_AC_BK;
 
 	/* Send the request to PE. */
 	qdf_mem_zero(&msg, sizeof(msg));
@@ -370,7 +374,7 @@
 	enum wlan_serialization_status ser_cmd_status;
 
 	/* If connected and in Infra. Only then allow this */
-	status = tdls_validate_mgmt_request(tdls_mgmt_req->chk_frame);
+	status = tdls_validate_mgmt_request(tdls_mgmt_req);
 	if (status != QDF_STATUS_SUCCESS) {
 		status = tdls_internal_send_mgmt_tx_done(tdls_mgmt_req,
 							 status);
diff --git a/umac/tdls/core/src/wlan_tdls_mgmt.h b/umac/tdls/core/src/wlan_tdls_mgmt.h
index 3d3e6dd..a6973f1 100644
--- a/umac/tdls/core/src/wlan_tdls_mgmt.h
+++ b/umac/tdls/core/src/wlan_tdls_mgmt.h
@@ -73,6 +73,7 @@
 	uint32_t peer_capability;
 	struct qdf_mac_addr bssid;
 	struct qdf_mac_addr peer_mac;
+	enum wifi_traffic_ac ac;
 	/* Variable length. Dont add any field after this. */
 	uint8_t add_ie[1];
 };
diff --git a/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h b/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h
index eaed561..712a81d 100644
--- a/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h
+++ b/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h
@@ -985,6 +985,7 @@
 	const uint8_t *cmd_buf;
 	uint8_t len;
 	struct tdls_send_mgmt tdls_mgmt;
+	bool use_default_ac;
 };
 
 /**
diff --git a/umac/tdls/dispatcher/src/wlan_tdls_tgt_api.c b/umac/tdls/dispatcher/src/wlan_tdls_tgt_api.c
index 4100c29..8b35247 100644
--- a/umac/tdls/dispatcher/src/wlan_tdls_tgt_api.c
+++ b/umac/tdls/dispatcher/src/wlan_tdls_tgt_api.c
@@ -26,6 +26,7 @@
 #include <wlan_tdls_tgt_api.h>
 #include "../../core/src/wlan_tdls_main.h"
 #include "../../core/src/wlan_tdls_cmds_process.h"
+#include "../../core/src/wlan_tdls_mgmt.h"
 
 static inline struct wlan_lmac_if_tdls_tx_ops *
 wlan_psoc_get_tdls_txops(struct wlan_objmgr_psoc *psoc)
diff --git a/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c b/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c
index 0d8f34c..930ea1b 100644
--- a/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c
+++ b/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c
@@ -27,6 +27,7 @@
 #include "../../core/src/wlan_tdls_main.h"
 #include "../../core/src/wlan_tdls_cmds_process.h"
 #include "../../core/src/wlan_tdls_ct.h"
+#include "../../core/src/wlan_tdls_mgmt.h"
 #include <wlan_objmgr_global_obj.h>
 #include <wlan_objmgr_cmn.h>
 #include "wlan_policy_mgr_api.h"