Эх сурвалжийг харах

qcacld-3.0: Handle MIC Error in Chatter Mode

qcacld-2.0 to qcacld-3.0 propagation

Add support to handle an error indicated by the fw in offload mode.
In this case - MIC error type.

Change-Id: I53363bdbaafad7fab0a6e067a43892a3066abbb6
CRs-Fixed: 791274
Dhanashri Atre 9 жил өмнө
parent
commit
1f0cbe43e3

+ 53 - 2
core/dp/htt/htt_t2h.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -35,7 +35,7 @@
  *      based on the HTT message type.
  *  2.  functions that provide the info elements from specific HTT messages.
  */
-
+#include <wma.h>
 #include <htc_api.h>            /* HTC_PACKET */
 #include <htt.h>                /* HTT_T2H_MSG_TYPE, etc. */
 #include <cdf_nbuf.h>           /* cdf_nbuf_t */
@@ -49,6 +49,8 @@
 #include <wdi_event.h>
 #include <ol_htt_tx_api.h>
 #include <ol_txrx_types.h>
+#include <ol_txrx_peer_find.h>
+
 /*--- target->host HTT message dispatch function ----------------------------*/
 
 #ifndef DEBUG_CREDIT
@@ -418,6 +420,55 @@ void htt_t2h_lp_msg_handler(void *context, cdf_nbuf_t htt_t2h_msg)
 		break;
 	}
 
+	case HTT_T2H_MSG_TYPE_RX_OFLD_PKT_ERR:
+	{
+		switch (HTT_RX_OFLD_PKT_ERR_MSG_SUB_TYPE_GET(*msg_word)) {
+		case HTT_RX_OFLD_PKT_ERR_TYPE_MIC_ERR:
+		{
+			struct ol_error_info err_info;
+			struct ol_txrx_vdev_t *vdev;
+			struct ol_txrx_peer_t *peer;
+			uint16_t peer_id =
+				 HTT_RX_OFLD_PKT_ERR_MIC_ERR_PEER_ID_GET
+				(*(msg_word + 1));
+
+			peer = ol_txrx_peer_find_by_id(pdev->txrx_pdev,
+				 peer_id);
+			if (!peer) {
+				cdf_print("%s: invalid peer id %d\n",
+					 __func__, peer_id);
+				cdf_assert(0);
+				break;
+			}
+			vdev = peer->vdev;
+			err_info.u.mic_err.vdev_id = vdev->vdev_id;
+			err_info.u.mic_err.key_id =
+				HTT_RX_OFLD_PKT_ERR_MIC_ERR_KEYID_GET
+				(*(msg_word + 1));
+			cdf_mem_copy(err_info.u.mic_err.da,
+				 (uint8_t *)(msg_word + 2),
+				 OL_TXRX_MAC_ADDR_LEN);
+			cdf_mem_copy(err_info.u.mic_err.sa,
+				 (uint8_t *)(msg_word + 4),
+				 OL_TXRX_MAC_ADDR_LEN);
+			cdf_mem_copy(&err_info.u.mic_err.pn,
+				 (uint8_t *)(msg_word + 6), 6);
+			cdf_mem_copy(err_info.u.mic_err.ta,
+				 peer->mac_addr.raw, OL_TXRX_MAC_ADDR_LEN);
+
+			wma_indicate_err(OL_RX_ERR_TKIP_MIC, &err_info);
+			break;
+		}
+		default:
+		{
+			cdf_print("%s: unhandled error type %d\n",
+			 __func__,
+			 HTT_RX_OFLD_PKT_ERR_MSG_SUB_TYPE_GET(*msg_word));
+		break;
+		}
+		}
+	}
+
 	default:
 		break;
 	};

+ 2 - 19
core/dp/txrx/ol_ctrl_txrx_api.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -38,25 +38,9 @@
 
 #include <ol_ctrl_api.h>            /* ol_vdev_handle */
 #include <ol_txrx_api.h>            /* ol_txrx_peer_handle, etc. */
