wlan: Add changes for auth in send mgmt path

propagation from qcacld-3.0 to prima

Add changes to support authentication in send mgmt path.
With these changes, supplicant/upper layer can send
authentication frame for station mode.

Change-Id: I6807f49acc9284e69c6362e07a583ff26f15edca
CRs-Fixed: 2531064
diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c
index 55e5e8b..3b1b38f 100644
--- a/CORE/HDD/src/wlan_hdd_p2p.c
+++ b/CORE/HDD/src/wlan_hdd_p2p.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1289,6 +1289,7 @@
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
     uint8_t home_ch = 0;
 #endif
+    eHalStatus hal_status;
 
     ENTER();
 
@@ -1313,6 +1314,18 @@
     hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d type: %d",
                             __func__, pAdapter->device_mode, type);
 
+    /* When frame to be transmitted is auth mgmt, then trigger
+     * sme_send_mgmt_tx to send auth frame.
+     */
+    if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
+        (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_AUTH)) {
+         hal_status = sme_send_mgmt_tx(WLAN_HDD_GET_HAL_CTX(pAdapter),
+                                       pAdapter->sessionId, buf, len);
+         if (HAL_STATUS_SUCCESS(hal_status))
+              return 0;
+         else
+              return -EINVAL;
+    }
 
     if ((type == SIR_MAC_MGMT_FRAME) &&
             (subType == SIR_MAC_MGMT_ACTION) &&
diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h
index 3314d7a..9408712 100644
--- a/CORE/MAC/inc/wniApi.h
+++ b/CORE/MAC/inc/wniApi.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 2016-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -402,6 +402,7 @@
     eWNI_SME_ECSA_CHAN_CHANGE_RSP,
     eWNI_SME_STA_DEL_BA_REQ,
     eWNI_SME_TRIGGER_SAE,
+    eWNI_SME_SEND_MGMT_FRAME_TX,
     eWNI_SME_MSG_TYPES_END
 };
 
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index e834dc8..4057e37 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -266,6 +266,20 @@
     tANI_U32 data[1];
 } tSirMbMsgP2p, *tpSirMbMsgP2p;
 
+/**
+ * struct sir_mgmt_msg - Structure used to send auth frame from CSR to LIM
+ * @type: Message type
+ * @msg_len: Message length
+ * @session_id: session id
+ * @data: Pointer to data tobe transmitted
+ */
+struct sir_mgmt_msg {
+    uint16_t type;
+    uint16_t msg_len;
+    uint8_t session_id;
+    uint8_t *data;
+};
+
 /// Message queue definitions
 //  msgtype(2bytes) reserved(2bytes) bodyptr(4bytes) bodyval(4bytes)
 //  NOTE tSirMsgQ should be always multiples of WORD(4Bytes)
diff --git a/CORE/MAC/src/pe/include/limSession.h b/CORE/MAC/src/pe/include/limSession.h
index 75ff4f4..16b6bcc 100644
--- a/CORE/MAC/src/pe/include/limSession.h
+++ b/CORE/MAC/src/pe/include/limSession.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -480,9 +480,19 @@
 
 --------------------------------------------------------------------------*/
  tpPESession peFindSessionByStaId(tpAniSirGlobal pMac,  tANI_U8  staid,    tANI_U8* sessionId);
- 
 
-
+/**
+ * pe_find_session_by_sme_session_id() - looks up the PE session for given sme
+ * session id
+ * @mac_ctx: pointer to global adapter context
+ * @sme_session_id: sme session id
+ *
+ * Looks up the PE session for given sme session id
+ *
+ * Return: pe session entry for given sme session if found else NULL
+ */
+tpPESession pe_find_session_by_sme_session_id(tpAniSirGlobal mac_ctx,
+                                              uint8_t sme_session_id);
 
 
 /*--------------------------------------------------------------------------
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index 6c8e41b..6659903 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1769,6 +1769,12 @@
             limMsg->bodyptr = NULL;
             break;
 
+        case eWNI_SME_SEND_MGMT_FRAME_TX:
+            lim_send_mgmt_frame_tx(pMac, limMsg);
+            vos_mem_free(limMsg->bodyptr);
+            limMsg->bodyptr = NULL;
+            break;
+
 #ifdef WLAN_FEATURE_RMC
         case eWNI_SME_ENABLE_RMC_REQ:
         case eWNI_SME_DISABLE_RMC_REQ:
diff --git a/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/CORE/MAC/src/pe/lim/limSendManagementFrames.c
index c47fa71..c776cfb 100644
--- a/CORE/MAC/src/pe/lim/limSendManagementFrames.c
+++ b/CORE/MAC/src/pe/lim/limSendManagementFrames.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -7333,3 +7333,77 @@
 } // End limSendRMCActionFrame.
 
 #endif /* WLAN_FEATURE_RMC */
