Merge tag 'LA.UM.9.6.2.c25-02800-89xx.0' into int/11/fp3

"LA.UM.9.6.2.c25-02800-89xx.0"

* tag 'LA.UM.9.6.2.c25-02800-89xx.0':
  qcacld-2.0: Fix array OOB for duplicate rate
  wlan: Avoid OOB read in dot11f_unpack_assoc_response
  wlan: Fix possible OOB in UnpackTlvCore
  wlan: Do not make hdd context as NULL in hdd adapter
  wlan: Fix missing sta_id hash attach in ap mode
  wlan: Fix possible OOB in unpack_tlv_core
  wlan: Drop invalid EAPOL packets in SAP mode
  wlan: Drop invalid AMSDU subframe
  prima: Send assoc reject upon failing to post ASSOC_IND

Change-Id: I52faf6e6134e5f50b84aa8ce7c451da4a0160c9a
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 0b5b8fe..bd58455 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -2110,6 +2110,11 @@
 #define CFG_ENABLE_RX_STBC_MAX                   ( 1 )
 #define CFG_ENABLE_RX_STBC_DEFAULT               ( 1 )
 
+#define CFG_ENABLE_TX_STBC                       "gEnableTXSTBC"
+#define CFG_ENABLE_TX_STBC_MIN                   ( 0 )
+#define CFG_ENABLE_TX_STBC_MAX                   ( 1 )
+#define CFG_ENABLE_TX_STBC_DEFAULT               ( 1 )
+
 /* 
  * Enable/Disable vsta based on MAX Assoc limit 
  * defined in WCNSS_qcom_cfg.ini.
@@ -3695,6 +3700,7 @@
    v_U16_t                     configMccParam;
    v_U32_t                     numBuffAdvert;
    v_BOOL_t                    enableRxSTBC;
+   v_BOOL_t                    enableTxSTBC;
 #ifdef FEATURE_WLAN_TDLS       
    v_BOOL_t                    fEnableTDLSSupport;
    v_BOOL_t                    fEnableTDLSImplicitTrigger;
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index be208ae..a52093c 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -2119,6 +2119,29 @@
 }
 #endif
 
+#define JOINT_MULTI_BAND_RSNA 0x01
+#define PEER_KEY_ENABLED 0x02
+#define AMSDU_CAPABLE 0x04
+#define AMSDU_REQUIRED 0x08
+#define PBAC 0x10
+#define EXT_KEY_ID 0x20
+#define OCVC 0x40
+#define RESERVED 0x80
+
+/**
+ * wlan_hdd_mask_unsupported_rsn_caps() - Mask unsupported RSN CAPs in RSN IE
+ * @pBuf: pointer to rsn_ie
+ * @ielen: rsn_ie len
+ *
+ * This function is used to point rsn cap element in rsn IE and mask the rsn
+ * caps bits which driver doesn't support.
+ *
+ * Return: None
+ */
+void
+wlan_hdd_mask_unsupported_rsn_caps(tANI_U8 *pBuf, tANI_S16 ielen);
+
+
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
 #define nla_parse(a, b, c, d, e) nla_parse(a, b, c, d, e, NULL)
 #define cfg80211_sched_scan_results(a) cfg80211_sched_scan_results(a, 0)
diff --git a/CORE/HDD/inc/wlan_hdd_wmm.h b/CORE/HDD/inc/wlan_hdd_wmm.h
index 4e1eb23..16cee8f 100644
--- a/CORE/HDD/inc/wlan_hdd_wmm.h
+++ b/CORE/HDD/inc/wlan_hdd_wmm.h
@@ -264,14 +264,23 @@
   @return         : Qdisc queue index
   ===========================================================================*/
 