+#include <ol_txrx_types.h>          /* OL_TXRX_MAC_ADDR_LEN */
 #include <cds_ieee80211_common.h>   /* ieee80211_frame */
 
-enum ol_rx_err_type {
-	OL_RX_ERR_DEFRAG_MIC,
-	OL_RX_ERR_PN,
-	OL_RX_ERR_UNKNOWN_PEER,
-	OL_RX_ERR_MALFORMED,
-	OL_RX_ERR_TKIP_MIC,
-	OL_RX_ERR_DECRYPT,
-	OL_RX_ERR_MPDU_LENGTH,
-	OL_RX_ERR_ENCRYPT_REQUIRED,
-	OL_RX_ERR_DUP,
-	OL_RX_ERR_UNKNOWN,
-	OL_RX_ERR_FCS,
-	OL_RX_ERR_PRIVACY,
-	OL_RX_ERR_NONE_FRAG,
-	OL_RX_ERR_NONE = 0xFF
-};
-
 #ifdef SUPPORT_HOST_STATISTICS
 /** * @brief Update tx statistics
  * @details
@@ -186,5 +170,4 @@ void ol_tx_paused_peer_data(ol_peer_handle peer, int has_tx_data);
 
 void ol_txrx_set_peer_authorized_event(struct ol_txrx_vdev_t *vdev);
 
-
 #endif /* _OL_CTRL_TXRX_API__H_ */

+ 47 - 4
core/dp/txrx/ol_txrx_types.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -47,9 +47,6 @@
 #include "ol_txrx_htt_api.h"
 #include "ol_htt_tx_api.h"
 #include "ol_htt_rx_api.h"
-#include <ol_ctrl_txrx_api.h>
-#include <ol_txrx_ctrl_api.h>
-
 
 /*
  * The target may allocate multiple IDs for a peer.
@@ -1008,4 +1005,50 @@ struct ol_txrx_peer_t {
 	uint16_t last_pkt_center_freq;
 };
 
+enum ol_rx_err_type {
+	OL_RX_ERR_DEFRAG_MIC,
+	OL_RX_ERR_PN,
+	OL_RX_ERR_UNKNOWN_PEER,
+	OL_RX_ERR_MALFORMED,
+	OL_RX_ERR_TKIP_MIC,
+	OL_RX_ERR_DECRYPT,
+	OL_RX_ERR_MPDU_LENGTH,
+	OL_RX_ERR_ENCRYPT_REQUIRED,
+	OL_RX_ERR_DUP,
+	OL_RX_ERR_UNKNOWN,
+	OL_RX_ERR_FCS,
+	OL_RX_ERR_PRIVACY,
+	OL_RX_ERR_NONE_FRAG,
+	OL_RX_ERR_NONE = 0xFF
+};
+
+/**
+ * ol_mic_error_info - carries the information associated with
+ * a MIC error
+ * @vdev_id: virtual device ID
+ * @key_id: Key ID
+ * @pn: packet number
+ * @sa: source address
+ * @da: destination address
+ * @ta: transmitter address
+ */
+struct ol_mic_error_info {
+	uint8_t vdev_id;
+	uint32_t key_id;
+	uint64_t pn;
+	uint8_t sa[OL_TXRX_MAC_ADDR_LEN];
+	uint8_t da[OL_TXRX_MAC_ADDR_LEN];
+	uint8_t ta[OL_TXRX_MAC_ADDR_LEN];
+};
+
+/**
+ * ol_error_info - carries the information associated with an
+ * error indicated by the firmware
+ * @mic_err: MIC error information
+ */
+struct ol_error_info {
+	union {
+		struct ol_mic_error_info mic_err;
+	} u;
+};
 #endif /* _OL_TXRX_TYPES__H_ */

+ 3 - 0
core/wma/inc/wma.h

@@ -2050,4 +2050,7 @@ static inline CDF_STATUS wma_lro_config_cmd(tp_wma_handle wma_handle,
 	return CDF_STATUS_SUCCESS;
 }
 #endif
+void
+wma_indicate_err(enum ol_rx_err_type err_type,
+	 struct ol_error_info *err_info);
 #endif

