From 25607a7bb85676bc0b150ff26acfdbc9895e89fe Mon Sep 17 00:00:00 2001 From: Gurumoorthi Gnanasambandhan Date: Mon, 7 Aug 2017 11:53:16 +0530 Subject: [PATCH] qcacmn: Handle MIC error indication from Hardware Handle MIC error reported by Hardware and pass the event to hostapd. Change-Id: I510808f1e714edab5d4ccc0a2e205988892ea162 --- dp/inc/cdp_txrx_ops.h | 3 ++ dp/wifi3.0/dp_rx.h | 1 + dp/wifi3.0/dp_rx_err.c | 88 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 6d3ac355afcc..034cce368352 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -627,6 +627,9 @@ struct ol_if_ops { 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); + /* TODO: Add any other control path calls required to OL_IF/WMA layer */ }; diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index b9d11d547738..d0e760fb3443 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -411,6 +411,7 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc, #endif uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t nbuf); + #define DP_RX_LIST_APPEND(head, tail, elem) \ do { \ if (!(head)) { \ diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index efe315a1ac78..610cdd4a9c54 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -598,6 +598,75 @@ fail: return rx_bufs_used; } +/** + * dp_rx_process_mic_error(): Function to pass mic error indication to umac + * @soc: DP SOC handle + * @rx_desc : pointer to the sw rx descriptor + * @head: pointer to head of rx descriptors to be added to free list + * @tail: pointer to tail of rx descriptors to be added to free list + * + * return: void + */ +static void +dp_rx_process_mic_error(struct dp_soc *soc, struct dp_rx_desc *rx_desc, + union dp_rx_desc_list_elem_t **head, + union dp_rx_desc_list_elem_t **tail) +{ + struct dp_vdev *vdev = NULL; + struct dp_pdev *pdev = NULL; + struct ol_if_ops *tops = NULL; + qdf_nbuf_t nbuf; + struct ieee80211_frame *wh; + uint8_t *rx_pkt_hdr; + uint8_t *rx_tlv_hdr; + uint8_t i; + + nbuf = rx_desc->nbuf; + qdf_nbuf_unmap_single(soc->osdev, nbuf, QDF_DMA_BIDIRECTIONAL); + rx_tlv_hdr = qdf_nbuf_data(nbuf); + + if (!hal_rx_msdu_end_first_msdu_get(rx_tlv_hdr)) + goto fail; + + rx_pkt_hdr = hal_rx_pkt_hdr_get(qdf_nbuf_data(nbuf)); + wh = (struct ieee80211_frame *)rx_pkt_hdr; + + for (i = 0; i < MAX_PDEV_CNT; i++) { + pdev = soc->pdev_list[i]; + if (!pdev) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "PDEV not found"); + continue; + } + + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + if (qdf_mem_cmp(wh->i_addr1, vdev->mac_addr.raw, + DP_MAC_ADDR_LEN) == 0) { + goto out; + } + } + } + + if (!vdev) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "VDEV not found"); + goto fail; + } + +out: + tops = pdev->soc->cdp_soc.ol_ops; + if (tops->rx_mic_error) + tops->rx_mic_error(pdev->osif_pdev, vdev->vdev_id, wh); + +fail: + qdf_nbuf_free(rx_desc->nbuf); + dp_rx_add_to_free_desc_list(&head[rx_desc->pool_id], + &tail[rx_desc->pool_id], rx_desc); + + return; +} + + /** * dp_rx_link_desc_return() - Return a MPDU link descriptor to HW * (WBM), following error handling @@ -949,6 +1018,20 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) quota); continue; + case HAL_RXDMA_ERR_TKIP_MIC: + dp_rx_process_mic_error(soc, + rx_desc, + &head[pool_id], + &tail[pool_id]); + rx_bufs_used[pool_id]++; + continue; + + case HAL_RXDMA_ERR_DECRYPT: + QDF_TRACE(QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_ERROR, + "Packet received with Decrypt error"); + break; + default: QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, @@ -1089,6 +1172,11 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, DP_STATS_INC(soc, rx.err.rxdma_error[rxdma_error_code], 1); + if (rxdma_error_code == HAL_RXDMA_ERR_DECRYPT) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "Packet received with Decrypt error"); + } + return rx_bufs_used; }