-v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
-                                 , void *accel_priv
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
+uint16_t hdd_hostapd_select_queue(struct net_device *dev, struct sk_buff *skb,
+				  struct net_device *sb_dev,
+				  select_queue_fallback_t fallbac);
+
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+uint16_t hdd_hostapd_select_queue(struct net_device *dev, struct sk_buff *skb,
+				  void *accel_priv,
+				  select_queue_fallback_t fallbac);
+
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
+uint16_t hdd_hostapd_select_queue(struct net_device *dev, struct sk_buff *skb,
+				  void *accel_priv);
+
+#else
+uint16_t hdd_hostapd_select_queue(struct net_device *dev, struct sk_buff *skb);
 #endif
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
-                                 , select_queue_fallback_t fallbac
-#endif
-);
 
 
 /**============================================================================
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 02586ab..b16c3d4 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -2493,6 +2493,12 @@
               CFG_ENABLE_RX_STBC_DEFAULT,
               CFG_ENABLE_RX_STBC_MIN,
               CFG_ENABLE_RX_STBC_MAX ),
+   REG_VARIABLE( CFG_ENABLE_TX_STBC, WLAN_PARAM_Integer,
+              hdd_config_t, enableTxSTBC,
+              VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+              CFG_ENABLE_TX_STBC_DEFAULT,
+              CFG_ENABLE_TX_STBC_MIN,
+              CFG_ENABLE_TX_STBC_MAX ),
 #ifdef FEATURE_WLAN_TDLS
    REG_VARIABLE( CFG_TDLS_SUPPORT_ENABLE, WLAN_PARAM_Integer,
               hdd_config_t, fEnableTDLSSupport,
@@ -5928,6 +5934,14 @@
          hddLog(LOGE, "Could not pass on WNI_CFG_VHT_RXSTBC to CCM");
      }
 
+     if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_TXSTBC,
+                     pConfig->enableTxSTBC, NULL, eANI_BOOLEAN_FALSE)
+         == eHAL_STATUS_FAILURE)
+     {
+         fStatus = FALSE;
+         hddLog(LOGE, "Could not pass on WNI_CFG_VHT_TXSTBC to CCM");
+     }
+
 #ifdef WLAN_SOFTAP_VSTA_FEATURE
      if(pConfig->fEnableVSTASupport)
      {
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 138ce72..c8035f9 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -9503,6 +9503,11 @@
     {
         wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
     }
+    if (pCfg->enableTxSTBC)
+    {
+        wlan_hdd_band_2_4_GHZ.vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
+        wlan_hdd_band_5_GHZ.vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
+    }
     /*
      * In case of static linked driver at the time of driver unload,
      * module exit doesn't happens. Module cleanup helps in cleaning
@@ -15954,14 +15959,23 @@
 
     if( request->n_channels )
     {
-        char chList [(request->n_channels*5)+1];
         int len;
+	char *chList;
+
+	chList = vos_mem_malloc((request->n_channels * 5) + 1);
+	if (!chList) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       "%s: memory alloc failed channelList", __func__);
+		status = -ENOMEM;
+	}
+
         channelList = vos_mem_malloc( request->n_channels );
         if( NULL == channelList )
         {
             hddLog(VOS_TRACE_LEVEL_ERROR,
                            "%s: memory alloc failed channelList", __func__);
             status = -ENOMEM;
+	    vos_mem_free(chList);
             goto free_mem;
         }
 
@@ -15973,6 +15987,7 @@
 
         hddLog(VOS_TRACE_LEVEL_INFO,
                            "Channel-List:  %s ", chList);
+	vos_mem_free(chList);
     }
 
     scanRequest.ChannelInfo.numOfChannels = request->n_channels;
@@ -16759,6 +16774,102 @@
     return 0;
 }
 
+static void framesntohs(v_U16_t *pOut,
+                        v_U8_t  *pIn,
+                        unsigned char fMsb)
+{
+#   if defined ( DOT11F_LITTLE_ENDIAN_HOST )
+    if ( !fMsb )
+    {
+        vos_mem_copy(( v_U16_t* )pOut, pIn, 2);
+    }
+    else
+    {
+        *pOut = ( v_U16_t )( *pIn << 8 ) | *( pIn + 1 );
+    }
+#   else
+    if ( !fMsb )
+    {
+        *pOut = ( v_U16_t )( *pIn | ( *( pIn + 1 ) << 8 ) );
+    }
+    else
+    {
+        vos_mem_copy(( v_U16_t* )pOut, pIn, 2);
+    }
+#   endif
+}
+
+void
+wlan_hdd_mask_unsupported_rsn_caps(tANI_U8 *pBuf, tANI_S16 ielen)
+{
+    u16 pwise_cipher_suite_count, akm_suite_cnt, mask = 0;
+    u8 *rsn_cap;
+
+    if (unlikely(ielen < 2)) {
+        return;
+    }
+
+    pBuf += 2;
+    ielen -= (tANI_U8)2;
+
+    if (unlikely(ielen < 4)) {
+        return;
+    }
+
+    pBuf += 4;
+    ielen -= (tANI_U8)4;
+
+    if (unlikely(ielen < 2)) {
+        return;
+    }
+
+    framesntohs(&pwise_cipher_suite_count, pBuf, 0);
+    pBuf += 2;
+    ielen -= (tANI_U8)2;
+
+    if (unlikely(ielen < pwise_cipher_suite_count * 4)) {
+        return;
+    }
+
+    if (!pwise_cipher_suite_count ||
+        pwise_cipher_suite_count > 4){
+        return;
+    }
+
+    pBuf += (pwise_cipher_suite_count * 4);
+    ielen -= (pwise_cipher_suite_count * 4);
+
+    if (unlikely(ielen < 2)) {
+        return;
+    }
+
+    framesntohs(&akm_suite_cnt, pBuf, 0);
+    pBuf += 2;
+    ielen -= (tANI_U8)2;
+
+    if (unlikely(ielen < akm_suite_cnt * 4)) {
+        return;
+    }
+
+    if (!akm_suite_cnt ||
+        akm_suite_cnt > 4){
+        return;
+    }
+
+    pBuf += (akm_suite_cnt * 4);
+    ielen -= (akm_suite_cnt * 4);
+
+    if (unlikely(ielen < 2)) {
+        return;
+    }
+
+    rsn_cap = pBuf;
+    mask = ~(JOINT_MULTI_BAND_RSNA | PEER_KEY_ENABLED | AMSDU_CAPABLE |
+             AMSDU_REQUIRED | PBAC | EXT_KEY_ID | OCVC | RESERVED);
+    rsn_cap[1] &= mask;
+
+    return;
+}
 
 /*
  * FUNCTION: wlan_hdd_cfg80211_set_ie
@@ -17071,6 +17182,8 @@
                 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
                 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
                 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
+                wlan_hdd_mask_unsupported_rsn_caps(pWextState->WPARSNIE + 2,
+                                                   eLen);
                 break;
 
                 /* Appending extended capabilities with Interworking or
@@ -20389,9 +20502,17 @@
     num_ch = 0;
     if (request->n_channels)
     {
-        char chList [(request->n_channels*5)+1];
         int len;
-        for (i = 0, len = 0; i < request->n_channels; i++)
+	char *chList;
+
+	chList = vos_mem_malloc((request->n_channels * 5) + 1);
+	if (!chList) {
+		hddLog(VOS_TRACE_LEVEL_ERROR,
+		       "%s: memory alloc failed channelList", __func__);
+		status = -ENOMEM;
+	}
+
+	for (i = 0, len = 0; i < request->n_channels; i++)
         {
             for (indx = 0; indx < num_channels_allowed; indx++)
             {
@@ -20422,8 +20543,10 @@
             VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
              "%s : All requested channels are DFS channels", __func__);
             ret = -EINVAL;
+	    vos_mem_free(chList);
             goto error;
         }
+	vos_mem_free(chList);
      }
 
     pnoRequest.aNetworks =
diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c
index 174f1ea..537e7ae 100644
--- a/CORE/HDD/src/wlan_hdd_early_suspend.c
+++ b/CORE/HDD/src/wlan_hdd_early_suspend.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018, 2021 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -2146,17 +2146,20 @@
     vos_ssr_unprotect(__func__);
 }
 
-static void hdd_ssr_timer_init(void)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
+static void hdd_ssr_timer_cb(struct timer_list *data)
 {
-    init_timer(&ssr_timer);
+	hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
+
+#ifdef WCN_PRONTO
+	if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
+		wcnss_pronto_log_debug_regs();
+#endif
+
+	VOS_BUG(0);
 }
 
-static void hdd_ssr_timer_del(void)
-{
-    del_timer(&ssr_timer);
-    ssr_timer_started = false;
-}
-
+#else
 static void hdd_ssr_timer_cb(unsigned long data)
 {
     hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__);
@@ -2168,6 +2171,26 @@
 
     VOS_BUG(0);
 }
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
+static void hdd_ssr_timer_init(void)
+{
+	timer_setup(&ssr_timer, hdd_ssr_timer_cb, 0);
+}
+
+#else
+static void hdd_ssr_timer_init(void)
+{
+	init_timer(&ssr_timer);
+}
+#endif
+
+static void hdd_ssr_timer_del(void)
+{
+    del_timer(&ssr_timer);
+    ssr_timer_started = false;
+}
 
 static void hdd_ssr_timer_start(int msec)
 {
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 903781a..ca1e7df 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -257,15 +257,21 @@
 void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable);
 void hdd_set_olpc_mode(tHalHandle hHal, bool low_power);
 
-v_U16_t hdd_select_queue(struct net_device *dev,
-    struct sk_buff *skb
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
-    , void *accel_priv
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
+uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb,
+			  struct net_device *sb_dev,
+			  select_queue_fallback_t fallback);
+
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb,
+			  void *accel_priv, select_queue_fallback_t fallback);
+
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
+uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb,
+			  void *accel_priv);
+#else
+uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb);
 #endif
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
-    , select_queue_fallback_t fallback
-#endif
-);
 
 #ifdef WLAN_FEATURE_PACKET_FILTERING
 static void hdd_set_multicast_list(struct net_device *dev);
@@ -4033,7 +4039,6 @@
 static void hdd_init_sw_pta(hdd_context_t *hdd_ctx)
 {
 	init_completion(&hdd_ctx->sw_pta_comp);
-	wcnss_update_bt_profile();
 }
 
 static void hdd_deinit_sw_pta(hdd_context_t *hdd_ctx)
@@ -12220,19 +12225,31 @@
   \return - ac, Queue Index/access category corresponding to UP in IP header 
   
   --------------------------------------------------------------------------*/