+ 83 - 0
core/wma/src/wma_data.c

@@ -3077,3 +3077,86 @@ CDF_STATUS wma_lro_config_cmd(tp_wma_handle wma_handle,
 	return CDF_STATUS_SUCCESS;
 }
 #endif
+
+/**
+ * wma_indicate_err() - indicate an error to the protocol stack
+ * @err_type: error type
+ * @err_info: information associated with the error
+ *
+ * This function indicates an error encountered in the data path
+ * to the protocol stack
+ *
+ * Return: none
+ */
+void
+wma_indicate_err(
+	enum ol_rx_err_type err_type,
+	struct ol_error_info *err_info)
+{
+	switch (err_type) {
+	case OL_RX_ERR_TKIP_MIC:
+	{
+		tp_wma_handle wma = cds_get_context(CDF_MODULE_ID_WMA);
+		tpSirSmeMicFailureInd mic_err_ind;
+		cds_msg_t cds_msg;
+		uint8_t vdev_id;
+
+		if (NULL == wma) {
+			WMA_LOGE("%s: Failed to get wma context",
+				 __func__);
+			return;
+		}
+
+		mic_err_ind = cdf_mem_malloc(sizeof(*mic_err_ind));
+		if (!mic_err_ind) {
+			WMA_LOGE("%s: MIC indication mem alloc failed",
+					 __func__);
+			return;
+		}
+
+		cdf_mem_set((void *) mic_err_ind, 0,
+			 sizeof(*mic_err_ind));
+		mic_err_ind->messageType = eWNI_SME_MIC_FAILURE_IND;
+		mic_err_ind->length = sizeof(*mic_err_ind);
+		vdev_id = err_info->u.mic_err.vdev_id;
+		cdf_copy_macaddr(&mic_err_ind->bssId,
+		     (struct cdf_mac_addr *) &wma->interfaces[vdev_id].bssid);
+		WMA_LOGE("MIC error: BSSID:%02x:%02x:%02x:%02x:%02x:%02x\n",
+			 mic_err_ind->bssId.bytes[0], mic_err_ind->bssId.bytes[1],
+			 mic_err_ind->bssId.bytes[2], mic_err_ind->bssId.bytes[3],
+			 mic_err_ind->bssId.bytes[4], mic_err_ind->bssId.bytes[5]);
+		cdf_mem_copy(mic_err_ind->info.taMacAddr,
+			 (struct cdf_mac_addr *) err_info->u.mic_err.ta,
+			 sizeof(tSirMacAddr));
+		cdf_mem_copy(mic_err_ind->info.srcMacAddr,
+			 (struct cdf_mac_addr *) err_info->u.mic_err.sa,
+			 sizeof(tSirMacAddr));
+		cdf_mem_copy(mic_err_ind->info.dstMacAddr,
+			(struct cdf_mac_addr *) err_info->u.mic_err.da,
+			 sizeof(tSirMacAddr));
+		mic_err_ind->info.keyId = err_info->u.mic_err.key_id;
+		mic_err_ind->info.multicast =
+			 IEEE80211_IS_MULTICAST(err_info->u.mic_err.da);
+		cdf_mem_copy(mic_err_ind->info.TSC,
+			 (void *)&err_info->
+			 u.mic_err.pn, SIR_CIPHER_SEQ_CTR_SIZE);
+
+		cdf_mem_set(&cds_msg, sizeof(cds_msg_t), 0);
+		cds_msg.type = eWNI_SME_MIC_FAILURE_IND;
+		cds_msg.bodyptr = (void *) mic_err_ind;
+		if (CDF_STATUS_SUCCESS !=
+			cds_mq_post_message(CDS_MQ_ID_SME,
+				 (cds_msg_t *) &cds_msg)) {
+			WMA_LOGE("%s: mic failure ind post to SME failed",
+					 __func__);
+			cdf_mem_free((void *)mic_err_ind);
+		}
+		break;
+	}
+	default:
+	{
+		WMA_LOGE("%s: unhandled ol error type %d", __func__, err_type);
+		break;
+	}
+	}
+}