+
+/**
+ * lim_tx_mgmt_frame() - Transmits Auth mgmt frame
+ * @mac_ctx Pointer to Global MAC structure
+ * @mb_msg: Received message info
+ * @msg_len: Received message length
+ * @packet: Packet to be transmitted
+ * @frame: Received frame
+ *
+ * Return: None
+ */
+static void lim_tx_mgmt_frame(tpAniSirGlobal mac_ctx,
+                              struct sir_mgmt_msg *mb_msg, uint32_t msg_len,
+                              void *packet, uint8_t *frame)
+{
+    tpSirMacFrameCtl fc = (tpSirMacFrameCtl)mb_msg->data;
+    eHalStatus hal_status;
+    uint8_t sme_session_id = 0;
+    tpPESession session;
+
+    sme_session_id = mb_msg->session_id;
+    session = pe_find_session_by_sme_session_id(mac_ctx, sme_session_id);
+    if (session == NULL) {
+            limLog(mac_ctx, LOGP,
+                   FL("session not found for given sme session"));
+            return;
+    }
+    MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_MGMT,
+           session->peSessionId, fc->subType));
+    mac_ctx->authAckStatus = LIM_AUTH_ACK_NOT_RCD;
+    hal_status =
+           halTxFrameWithTxComplete(mac_ctx, packet, (uint16_t)msg_len,
+                                    HAL_TXRX_FRM_802_11_MGMT,
+                                    ANI_TXDIR_TODS,
+                                    7, limTxComplete, frame,
+                                    limAuthTxCompleteCnf,
+                                    0, mac_ctx->lim.txBdToken);
+    MTRACE(vos_trace(VOS_MODULE_ID_PE, TRACE_CODE_TX_COMPLETE,
+           session->peSessionId, hal_status));
+    if (!HAL_STATUS_SUCCESS(hal_status)) {
+        limLog(mac_ctx, LOGP,
+               FL("*** Could not send Auth frame, retCode=%X ***"),
+               hal_status);
+        mac_ctx->authAckStatus = LIM_AUTH_ACK_RCD_FAILURE;
+        limDiagEventReport(mac_ctx, WLAN_PE_DIAG_AUTH_REQ_EVENT,
+                           session, eSIR_FAILURE, eSIR_FAILURE);
+        /* Pkt will be freed up by the callback */
+    }
+}
+
+void lim_send_mgmt_frame_tx(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
+{
+    struct sir_mgmt_msg *mb_msg = (struct sir_mgmt_msg *)msg->bodyptr;
+    uint32_t msg_len;
+    tpSirMacFrameCtl fc = (tpSirMacFrameCtl)mb_msg->data;
+    uint8_t sme_session_id;
+    eHalStatus halstatus;
+    uint8_t *frame;
+    void *packet;
+
+    msg_len = mb_msg->msg_len - sizeof(*mb_msg);
+    limLog(mac_ctx, LOG1, FL("sending fc->type: %d fc->subType: %d"),
+           fc->type, fc->subType);
+    sme_session_id = mb_msg->session_id;
+    halstatus = palPktAlloc(mac_ctx->hHdd, HAL_TXRX_FRM_802_11_MGMT,
+                            (uint16_t)msg_len, (void **)&frame,
+                            (void **)&packet);
+    if (!HAL_STATUS_SUCCESS(halstatus)) {
+        limLog(mac_ctx, LOGP, FL("call to bufAlloc failed for AUTH frame"));
+        return;
+    }
+    vos_mem_copy(frame, mb_msg->data, msg_len);
+    lim_tx_mgmt_frame(mac_ctx, mb_msg, msg_len, packet, frame);
+}
diff --git a/CORE/MAC/src/pe/lim/limSession.c b/CORE/MAC/src/pe/lim/limSession.c
index 23c53bd..667032d 100644
--- a/CORE/MAC/src/pe/lim/limSession.c
+++ b/CORE/MAC/src/pe/lim/limSession.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, 2016-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -276,6 +276,22 @@
     return NULL;
 }
 
+tpPESession pe_find_session_by_sme_session_id(tpAniSirGlobal mac_ctx,
+                                              tANI_U8 sme_session_id)
+{
+   uint8_t i;
+
+   for (i = 0; i < mac_ctx->lim.maxBssId; i++) {
+       if ((mac_ctx->lim.gpSession[i].valid) &&
+           (mac_ctx->lim.gpSession[i].smeSessionId == sme_session_id))
+           return &mac_ctx->lim.gpSession[i];
+   }
+   limLog(mac_ctx, LOG4, FL("Session lookup fails for smeSessionID: %d"),
+          sme_session_id);
+
+   return NULL;
+}
+
 /*--------------------------------------------------------------------------
   \brief peFindSessionBySessionId() - looks up the PE session given the session ID.
 
diff --git a/CORE/MAC/src/pe/lim/limTypes.h b/CORE/MAC/src/pe/lim/limTypes.h
index 6d0ca49..aaffe0c 100644
--- a/CORE/MAC/src/pe/lim/limTypes.h
+++ b/CORE/MAC/src/pe/lim/limTypes.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1142,6 +1142,14 @@
 void lim_send_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
      uint16_t new_channel, tpPESession session_entry);
 
+/**
+ * lim_send_mgmt_frame_tx() - Sends mgmt frame
+ * @mac_ctx Pointer to Global MAC structure
+ * @msg: Received message info
+ *
+ * Return: None
+ */
+void lim_send_mgmt_frame_tx(tpAniSirGlobal mac_ctx, tpSirMsgQ msg);
 
 #endif /* __LIM_TYPES_H */
 
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 51c9425..1ed8abd 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -4115,4 +4115,16 @@
  */
 VOS_STATUS sme_process_msg_callback(tHalHandle hal, vos_msg_t *msg);
 
