Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5118935

Browse files
Manikanta PubbisettyKalle Valo
authored andcommitted
ath11k: dump SRNG stats during FW assert
Dumping the SRNG stats during FW assert, this would help in debugging ring stuck issues. Co-developed-by: Karthikeyan Periyasamy <[email protected]> Signed-off-by: Karthikeyan Periyasamy <[email protected]> Signed-off-by: Manikanta Pubbisetty <[email protected]> Signed-off-by: Kalle Valo <[email protected]>
1 parent de06b2f commit 5118935

File tree

6 files changed

+82
-2
lines changed

6 files changed

+82
-2
lines changed

drivers/net/wireless/ath/ath11k/ahb.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,9 @@ static irqreturn_t ath11k_ahb_ce_interrupt_handler(int irq, void *arg)
681681
{
682682
struct ath11k_ce_pipe *ce_pipe = arg;
683683

684+
/* last interrupt received for this CE */
685+
ce_pipe->timestamp = jiffies;
686+
684687
ath11k_ahb_ce_irq_disable(ce_pipe->ab, ce_pipe->pipe_num);
685688

686689
tasklet_schedule(&ce_pipe->intr_tq);
@@ -712,6 +715,9 @@ static irqreturn_t ath11k_ahb_ext_interrupt_handler(int irq, void *arg)
712715
{
713716
struct ath11k_ext_irq_grp *irq_grp = arg;
714717

718+
/* last interrupt received for this group */
719+
irq_grp->timestamp = jiffies;
720+
715721
ath11k_ahb_ext_grp_disable(irq_grp);
716722

717723
napi_schedule(&irq_grp->napi);

drivers/net/wireless/ath/ath11k/ce.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ struct ath11k_ce_pipe {
161161
struct ath11k_ce_ring *src_ring;
162162
struct ath11k_ce_ring *dest_ring;
163163
struct ath11k_ce_ring *status_ring;
164+
u64 timestamp;
164165
};
165166

166167
struct ath11k_ce {

drivers/net/wireless/ath/ath11k/core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ struct ath11k_ext_irq_grp {
110110
u32 irqs[ATH11K_EXT_IRQ_NUM_MAX];
111111
u32 num_irq;
112112
u32 grp_id;
113+
u64 timestamp;
113114
struct napi_struct napi;
114115
struct net_device napi_ndev;
115116
/* Queue of pending packets, not expected to be accessed concurrently

drivers/net/wireless/ath/ath11k/hal.c

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -877,23 +877,32 @@ void ath11k_hal_srng_access_end(struct ath11k_base *ab, struct hal_srng *srng)
877877
/* For LMAC rings, ring pointer updates are done through FW and
878878
* hence written to a shared memory location that is read by FW
879879
*/
880-
if (srng->ring_dir == HAL_SRNG_DIR_SRC)
880+
if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
881+
srng->u.src_ring.last_tp =
882+
*(volatile u32 *)srng->u.src_ring.tp_addr;
881883
*srng->u.src_ring.hp_addr = srng->u.src_ring.hp;
882-
else
884+
} else {
885+
srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;
883886
*srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp;
887+
}
884888
} else {
885889
if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
890+
srng->u.src_ring.last_tp =
891+
*(volatile u32 *)srng->u.src_ring.tp_addr;
886892
ath11k_ahb_write32(ab,
887893
(unsigned long)srng->u.src_ring.hp_addr -
888894
(unsigned long)ab->mem,
889895
srng->u.src_ring.hp);
890896
} else {
897+
srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;
891898
ath11k_ahb_write32(ab,
892899
(unsigned long)srng->u.dst_ring.tp_addr -
893900
(unsigned long)ab->mem,
894901
srng->u.dst_ring.tp);
895902
}
896903
}
904+
905+
srng->timestamp = jiffies;
897906
}
898907