-v_U16_t hdd_select_queue(struct net_device *dev,
-    struct sk_buff *skb
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
-    , void *accel_priv
-#endif
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
-    , select_queue_fallback_t fallback
-#endif
-)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
+v_U16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb,
+			 struct net_device *sb_dev,
+			 select_queue_fallback_t fallback)
 {
-   return hdd_wmm_select_queue(dev, skb);
+	return hdd_wmm_select_queue(dev, skb);
 }
-
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+v_U16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb,
+			 void *accel_priv, select_queue_fallback_t fallback)
+{
+	return hdd_wmm_select_queue(dev, skb);
+}
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
+v_U16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb,
+			 void *accel_priv)
+{
+	return hdd_wmm_select_queue(dev, skb);
+}
+#else
+v_U16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb)
+{
+	return hdd_wmm_select_queue(dev, skb);
+}
+#endif
 
 /**---------------------------------------------------------------------------
 
@@ -14135,6 +14152,7 @@
 #endif /* WLAN_KD_READY_NOTIFIER */
 
    vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
+   hdd_init_sw_pta(pHddCtx);
    status = vos_open( &pVosContext, pHddCtx->parent_dev);
    if ( !VOS_IS_STATUS_SUCCESS( status ))
    {
@@ -14767,7 +14785,7 @@
 
    mutex_init(&pHddCtx->cache_channel_lock);
 
-   hdd_init_sw_pta(pHddCtx);
+   wcnss_update_bt_profile();
    goto success;
 
 err_open_cesium_nl_sock:
@@ -16243,8 +16261,12 @@
    hdd_context_t *hdd_ctx = NULL;
    hdd_adapter_t *adapter = NULL;
    v_CONTEXT_t vos_context = NULL;
+   tANI_U8 type = 0;
+   tANI_U8 subType = 0;
    struct ieee80211_mgmt *mgmt =
            (struct ieee80211_mgmt *)frame_ind->frameBuf;
+   tANI_U8* pbFrames;
+   tANI_U32 nFrameLength;
 
    /* Get the global VOSS context.*/
    vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
@@ -16266,7 +16288,38 @@
         return;
    }
 