+/**
+ * sme_send_mgmt_tx() - Sends mgmt frame from CSR to LIM
+ * @hal: The handle returned by mac_open
+ * @session_id: session id
+ * @buf: pointer to frame
+ * @len: frame length
+ *
+ * Return: eHalStatus
+ */
+eHalStatus sme_send_mgmt_tx(tHalHandle hal, uint8_t session_id,
+                                const uint8_t *buf, uint32_t len);
+
 #endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/inc/sme_Trace.h b/CORE/SME/inc/sme_Trace.h
index 77ff1d6..9fd4495 100644
--- a/CORE/SME/inc/sme_Trace.h
+++ b/CORE/SME/inc/sme_Trace.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -146,6 +146,7 @@
     TRACE_CODE_SME_RX_HDD_LPHB_CONFIG_REQ,
 #endif /* FEATURE_WLAN_LPHB */
     TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE,
+    TRACE_CODE_SME_RX_HDD_SEND_MGMT_TX,
     TRACE_CODE_SME_TX_HDD_CAP_TSF_REQ,
     TRACE_CODE_SME_TX_HDD_GET_TSF_REQ,
     TRACE_CODE_SME_DEL_STA_BA_SESSION_REQ,
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 7b19327..f7d81d4 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -15387,3 +15387,63 @@
 
          return dot11fUnpackIeRSN(mac_ctx, buf, buf_len, rsn_ie);
 }
+
+/**
+ * sme_prepare_mgmt_tx() - Prepares mgmt frame
+ * @hal: The handle returned by mac_open
+ * @session_id: session id
+ * @buf: pointer to frame
+ * @len: frame length
+ *
+ * Return: eHalStatus
+ */
+static eHalStatus sme_prepare_mgmt_tx(tHalHandle hal, uint8_t session_id,
+                                      const uint8_t *buf, uint32_t len)
+{
+    eHalStatus status = eHAL_STATUS_SUCCESS;
+    VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
+    vos_msg_t vos_message;
+    struct sir_mgmt_msg *msg;
+    uint16_t msg_len;
+
+    VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
+              ("prepares auth frame"));
+
+    msg_len = sizeof(*msg) + len;
+    msg = vos_mem_malloc(msg_len);
+    if (msg == NULL) {
+        status = eHAL_STATUS_FAILED_ALLOC;
+    } else {
+        msg->type = eWNI_SME_SEND_MGMT_FRAME_TX;
+        msg->msg_len = msg_len;
+        msg->session_id = session_id;
+        msg->data = (uint8_t *)msg + sizeof(*msg);
+        vos_mem_copy(msg->data, buf, len);
+        vos_message.bodyptr = msg;
+        vos_message.type =  eWNI_SME_SEND_MGMT_FRAME_TX;
+        vos_status = vos_mq_post_message(VOS_MQ_ID_PE, &vos_message);
+        if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
+            vos_mem_free(msg);
+            status = eHAL_STATUS_FAILURE;
+        }
+    }
+    return status;
+}
+
+eHalStatus sme_send_mgmt_tx(tHalHandle hal, uint8_t session_id,
+                            const uint8_t *buf, uint32_t len)
+{
+    eHalStatus status = eHAL_STATUS_SUCCESS;
+    tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+    MTRACE(vos_trace(VOS_MODULE_ID_SME,
+           TRACE_CODE_SME_RX_HDD_SEND_MGMT_TX, session_id, 0));
+
+    status = sme_AcquireGlobalLock(&mac->sme);
+    if (HAL_STATUS_SUCCESS(status)) {
+        status = sme_prepare_mgmt_tx(hal, session_id, buf, len);
+        sme_ReleaseGlobalLock(&mac->sme);
+    }
+
+    return status;
+}
diff --git a/CORE/SYS/legacy/src/utils/src/macTrace.c b/CORE/SYS/legacy/src/utils/src/macTrace.c
index ba58a58..69b2a52 100644
--- a/CORE/SYS/legacy/src/utils/src/macTrace.c
+++ b/CORE/SYS/legacy/src/utils/src/macTrace.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -587,6 +587,7 @@
         CASE_RETURN_STRING(eWNI_SME_ECSA_CHAN_CHANGE_REQ);
         CASE_RETURN_STRING(eWNI_SME_ECSA_CHAN_CHANGE_RSP);
         CASE_RETURN_STRING(eWNI_SME_TRIGGER_SAE);
+        CASE_RETURN_STRING(eWNI_SME_SEND_MGMT_FRAME_TX);
         default:
             return( (tANI_U8*)"UNKNOWN" );
             break;