mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 15:11:48 -04:00
qcacmn: Add support for delivering unencrypted errors
In mesh mode, it is possible to receive unencrypted frames while security is enabled. Deliver such frames to OS stack. Change-Id: Id148b6ecc1432b419ae97c92f2340155f3d851bf CRs-Fixed: 2004658
This commit is contained in:
parent
403b085d0a
commit
eb8a92cedc
4 changed files with 134 additions and 22 deletions
|
|
@ -220,7 +220,7 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
|
|||
*/
|
||||
void
|
||||
dp_rx_deliver_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf_list,
|
||||
struct cdp_peer *peer)
|
||||
struct dp_peer *peer)
|
||||
{
|
||||
qdf_nbuf_t deliver_list_head = NULL;
|
||||
qdf_nbuf_t deliver_list_tail = NULL;
|
||||
|
|
@ -248,7 +248,7 @@ dp_rx_deliver_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf_list,
|
|||
}
|
||||
|
||||
vdev->osif_rsim_rx_decap(vdev->osif_vdev, &deliver_list_head,
|
||||
&deliver_list_tail, peer);
|
||||
&deliver_list_tail, (struct cdp_peer*) peer);
|
||||
|
||||
vdev->osif_rx(vdev->osif_vdev, deliver_list_head);
|
||||
}
|
||||
|
|
@ -1308,8 +1308,7 @@ done:
|
|||
|
||||
if (qdf_unlikely(vdev->rx_decap_type == htt_cmn_pkt_type_raw) ||
|
||||
(vdev->rx_decap_type == htt_cmn_pkt_type_native_wifi))
|
||||
dp_rx_deliver_raw(vdev, deliver_list_head,
|
||||
(struct cdp_peer *) peer);
|
||||
dp_rx_deliver_raw(vdev, deliver_list_head, peer);
|
||||
else if (qdf_likely(vdev->osif_rx) && deliver_list_head)
|
||||
vdev->osif_rx(vdev->osif_vdev, deliver_list_head);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ void dp_rx_desc_pool_free(struct dp_soc *soc,
|
|||
struct rx_desc_pool *rx_desc_pool);
|
||||
|
||||
void dp_rx_deliver_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf_list,
|
||||
struct cdp_peer *peer);
|
||||
struct dp_peer *peer);
|
||||
|
||||
/**
|
||||
* dp_rx_add_to_free_desc_list() - Adds to a local free descriptor list
|
||||
|
|
|
|||
|
|
@ -342,10 +342,7 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc,
|
|||
* Advance the packet start pointer by total size of
|
||||
* pre-header TLV's
|
||||
*/
|
||||
qdf_nbuf_pull_head(nbuf, RX_PKT_TLVS_LEN);
|
||||
|
||||
if (l2_hdr_offset)
|
||||
qdf_nbuf_pull_head(nbuf, l2_hdr_offset);
|
||||
qdf_nbuf_pull_head(nbuf, (l2_hdr_offset + RX_PKT_TLVS_LEN));
|
||||
|
||||
nbuf_data = qdf_nbuf_data(nbuf);
|
||||
for (count = 0; count < soc->mect_cnt; count++) {
|
||||
|
|
@ -393,7 +390,7 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc,
|
|||
|
||||
if (qdf_unlikely(vdev->rx_decap_type == htt_cmn_pkt_type_raw)) {
|
||||
qdf_nbuf_set_next(nbuf, NULL);
|
||||
dp_rx_deliver_raw(vdev, nbuf, (struct cdp_peer *) peer);
|
||||
dp_rx_deliver_raw(vdev, nbuf, peer);
|
||||
} else {
|
||||
if (qdf_unlikely(peer->bss_peer)) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||
|
|
@ -423,6 +420,115 @@ fail:
|
|||
return rx_bufs_used;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_rx_err_deliver() - Function to deliver error frames to OS
|
||||
*
|
||||
* @soc: core DP main context
|
||||
* @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
|
||||
* quota: upper limit of descriptors that can be reaped
|
||||
*
|
||||
* Return: uint32_t: No. of Rx buffers reaped
|
||||
*/
|
||||
static uint32_t
|
||||
dp_rx_err_deliver(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,
|
||||
uint32_t quota)
|
||||
{
|
||||
uint32_t rx_bufs_used = 0;
|
||||
uint32_t pkt_len, l2_hdr_offset;
|
||||
uint16_t msdu_len;
|
||||
qdf_nbuf_t nbuf;
|
||||
struct dp_vdev *vdev;
|
||||
uint16_t peer_id = 0xFFFF;
|
||||
struct dp_peer *peer = NULL;
|
||||
|
||||
rx_bufs_used++;
|
||||
|
||||
nbuf = rx_desc->nbuf;
|
||||
|
||||
qdf_nbuf_unmap_single(soc->osdev, nbuf,
|
||||
QDF_DMA_BIDIRECTIONAL);
|
||||
|
||||
rx_desc->rx_buf_start = qdf_nbuf_data(nbuf);
|
||||
|
||||
/*
|
||||
* Check if DMA completed -- msdu_done is the last bit
|
||||
* to be written
|
||||
*/
|
||||
if (!hal_rx_attn_msdu_done_get(rx_desc->rx_buf_start)) {
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
FL("MSDU DONE failure"));
|
||||
|
||||
hal_rx_dump_pkt_tlvs(rx_desc->rx_buf_start,
|
||||
QDF_TRACE_LEVEL_INFO);
|
||||
qdf_assert(0);
|
||||
}
|
||||
|
||||
peer_id = hal_rx_mpdu_start_sw_peer_id_get(rx_desc->rx_buf_start);
|
||||
peer = dp_peer_find_by_id(soc, peer_id);
|
||||
|
||||
if (!peer) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
FL("peer is NULL"));
|
||||
DP_STATS_INC_PKT(soc, rx.err.rx_invalid_peer, 1,
|
||||
qdf_nbuf_len(nbuf));
|
||||
/* Drop & free packet */
|
||||
qdf_nbuf_free(nbuf);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
vdev = peer->vdev;
|
||||
if (!vdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
FL("INVALID vdev %p OR osif_rx"), vdev);
|
||||
/* Drop & free packet */
|
||||
qdf_nbuf_free(nbuf);
|
||||
DP_STATS_INC(soc, rx.err.invalid_vdev, 1);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Drop & free packet if mesh mode not enabled */
|
||||
if (!vdev->mesh_vdev) {
|
||||
qdf_nbuf_free(nbuf);
|
||||
DP_STATS_INC(soc, rx.err.invalid_vdev, 1);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
l2_hdr_offset =
|
||||
hal_rx_msdu_end_l3_hdr_padding_get(rx_desc->rx_buf_start);
|
||||
|
||||
msdu_len =
|
||||
hal_rx_msdu_start_msdu_len_get(rx_desc->rx_buf_start);
|
||||
|
||||
pkt_len = msdu_len + l2_hdr_offset + RX_PKT_TLVS_LEN;
|
||||
|
||||
/* Set length in nbuf */
|
||||
qdf_nbuf_set_pktlen(nbuf, pkt_len);
|
||||
|
||||
qdf_nbuf_set_next(nbuf, NULL);
|
||||
|
||||
/*
|
||||
* Advance the packet start pointer by total size of
|
||||
* pre-header TLV's
|
||||
*/
|
||||
qdf_nbuf_pull_head(nbuf, (l2_hdr_offset + RX_PKT_TLVS_LEN));
|
||||
|
||||
if (qdf_unlikely(vdev->rx_decap_type == htt_cmn_pkt_type_raw)) {
|
||||
dp_rx_deliver_raw(vdev, nbuf, peer);
|
||||
} else {
|
||||
DP_STATS_INC(vdev->pdev, rx.to_stack.num, 1);
|
||||
vdev->osif_rx(vdev->osif_vdev, nbuf);
|
||||
}
|
||||
fail:
|
||||
dp_rx_add_to_free_desc_list(head, tail, rx_desc);
|
||||
|
||||
return rx_bufs_used;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_rx_link_desc_return() - Return a MPDU link descriptor to HW
|
||||
* (WBM), following error handling
|
||||
|
|
@ -432,7 +538,7 @@ fail:
|
|||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS
|
||||
static QDF_STATUS
|
||||
dp_rx_link_desc_return(struct dp_soc *soc, void *ring_desc)
|
||||
{
|
||||
void *buf_addr_info = HAL_RX_REO_BUF_ADDR_INFO_GET(ring_desc);
|
||||
|
|
@ -646,6 +752,7 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
|
|||
struct dp_pdev *dp_pdev;
|
||||
struct dp_srng *dp_rxdma_srng;
|
||||
struct rx_desc_pool *rx_desc_pool;
|
||||
uint8_t pool_id;
|
||||
|
||||
/* Debug -- Remove later */
|
||||
qdf_assert(soc && hal_ring);
|
||||
|
|
@ -702,6 +809,8 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
|
|||
continue;
|
||||
}
|
||||
|
||||
pool_id = rx_desc->pool_id;
|
||||
|
||||
/* XXX */
|
||||
buf_type = HAL_RX_WBM_BUF_TYPE_GET(ring_desc);
|
||||
|
||||
|
|
@ -716,7 +825,6 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
|
|||
HAL_RX_WBM_REO_PUSH_REASON_GET(ring_desc);
|
||||
|
||||
if (push_reason == HAL_RX_WBM_REO_PSH_RSN_ERROR) {
|
||||
|
||||
uint8_t reo_error_code =
|
||||
HAL_RX_WBM_REO_ERROR_CODE_GET(ring_desc);
|
||||
|
||||
|
|
@ -734,11 +842,11 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
|
|||
"Got pkt with REO ERROR: %d",
|
||||
reo_error_code);
|
||||
|
||||
rx_bufs_used[rx_desc->pool_id] +=
|
||||
rx_bufs_used[pool_id] +=
|
||||
dp_rx_null_q_desc_handle(soc,
|
||||
rx_desc,
|
||||
&head[rx_desc->pool_id],
|
||||
&tail[rx_desc->pool_id], quota);
|
||||
&head[pool_id],
|
||||
&tail[pool_id], quota);
|
||||
continue;
|
||||
/* TODO */
|
||||
/* Add per error code accounting */
|
||||
|
|
@ -763,15 +871,20 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
|
|||
rxdma_error_code], 1);
|
||||
|
||||
switch (rxdma_error_code) {
|
||||
|
||||
/* TODO */
|
||||
/* Add per error code accounting */
|
||||
case HAL_RXDMA_ERR_UNENCRYPTED:
|
||||
rx_bufs_used[pool_id] +=
|
||||
dp_rx_err_deliver(soc,
|
||||
rx_desc,
|
||||
&head[pool_id],
|
||||
&tail[pool_id],
|
||||
quota);
|
||||
continue;
|
||||
|
||||
default:
|
||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||
QDF_TRACE_LEVEL_ERROR,
|
||||
"RXDMA error %d detected",
|
||||
rxdma_error_code);
|
||||
QDF_TRACE_LEVEL_ERROR,
|
||||
"RXDMA error %d",
|
||||
rxdma_error_code);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1827,7 +1827,7 @@ enum hal_rxdma_error_code {
|
|||
HAL_RXDMA_ERR_FCS,
|
||||
HAL_RXDMA_ERR_DECRYPT,
|
||||
HAL_RXDMA_ERR_TKIP_MIC,
|
||||
HAL_RXDMA_ERR_UNECRYPTED,
|
||||
HAL_RXDMA_ERR_UNENCRYPTED,
|
||||
HAL_RXDMA_ERR_MSDU_LEN,
|
||||
HAL_RXDMA_ERR_MSDU_LIMIT,
|
||||
HAL_RXDMA_ERR_WIFI_PARSE,
|
||||
|
|
|
|||
Loading…
Reference in a new issue