-   adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
+   /* Try to retrieve the adapter from the mac address list*/
+     type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
+     subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
+     pbFrames = frame_ind->frameBuf;
+     nFrameLength = frame_ind->frameLen;
+
+    /* Get pAdapter from Destination mac address of the frame */
+    if ((type == SIR_MAC_MGMT_FRAME) &&
+        (subType != SIR_MAC_MGMT_PROBE_REQ) &&
+        (frame_ind->frameLen > WLAN_HDD_80211_FRM_DA_OFFSET + VOS_MAC_ADDR_SIZE)
+	&&
+        !vos_is_macaddr_broadcast(
+         (v_MACADDR_t *)&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]))
+      {
+         adapter = hdd_get_adapter_by_macaddr(hdd_ctx,
+                               &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]);
+         if (NULL == adapter)
+         {
+             /* Under assumtion that we don't receive any action frame
+              * with BCST as destination we dropping action frame
+              */
+             hddLog(VOS_TRACE_LEVEL_FATAL,"pAdapter for action frame is NULL Macaddr = "
+                               MAC_ADDRESS_STR ,
+                               MAC_ADDR_ARRAY(&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]));
+             hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Frame Type = %d Frame Length = %d"
+                              " subType = %d",__func__,frame_ind->frameType,nFrameLength,subType);
+             return;
+         }
+       }
+
+   if (adapter == NULL)
+       adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
                                           frame_ind->sessionId);
 
    if ((NULL != adapter) &&
diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c
index b0f5f00..b30046f 100644
--- a/CORE/HDD/src/wlan_hdd_p2p.c
+++ b/CORE/HDD/src/wlan_hdd_p2p.c
@@ -253,13 +253,11 @@
        )
     {
         tANI_U8 sessionId = pAdapter->sessionId;
-        if( REMAIN_ON_CHANNEL_REQUEST == req_type )
-        {
+            wlan_hdd_cfg80211_deregister_frames(pAdapter);
             sme_DeregisterMgmtFrame(
                        hHal, sessionId,
                       (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4),
                        NULL, 0 );
-        }
     }
     else if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
     {
@@ -661,8 +659,6 @@
             return -EINVAL;
         }
 
