diff --git a/drivers/net/wireless/ath/ath12k/ce.c b/drivers/net/wireless/ath/ath12k/ce.c index f13b260c5c96e..a0c056d9aba1c 100644 --- a/drivers/net/wireless/ath/ath12k/ce.c +++ b/drivers/net/wireless/ath/ath12k/ce.c @@ -134,6 +134,18 @@ static int ath12k_ce_completed_recv_next(struct ath12k_ce_pipe *pipe, } *nbytes = ath12k_hal_ce_dst_status_get_length(&ab->hal, desc); + if (*nbytes == 0) { + ath12k_warn(ab, "ce pipe %d recv nbytes 0, status desc raw: %08x %08x %08x %08x, srng hp %u tp %u\n", + pipe->pipe_num, + le32_to_cpu(((__le32 *)desc)[0]), + le32_to_cpu(((__le32 *)desc)[1]), + le32_to_cpu(((__le32 *)desc)[2]), + le32_to_cpu(((__le32 *)desc)[3]), + srng->u.dst_ring.cached_hp, + srng->u.dst_ring.tp); + ret = -EIO; + goto err; + } *skb = pipe->dest_ring->skb[sw_index]; pipe->dest_ring->skb[sw_index] = NULL; @@ -166,9 +178,9 @@ static void ath12k_ce_recv_process_cb(struct ath12k_ce_pipe *pipe) dma_unmap_single(ab->dev, ATH12K_SKB_RXCB(skb)->paddr, max_nbytes, DMA_FROM_DEVICE); - if (unlikely(max_nbytes < nbytes || nbytes == 0)) { - ath12k_warn(ab, "unexpected rx length (nbytes %d, max %d)", - nbytes, max_nbytes); + if (unlikely(max_nbytes < nbytes)) { + ath12k_warn(ab, "rxed more than expected (nbytes %d, max %d) on ce pipe %d\n", + nbytes, max_nbytes, pipe->pipe_num); dev_kfree_skb_any(skb); continue; } diff --git a/drivers/net/wireless/ath/ath12k/hal.c b/drivers/net/wireless/ath/ath12k/hal.c index bad672942ee35..e531f7d118554 100644 --- a/drivers/net/wireless/ath/ath12k/hal.c +++ b/drivers/net/wireless/ath/ath12k/hal.c @@ -538,9 +538,18 @@ void ath12k_hal_srng_access_begin(struct ath12k_base *ab, struct hal_srng *srng) if (srng->ring_dir == HAL_SRNG_DIR_SRC) { srng->u.src_ring.cached_tp = *(volatile u32 *)srng->u.src_ring.tp_addr; + if (unlikely(srng->u.src_ring.cached_tp >= srng->ring_size)) + ath12k_warn(ab, "srng %d src tp out of bounds: tp %u ring_size %u\n", + srng->ring_id, srng->u.src_ring.cached_tp, + srng->ring_size); } else { hp = READ_ONCE(*srng->u.dst_ring.hp_addr); + if (unlikely(hp >= srng->ring_size)) + ath12k_warn(ab, "srng %d dst hp out of bounds: hp %u ring_size %u (raw hp_addr value 0x%08x)\n", + srng->ring_id, hp, srng->ring_size, + READ_ONCE(*srng->u.dst_ring.hp_addr)); + if (hp != srng->u.dst_ring.cached_hp) { srng->u.dst_ring.cached_hp = hp; /* Make sure descriptor is read after the head diff --git a/drivers/net/wireless/ath/ath12k/htc.c b/drivers/net/wireless/ath/ath12k/htc.c index 92138caa2a82f..b80bf7547a050 100644 --- a/drivers/net/wireless/ath/ath12k/htc.c +++ b/drivers/net/wireless/ath/ath12k/htc.c @@ -268,7 +268,12 @@ void ath12k_htc_rx_completion_handler(struct ath12k_base *ab, eid = le32_get_bits(hdr->htc_info, HTC_HDR_ENDPOINTID); if (eid >= ATH12K_HTC_EP_COUNT) { - ath12k_warn(ab, "HTC Rx: invalid eid %d\n", eid); + ath12k_warn(ab, "HTC Rx: invalid eid %d, htc_info 0x%08x ctrl_info 0x%08x skb->len %d\n", + eid, le32_to_cpu(hdr->htc_info), + le32_to_cpu(hdr->ctrl_info), skb->len); + ath12k_warn(ab, "HTC Rx: payload after hdr (%d bytes): %*ph\n", + min_t(int, skb->len, 32), + min_t(int, skb->len, 32), skb->data); goto out; } @@ -277,14 +282,21 @@ void ath12k_htc_rx_completion_handler(struct ath12k_base *ab, payload_len = le32_get_bits(hdr->htc_info, HTC_HDR_PAYLOADLEN); if (payload_len + sizeof(*hdr) > ATH12K_HTC_MAX_LEN) { - ath12k_warn(ab, "HTC rx frame too long, len: %zu\n", - payload_len + sizeof(*hdr)); + ath12k_warn(ab, "HTC rx frame too long, len: %zu, htc_info 0x%08x ctrl_info 0x%08x\n", + payload_len + sizeof(*hdr), + le32_to_cpu(hdr->htc_info), + le32_to_cpu(hdr->ctrl_info)); + ath12k_warn(ab, "HTC Rx: payload after hdr (%d bytes): %*ph\n", + min_t(int, skb->len, 32), + min_t(int, skb->len, 32), skb->data); goto out; } if (skb->len < payload_len) { - ath12k_warn(ab, "HTC Rx: insufficient length, got %d, expected %d\n", - skb->len, payload_len); + ath12k_warn(ab, "HTC Rx: insufficient length, got %d, expected %d, htc_info 0x%08x ctrl_info 0x%08x\n", + skb->len, payload_len, + le32_to_cpu(hdr->htc_info), + le32_to_cpu(hdr->ctrl_info)); goto out; } diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 48e68045c14c6..c51325a6f256c 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -5377,7 +5377,8 @@ int ath12k_mac_get_fw_stats(struct ath12k *ar, time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ); if (!time_left) { - ath12k_warn(ab, "time out while waiting for get fw stats\n"); + ath12k_warn(ab, "time out while waiting for get fw stats (pdev_id %d vdev_id %d stats_id 0x%x)\n", + param->pdev_id, param->vdev_id, param->stats_id); return -ETIMEDOUT; } diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index a3fde83cdad3f..ddc8ec64748dc 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -513,7 +513,9 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, ath12k_dp_extract_rx_desc_data(hal, rx_info, rx_desc, lrx_desc); if (!rx_info->msdu_done) { - ath12k_warn(dp->ab, "msdu_done bit in msdu_end is not set\n"); + ath12k_warn(dp->ab, "msdu_done bit in msdu_end is not set, rx_desc first 32 bytes: %*ph\n", + min_t(int, 32, (int)sizeof(*rx_desc)), + rx_desc); ret = -EIO; goto free_out; } @@ -528,9 +530,10 @@ static int ath12k_wifi7_dp_rx_process_msdu(struct ath12k_pdev_dp *dp_pdev, } else if (!rxcb->is_continuation) { if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { ret = -EINVAL; - ath12k_warn(dp->ab, "invalid msdu len %u\n", msdu_len); - ath12k_dbg_dump(dp->ab, ATH12K_DBG_DATA, NULL, "", rx_desc, - sizeof(*rx_desc)); + ath12k_warn(dp->ab, "invalid msdu len %u (desc_sz %u buf_sz %d), rx_desc first 32 bytes: %*ph\n", + msdu_len, hal_rx_desc_sz, DP_RX_BUFFER_SIZE, + min_t(int, 32, (int)sizeof(*rx_desc)), + rx_desc); goto free_out; } skb_put(msdu, hal_rx_desc_sz + l3_pad_bytes + msdu_len); @@ -1381,9 +1384,10 @@ ath12k_wifi7_dp_process_rx_err_buf(struct ath12k_pdev_dp *dp_pdev, msdu_len = rx_info.msdu_len; if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { - ath12k_warn(dp->ab, "invalid msdu leng %u", msdu_len); - ath12k_dbg_dump(dp->ab, ATH12K_DBG_DATA, NULL, "", rx_desc, - sizeof(*rx_desc)); + ath12k_warn(dp->ab, "invalid msdu leng %u (desc_sz %u buf_sz %d), rx_desc first 32 bytes: %*ph\n", + msdu_len, hal_rx_desc_sz, DP_RX_BUFFER_SIZE, + min_t(int, 32, (int)sizeof(*rx_desc)), + rx_desc); dev_kfree_skb_any(msdu); goto exit; } @@ -1663,7 +1667,9 @@ static int ath12k_wifi7_dp_rx_h_null_q_desc(struct ath12k_pdev_dp *dp_pdev, if (!rx_info->msdu_done) { ath12k_warn(ab, - "msdu_done bit not set in null_q_des processing\n"); + "msdu_done bit not set in null_q_des processing, rx_desc first 32 bytes: %*ph\n", + min_t(int, 32, hal_rx_desc_sz), + msdu->data); __skb_queue_purge(msdu_list); return -EIO; }