qcacmn: Add new API for registering rx mic error callback

Add new CDP API cdp_register_rx_mic_error_ind_handler to
register rx mic error callback. Also, define new structure
cdp_rx_mic_err_info for holding MIC error information.

Change-Id: I4d5d6426b1d5f04848afd48f6dbf51edba291a20
CRs-Fixed: 2488424
diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h
index e058566..cfd2109 100644
--- a/dp/inc/cdp_txrx_cmn_struct.h
+++ b/dp/inc/cdp_txrx_cmn_struct.h
@@ -382,6 +382,39 @@
 	uint16_t peer_id;
 };
 
+#define MIC_SEQ_CTR_SIZE 6
+
+enum cdp_rx_frame_type {
+	cdp_rx_frame_type_802_11,
+	cdp_rx_frame_type_802_3,
+};
+
+/**
+ *  struct cdp_rx_mic_err_info - rx mic error information
+ *  @frame_type: frame type - 0 - 802.11 frame
+ *                          - 1 - 802.3 frame
+ *  @data: 802.11 frame
+ *  @ta_mac_addr: transmitter mac address
+ *  @da_mac_addr: destination mac address
+ *  @tsc: sequence number
+ *  @key_id: Key ID
+ *  @multicast: flag for multicast
+ *  @vdev_id: vdev ID
+ *
+ *  This structure holds rx mic error information
+ *
+ */
+struct cdp_rx_mic_err_info {
+	uint8_t frame_type;
+	uint8_t *data;
+	struct qdf_mac_addr ta_mac_addr;
+	struct qdf_mac_addr da_mac_addr;
+	uint8_t tsc[MIC_SEQ_CTR_SIZE];
+	uint8_t key_id;
+	bool multicast;
+	uint16_t vdev_id;
+};
+
 /**
  * struct cdp_sec_type - security type information
  */
diff --git a/dp/inc/cdp_txrx_misc.h b/dp/inc/cdp_txrx_misc.h
index 56c7224..4b1e004 100644
--- a/dp/inc/cdp_txrx_misc.h
+++ b/dp/inc/cdp_txrx_misc.h
@@ -621,6 +621,31 @@
 		return soc->ops->misc_ops->unregister_pktdump_cb();
 }
 
+typedef void (*rx_mic_error_callback)(void *scn_handle,
+				struct cdp_rx_mic_err_info *info);
+
+/**
+ * cdp_register_rx_mic_error_ind_handler() - API to register mic error
+ *                                           indication handler
+ *
+ * @soc: soc handle
+ * @rx_mic_cb: rx mic error indication callback
+ *
+ * Return: void
+ */
+static inline void
+cdp_register_rx_mic_error_ind_handler(ol_txrx_soc_handle soc,
+				      rx_mic_error_callback rx_mic_cb)
+{
+	if (!soc || !soc->ol_ops) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
+			  "%s invalid instance", __func__);
+		return;
+	}
+
+	soc->ol_ops->rx_mic_error = rx_mic_cb;
+}
+
 /**
  * cdp_pdev_reset_driver_del_ack() - reset driver TCP delayed ack flag
  * @soc - data path soc handle
diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h
index a04702f..0cd0c6b 100644
--- a/dp/inc/cdp_txrx_ops.h
+++ b/dp/inc/cdp_txrx_ops.h
@@ -935,7 +935,7 @@
 	int (*get_dp_cfg_param)(void *ol_soc_handle, enum cdp_cfg_param_type param_num);
 
 	void (*rx_mic_error)(void *ol_soc_handle,
-			 uint16_t vdev_id, void *wh);
+			     struct cdp_rx_mic_err_info *info);
 	bool (*rx_frag_tkip_demic)(struct wlan_objmgr_peer *ctrl_peer,
 				   qdf_nbuf_t nbuf,
 				   uint16_t hdr_space);
diff --git a/dp/wifi3.0/dp_rx_defrag.c b/dp/wifi3.0/dp_rx_defrag.c
index 28033a4..2a31d97 100644
--- a/dp/wifi3.0/dp_rx_defrag.c
+++ b/dp/wifi3.0/dp_rx_defrag.c
@@ -868,13 +868,26 @@
 	int rx_desc_len = sizeof(struct rx_pkt_tlvs);
 	uint8_t *orig_hdr;
 	struct ieee80211_frame *wh;
+	struct cdp_rx_mic_err_info mic_failure_info;
 
 	orig_hdr = (uint8_t *)(qdf_nbuf_data(nbuf) + rx_desc_len);
 	wh = (struct ieee80211_frame *)orig_hdr;
 
+	qdf_copy_macaddr((struct qdf_mac_addr *)&mic_failure_info.da_mac_addr,
+			 (struct qdf_mac_addr *)&wh->i_addr1);
+	qdf_copy_macaddr((struct qdf_mac_addr *)&mic_failure_info.ta_mac_addr,
+			 (struct qdf_mac_addr *)&wh->i_addr2);
+	mic_failure_info.key_id = 0;
+	mic_failure_info.multicast =
+		IEEE80211_IS_MULTICAST(wh->i_addr1);
+	qdf_mem_zero(mic_failure_info.tsc, MIC_SEQ_CTR_SIZE);
+	mic_failure_info.frame_type = cdp_rx_frame_type_802_11;
+	mic_failure_info.data = (uint8_t *)wh;
+	mic_failure_info.vdev_id = vdev->vdev_id;
+
 	tops = pdev->soc->cdp_soc.ol_ops;
 	if (tops->rx_mic_error)
-		tops->rx_mic_error(pdev->ctrl_pdev, vdev->vdev_id, wh);
+		tops->rx_mic_error(pdev->ctrl_pdev, &mic_failure_info);
 }
 
 
diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c
index aeb13a5..15435f9 100644
--- a/dp/wifi3.0/dp_rx_err.c
+++ b/dp/wifi3.0/dp_rx_err.c
@@ -1027,6 +1027,7 @@
 	uint16_t rx_seq, fragno;
 	unsigned int tid;
 	QDF_STATUS status;
+	struct cdp_rx_mic_err_info mic_failure_info;
 
 	if (!hal_rx_msdu_end_first_msdu_get(rx_tlv_hdr))
 		return;
@@ -1067,9 +1068,21 @@
 			return;
 	}
 
+	qdf_copy_macaddr((struct qdf_mac_addr *)&mic_failure_info.da_mac_addr,
+			 (struct qdf_mac_addr *)&wh->i_addr1);
+	qdf_copy_macaddr((struct qdf_mac_addr *)&mic_failure_info.ta_mac_addr,
+			 (struct qdf_mac_addr *)&wh->i_addr2);
+	mic_failure_info.key_id = 0;
+	mic_failure_info.multicast =
+		IEEE80211_IS_MULTICAST(wh->i_addr1);
+	qdf_mem_zero(mic_failure_info.tsc, MIC_SEQ_CTR_SIZE);
+	mic_failure_info.frame_type = cdp_rx_frame_type_802_11;
+	mic_failure_info.data = (uint8_t *)wh;
+	mic_failure_info.vdev_id = vdev->vdev_id;
+
 	tops = pdev->soc->cdp_soc.ol_ops;
 	if (tops->rx_mic_error)
-		tops->rx_mic_error(pdev->ctrl_pdev, vdev->vdev_id, wh);
+		tops->rx_mic_error(pdev->ctrl_pdev, &mic_failure_info);
 
 fail:
 	qdf_nbuf_free(nbuf);