-        if( REMAIN_ON_CHANNEL_REQUEST == request_type)
-        {
             if( eHAL_STATUS_SUCCESS != sme_RegisterMgmtFrame(
                         WLAN_HDD_GET_HAL_CTX(pAdapter),
                         sessionId, (SIR_MAC_MGMT_FRAME << 2) |
@@ -670,7 +666,7 @@
             {
                 hddLog(VOS_TRACE_LEVEL_ERROR,    "sme_RegisterMgmtFrame returned fail");
             }
-        }
+	    wlan_hdd_cfg80211_register_frames(pAdapter);
 
     }
     else if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
@@ -2814,32 +2810,6 @@
         return;
     }
 
-    type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
-    subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
-
-    /* Get pAdapter from Destination mac address of the frame */
-    if ((type == SIR_MAC_MGMT_FRAME) &&
-        (subType != SIR_MAC_MGMT_PROBE_REQ) &&
-        (nFrameLength > WLAN_HDD_80211_FRM_DA_OFFSET + VOS_MAC_ADDR_SIZE) &&
-        !vos_is_macaddr_broadcast(
-         (v_MACADDR_t *)&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]))
-    {
-         pAdapter = hdd_get_adapter_by_macaddr( WLAN_HDD_GET_CTX(pAdapter),
-                            &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]);
-         if (NULL == pAdapter)
-         {
-             /* Under assumtion that we don't receive any action frame
-              * with BCST as destination we dropping action frame
-              */
-             hddLog(VOS_TRACE_LEVEL_FATAL,"pAdapter for action frame is NULL Macaddr = "
-                               MAC_ADDRESS_STR ,
-                               MAC_ADDR_ARRAY(&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]));
-             hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Frame Type = %d Frame Length = %d"
-                              " subType = %d",__func__,frameType,nFrameLength,subType);
-             return;
-         }
-    }
-
 
     if (NULL == pAdapter->dev)
     {
diff --git a/CORE/HDD/src/wlan_hdd_tdls.c b/CORE/HDD/src/wlan_hdd_tdls.c
index 13da124..b804968 100644
--- a/CORE/HDD/src/wlan_hdd_tdls.c
+++ b/CORE/HDD/src/wlan_hdd_tdls.c
@@ -1382,6 +1382,8 @@
 
     vos_mem_zero(peer, sizeof(hddTdlsPeer_t));
     vos_mem_copy(peer->peerMac, mac, sizeof(peer->peerMac));
+    if (pHddCtx->cfg_ini->fTDLSExternalControl)
+        peer->isForcedPeer = 1;
     peer->pHddTdlsCtx = pHddTdlsCtx;
     list_add_tail(&peer->node, head);
 
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index 1bb4e18..82d7336 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -2367,6 +2367,8 @@
                 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2));
                 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
                 pWextState->roamProfile.nRSNReqIELength = eLen + 2;
+                wlan_hdd_mask_unsupported_rsn_caps(pWextState->WPARSNIE + 2,
+                                                   eLen);
               break;
 
          default:
diff --git a/CORE/HDD/src/wlan_hdd_wmm.c b/CORE/HDD/src/wlan_hdd_wmm.c
index 9c2ad34..62cc55a 100644
--- a/CORE/HDD/src/wlan_hdd_wmm.c
+++ b/CORE/HDD/src/wlan_hdd_wmm.c
@@ -1718,6 +1718,8 @@
    hddWmmDscpToUpMap[24] = SME_QOS_WMM_UP_EE;
    hddWmmDscpToUpMap[32] = SME_QOS_WMM_UP_CL;
    hddWmmDscpToUpMap[40] = SME_QOS_WMM_UP_VI;
+/* Special case for Expedited Forwarding (DSCP 46) in default mapping */
+   hddWmmDscpToUpMap[46] = SME_QOS_WMM_UP_VO;
    hddWmmDscpToUpMap[48] = SME_QOS_WMM_UP_VO;
    hddWmmDscpToUpMap[56] = SME_QOS_WMM_UP_NC;
    return VOS_STATUS_SUCCESS;
@@ -2191,7 +2193,7 @@
 }
 
 /**============================================================================
-  @brief hdd_hostapd_select_quueue() - Function which will classify the packet
+  @brief __hdd_hostapd_select_queue() - Function which will classify the packet
          according to linux qdisc expectation.
 
 
@@ -2200,14 +2202,8 @@
 
   @return         : Qdisc queue index
   ===========================================================================*/