899908
void ath11k_hal_setup_link_idle_list(struct ath11k_base *ab,
@@ -1017,6 +1026,7 @@ int ath11k_hal_srng_setup(struct ath11k_base *ab, enum hal_ring_type type,
10171026
params->intr_batch_cntr_thres_entries;
10181027
srng->intr_timer_thres_us = params->intr_timer_thres_us;
10191028
srng->flags = params->flags;
1029+
srng->initialized = 1;
10201030
spin_lock_init(&srng->lock);
10211031

10221032
for (i = 0; i < HAL_SRNG_NUM_REG_GRP; i++) {
@@ -1122,3 +1132,55 @@ void ath11k_hal_srng_deinit(struct ath11k_base *ab)
11221132
ath11k_hal_free_cont_rdp(ab);
11231133
ath11k_hal_free_cont_wrp(ab);
11241134
}
1135+
1136+
void ath11k_hal_dump_srng_stats(struct ath11k_base *ab)
1137+
{
1138+
struct hal_srng *srng;
1139+
struct ath11k_ext_irq_grp *irq_grp;
1140+
struct ath11k_ce_pipe *ce_pipe;
1141+
int i;
1142+
1143+
ath11k_err(ab, "Last interrupt received for each CE:\n");
1144+
for (i = 0; i < CE_COUNT; i++) {
1145+
ce_pipe = &ab->ce.ce_pipe[i];
1146+
1147+
if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR)
1148+
continue;
1149+
1150+
ath11k_err(ab, "CE_id %d pipe_num %d %ums before\n",
1151+
i, ce_pipe->pipe_num,
1152+
jiffies_to_msecs(jiffies - ce_pipe->timestamp));
1153+
}
1154+
1155+
ath11k_err(ab, "\nLast interrupt received for each group:\n");
1156+
for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
1157+
irq_grp = &ab->ext_irq_grp[i];
1158+
ath11k_err(ab, "group_id %d %ums before\n",
1159+
irq_grp->grp_id,
1160+
jiffies_to_msecs(jiffies - irq_grp->timestamp));
1161+
}
1162+
1163+
for (i = 0; i < HAL_SRNG_RING_ID_MAX; i++) {
1164+
srng = &ab->hal.srng_list[i];
1165+
1166+
if (!srng->initialized)
1167+
continue;
1168+
1169+
if (srng->ring_dir == HAL_SRNG_DIR_SRC)
1170+
ath11k_err(ab,
1171+
"src srng id %u hp %u, reap_hp %u, cur tp %u, cached tp %u last tp %u napi processed before %ums\n",
1172+
srng->ring_id, srng->u.src_ring.hp,
1173+
srng->u.src_ring.reap_hp,
1174+
*srng->u.src_ring.tp_addr, srng->u.src_ring.cached_tp,
1175+
srng->u.src_ring.last_tp,
1176+
jiffies_to_msecs(jiffies - srng->timestamp));
1177+
else if (srng->ring_dir == HAL_SRNG_DIR_DST)
1178+
ath11k_err(ab,
1179+
"dst srng id %u tp %u, cur hp %u, cached hp %u last hp %u napi processed before %ums\n",
1180+
srng->ring_id, srng->u.dst_ring.tp,
1181+
*srng->u.dst_ring.hp_addr,
1182+
srng->u.dst_ring.cached_hp,
1183+
srng->u.dst_ring.last_hp,
1184+
jiffies_to_msecs(jiffies - srng->timestamp));
1185+
}
1186+
}

drivers/net/wireless/ath/ath11k/hal.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,8 @@ struct hal_srng {
529529
*/
530530
u32 hwreg_base[HAL_SRNG_NUM_REG_GRP];
531531

532+
u64 timestamp;
533+
532534
/* Source or Destination ring */
533535
enum hal_srng_dir ring_dir;
534536

@@ -554,6 +556,9 @@ struct hal_srng {
554556

555557
/* max transfer size */
556558
u16 max_buffer_length;
559+
560+
/* head pointer at access end */
561+
u32 last_hp;
557562
} dst_ring;
558563

559564
struct {
@@ -577,6 +582,9 @@ struct hal_srng {
577582

578583
/* Low threshold - in number of ring entries */
579584
u32 low_threshold;
585+
586+
/* tail pointer at access end */
587+
u32 last_tp;
580588
} src_ring;
581589
} u;
582590
};
@@ -893,5 +901,6 @@ int ath11k_hal_srng_setup(struct ath11k_base *ab, enum hal_ring_type type,
893901
struct hal_srng_params *params);
894902
int ath11k_hal_srng_init(struct ath11k_base *ath11k);
895903
void ath11k_hal_srng_deinit(struct ath11k_base *ath11k);
904+
void ath11k_hal_dump_srng_stats(struct ath11k_base *ab);
896905

897906
#endif

drivers/net/wireless/ath/ath11k/qmi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2365,6 +2365,7 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work)
23652365
break;
23662366
case ATH11K_QMI_EVENT_FW_READY:
23672367
if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) {
2368+
ath11k_hal_dump_srng_stats(ab);
23682369
queue_work(ab->workqueue, &ab->restart_work);
23692370
break;
23702371
}

0 commit comments

Comments
 (0)