-v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
-                                 , void *accel_priv
-#endif
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
-                                 , select_queue_fallback_t fallbac
-#endif
-)
+uint16_t __hdd_hostapd_select_queue(struct net_device *dev,
+				    struct sk_buff *skb)
 {
    WLANTL_ACEnumType ac;
    sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
@@ -2283,6 +2279,34 @@
    return queueIndex;
 }
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
+uint16_t hdd_hostapd_select_queue(struct net_device *dev, struct sk_buff *skb,
+				  struct net_device *sb_dev,
+				  select_queue_fallback_t fallbac)
+{
+	return __hdd_hostapd_select_queue(dev, skb);
+}
+
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+uint16_t hdd_hostapd_select_queue(struct net_device *dev, struct sk_buff *skb,
+				  void *accel_priv,
+				  select_queue_fallback_t fallbac)
+{
+	return __hdd_hostapd_select_queue(dev, skb);
+}
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
+uint16_t hdd_hostapd_select_queue(struct net_device *dev, struct sk_buff *skb,
+				  void *accel_priv)
+{
+	return __hdd_hostapd_select_queue(dev, skb);
+}
+#else
+uint16_t hdd_hostapd_select_queue(struct net_device *dev, struct sk_buff *skb)
+{
+	return __hdd_hostapd_select_queue(dev, skb);
+}
+#endif
+
 /**============================================================================
   @brief hdd_wmm_select_quueue() - Function which will classify the packet
          according to linux qdisc expectation.
diff --git a/CORE/MAC/inc/wniCfg.h b/CORE/MAC/inc/wniCfg.h
index 0666539..527035c 100644
--- a/CORE/MAC/inc/wniCfg.h
+++ b/CORE/MAC/inc/wniCfg.h
@@ -1199,7 +1199,7 @@
 
 #define WNI_CFG_VHT_TXSTBC_STAMIN    0
 #define WNI_CFG_VHT_TXSTBC_STAMAX    1
-#define WNI_CFG_VHT_TXSTBC_STADEF    0
+#define WNI_CFG_VHT_TXSTBC_STADEF    1
 
 #define WNI_CFG_VHT_RXSTBC_STAMIN    0
 #define WNI_CFG_VHT_RXSTBC_STAMAX    1
diff --git a/CORE/MAC/src/pe/lim/limAssocUtils.c b/CORE/MAC/src/pe/lim/limAssocUtils.c
index 4f47243..02cf86f 100644
--- a/CORE/MAC/src/pe/lim/limAssocUtils.c
+++ b/CORE/MAC/src/pe/lim/limAssocUtils.c
@@ -3047,7 +3047,8 @@
         {
             pAddStaParams->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD, psessionEntry);
             pAddStaParams->txChannelWidthSet =
-                  pMac->roam.configParam.channelBondingMode5GHz;
+                  pMac->roam.configParam.channelBondingMode5GHz ^
+                  pMac->roam.configParam.channelBondingMode24GHz;
             // pAddStaParams->txChannelWidthSet = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry);
             pAddStaParams->mimoPS             = limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE, psessionEntry );
             pAddStaParams->rifsMode           = limGetHTCapability( pMac, eHT_RIFS_MODE, psessionEntry );
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index 0972fa6..f04fd4f 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -674,10 +674,10 @@
         pNext = NULL;
     }
    
+    limLog( pMac, LOG1,
+                FL("rcvd frame match with registered frame params match %d fc.type %d fc.subType %d"), match, fc.type, fc.subType);
     if (match)
     {
-        limLog( pMac, LOG1, 
-                FL("rcvd frame match with registered frame params"));
 
         /* Indicate this to SME */
         limSendSmeMgmtFrameInd( pMac, pLimMgmtRegistration->sessionId,
diff --git a/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c b/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c
index ef7ec01..86bf0c4 100644
--- a/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c
+++ b/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c
@@ -299,7 +299,7 @@
    type = wnl->nlh.nlmsg_type;
 
    if (wnl->nlh.nlmsg_len < (sizeof(struct nlmsghdr) +
-       sizeof(int) + sizeof(tAniHdr) + wnl->wmsg.length))
+       sizeof(int) + sizeof(tAniHdr) + be16_to_cpu(wnl->wmsg.length)))
 	   return -EINVAL;
 
    switch (type) {
diff --git a/CORE/TL/src/wlan_qct_tl_ba.c b/CORE/TL/src/wlan_qct_tl_ba.c
index db290d4..e8c7565 100644
--- a/CORE/TL/src/wlan_qct_tl_ba.c
+++ b/CORE/TL/src/wlan_qct_tl_ba.c
@@ -845,6 +845,7 @@
   static v_U32_t  numAMSDUFrames;
   vos_pkt_t*      vosDataBuff;
   uint8_t llc_hdr[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+  uint8_t broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
   /*------------------------------------------------------------------------
@@ -969,10 +970,13 @@
   }
 
   /**
-   * Set drop_amsdu flag and drop AMSDU subframe if AMSDU subframe DA
-   * is equal to LLC header
+   * Set drop_amsdu flag and drop AMSDU subframe if
+   * 1. AMSDU subframe header's DA is equal to LLC header or
+   * 2. AMPDU header's DA is a broadcast address
    */
-   if (vos_mem_compare2(MPDUHeaderAMSDUHeader + ucMPDUHLen, llc_hdr, 6) == 0) {
+   if ((vos_mem_compare2(MPDUHeaderAMSDUHeader + ucMPDUHLen,
+        llc_hdr, 6) == 0) ||
+       (vos_mem_compare2(MPDUHeaderAMSDUHeader + 4, broadcast_addr, 6) == 0)) {
       pClientSTA->drop_amsdu = true;
       vos_pkt_return_packet(vosDataBuff);
       *ppVosDataBuff = NULL;
diff --git a/CORE/VOSS/inc/i_vos_lock.h b/CORE/VOSS/inc/i_vos_lock.h
index cc213f7..804733c 100644
--- a/CORE/VOSS/inc/i_vos_lock.h
+++ b/CORE/VOSS/inc/i_vos_lock.h
@@ -77,8 +77,17 @@
 typedef spinlock_t vos_spin_lock_t;
 
 #if defined(WLAN_OPEN_SOURCE)
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
-typedef struct wakeup_source vos_wake_lock_t;
+/**
+ * typedef struct - vos_wake_lock_t
+ * @lock: this lock needs to be used in kernel version < 4.19
+ * @priv: this lock pointer needs to be used in kernel version >= 4.19
+ */
+typedef struct vos_wake_lock {
+	struct wakeup_source lock;
+	struct wakeup_source *priv;
+} vos_wake_lock_t;
 #else
 typedef struct wake_lock vos_wake_lock_t;
 #endif
diff --git a/CORE/VOSS/src/vos_lock.c b/CORE/VOSS/src/vos_lock.c
index aaa9e50..c8b3bbf 100644
--- a/CORE/VOSS/src/vos_lock.c
+++ b/CORE/VOSS/src/vos_lock.c
@@ -482,11 +482,27 @@
    return VOS_STATUS_SUCCESS;
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && \
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 110)) || \
+	defined(WAKEUP_SOURCE_DEV)
+VOS_STATUS vos_wake_lock_init(vos_wake_lock_t *lock, const char *name)
+{
+	vos_mem_zero(lock, sizeof(*lock));
+	lock->priv = wakeup_source_register(lock->lock.dev, name);
+	if (!(lock->priv)) {
+		VOS_BUG(0);
+		return VOS_STATUS_E_FAILURE;
+	}
+
+	lock->lock = *(lock->priv);
+
+	return VOS_STATUS_SUCCESS;
+}
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && \
 	defined(WLAN_OPEN_SOURCE)
 VOS_STATUS vos_wake_lock_init(vos_wake_lock_t *pLock, const char *name)
 {
-	wakeup_source_init(pLock, name);
+	wakeup_source_init(&pLock->lock, name);
+	pLock->priv = &(pLock->lock);
 	return VOS_STATUS_SUCCESS;
 }
 #else
@@ -513,8 +529,8 @@
 	defined(WLAN_OPEN_SOURCE)
 static const char *vos_wake_lock_name(vos_wake_lock_t *pLock)
 {
-	if (pLock->name)
-		return pLock->name;
+	if (pLock)
+		return pLock->lock.name;
 
 	return "UNNAMED_WAKELOCK";
 }
@@ -548,7 +564,7 @@
 	vos_log_wlock_diag(reason, vos_wake_lock_name(pLock),
 			   WIFI_POWER_EVENT_DEFAULT_WAKELOCK_TIMEOUT,
 			   WIFI_POWER_EVENT_WAKELOCK_TAKEN);
-	__pm_stay_awake(pLock);
+	__pm_stay_awake(pLock->priv);
 	return VOS_STATUS_SUCCESS;
 }
 #else
@@ -586,7 +602,7 @@
 	 * Wakelock for Rx is frequent.
 	 * It is reported only during active debug
 	 */
-	__pm_wakeup_event(pLock, msec);
+	__pm_wakeup_event(pLock->priv, msec);
 	return VOS_STATUS_SUCCESS;
 }
 #else
@@ -630,7 +646,7 @@
 	vos_log_wlock_diag(reason, vos_wake_lock_name(pLock),
 			   WIFI_POWER_EVENT_DEFAULT_WAKELOCK_TIMEOUT,
 			   WIFI_POWER_EVENT_WAKELOCK_RELEASED);
-	__pm_relax(pLock);
+	__pm_relax(pLock->priv);
 	return VOS_STATUS_SUCCESS;
 }
 #else
@@ -660,11 +676,19 @@
 }
 #endif
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && \
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 110)) || \
+	defined(WAKEUP_SOURCE_DEV)
+VOS_STATUS vos_wake_lock_destroy(vos_wake_lock_t *lock)
+{
+	wakeup_source_unregister(lock->priv);
+	return VOS_STATUS_SUCCESS;
+}
+
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && \
 	defined(WLAN_OPEN_SOURCE)
 VOS_STATUS vos_wake_lock_destroy(vos_wake_lock_t *pLock)
 {
-	wakeup_source_trash(pLock);
+	wakeup_source_trash(pLock->priv);
 	return VOS_STATUS_SUCCESS;
 }
 #else
@@ -691,7 +715,7 @@
 	defined(WLAN_OPEN_SOURCE)
 bool vos_wake_lock_active(vos_wake_lock_t *lock)
 {
-	return lock->active;
+	return lock->priv->active;
 }
 #else
 bool vos_wake_lock_active(vos_wake_lock_t *lock)
diff --git a/CORE/VOSS/src/vos_timer.c b/CORE/VOSS/src/vos_timer.c
index 8b6970d..324a5d2 100644
--- a/CORE/VOSS/src/vos_timer.c
+++ b/CORE/VOSS/src/vos_timer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, 2015-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2015-2021 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -110,9 +110,8 @@
 
   --------------------------------------------------------------------------*/
 
-static void vos_linux_timer_callback (unsigned long data)
+static void vos_linux_timer_callback(vos_timer_t *timer)
 {
-   vos_timer_t *timer = ( vos_timer_t *)data; 
    vos_msg_t msg;
    VOS_STATUS vStatus;
    unsigned long flags;
@@ -375,6 +374,47 @@
 }
 #endif
   
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
+static void vos_timer_shim(struct timer_list *vos_timer)
+{
+	vos_timer_platform_t *platformInfo_ptr = container_of(vos_timer,
+							vos_timer_platform_t,
+							Timer);
+
+	vos_timer_t *timer = container_of(platformInfo_ptr, vos_timer_t,
+						platformInfo);
+
+	vos_linux_timer_callback(timer);
+}
+
+static void vos_timer_setup(vos_timer_t *timer, bool deferrable)
+{
+	uint32_t flags = 0;
+
+	if (deferrable)
+		flags |= TIMER_DEFERRABLE;
+	timer_setup(&(timer->platformInfo.Timer), vos_timer_shim,
+		    flags);
+}
+#else
+static void vos_timer_shim(unsigned long data)
+{
+	vos_timer_t *timer = (vos_timer_t *)data;
+
+	vos_linux_timer_callback(timer);
+}
+
+static void vos_timer_setup(vos_timer_t *timer, bool deferrable)
+{
+	if (deferrable)
+		init_timer_deferrable(&timer->platformInfo.Timer);
+	else
+		init_timer(&timer->platformInfo.Timer);
+	timer->platformInfo.Timer.function = vos_timer_shim;
+	timer->platformInfo.Timer.data = (unsigned long)timer;
+}
+#endif
+
 /*--------------------------------------------------------------------------
   
   \brief vos_timer_init() - Initialize a vOSS timer.
@@ -484,12 +524,7 @@
     * with arguments passed or with default values
     */
    spin_lock_init(&timer->platformInfo.spinlock);
-   if(deferrable)
-     init_timer_deferrable(&(timer->platformInfo.Timer));
-   else
-     init_timer(&(timer->platformInfo.Timer));
-   timer->platformInfo.Timer.function = vos_linux_timer_callback;
-   timer->platformInfo.Timer.data = (unsigned long)timer;
+   vos_timer_setup(timer, deferrable);
    timer->callback = callback;
    timer->userData = userData;
    timer->type = timerType;
@@ -541,12 +576,7 @@
     * with arguments passed or with default values
     */
    spin_lock_init(&timer->platformInfo.spinlock);
-   if(deferrable)
-     init_timer_deferrable(&(timer->platformInfo.Timer));
-   else
-     init_timer(&(timer->platformInfo.Timer));
-   timer->platformInfo.Timer.function = vos_linux_timer_callback;
-   timer->platformInfo.Timer.data = (unsigned long)timer;
+   vos_timer_setup(timer, deferrable);
    timer->callback = callback;
    timer->userData = userData;
    timer->type = timerType;