Loading drivers/net/wireless/ath/wil6210/debugfs.c +2 −0 Original line number Diff line number Diff line Loading @@ -218,6 +218,8 @@ static void wil_print_sring(struct seq_file *s, struct wil6210_priv *wil, seq_puts(s, "???\n"); } seq_printf(s, " desc_rdy_pol = %d\n", sring->desc_rdy_pol); seq_printf(s, " invalid_buff_id_cnt = %d\n", sring->invalid_buff_id_cnt); if (sring->va && (sring->size <= (1 << WIL_RING_SIZE_ORDER_MAX))) { uint i; Loading drivers/net/wireless/ath/wil6210/txrx_edma.c +40 −12 Original line number Diff line number Diff line /* * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -29,6 +29,7 @@ #define WIL_EDMA_MAX_DATA_OFFSET (2) /* RX buffer size must be aligned to 4 bytes */ #define WIL_EDMA_RX_BUF_LEN_DEFAULT (2048) #define MAX_INVALID_BUFF_ID_RETRY (3) static void wil_tx_desc_unmap_edma(struct device *dev, union wil_tx_desc *desc, Loading Loading @@ -313,7 +314,8 @@ static int wil_init_rx_buff_arr(struct wil6210_priv *wil, struct list_head *free = &wil->rx_buff_mgmt.free; int i; wil->rx_buff_mgmt.buff_arr = kcalloc(size, sizeof(struct wil_rx_buff), wil->rx_buff_mgmt.buff_arr = kcalloc(size + 1, sizeof(struct wil_rx_buff), GFP_KERNEL); if (!wil->rx_buff_mgmt.buff_arr) return -ENOMEM; Loading @@ -322,14 +324,16 @@ static int wil_init_rx_buff_arr(struct wil6210_priv *wil, INIT_LIST_HEAD(active); INIT_LIST_HEAD(free); /* Linkify the list */ /* Linkify the list. * buffer id 0 should not be used (marks invalid id). */ buff_arr = wil->rx_buff_mgmt.buff_arr; for (i = 0; i < size; i++) { for (i = 1; i <= size; i++) { list_add(&buff_arr[i].list, free); buff_arr[i].id = i; } wil->rx_buff_mgmt.size = size; wil->rx_buff_mgmt.size = size + 1; return 0; } Loading Loading @@ -893,26 +897,50 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil, /* Extract the buffer ID from the status message */ buff_id = le16_to_cpu(wil_rx_status_get_buff_id(msg)); if (unlikely(!wil_val_in_range(buff_id, 0, wil->rx_buff_mgmt.size))) { while (!buff_id) { struct wil_rx_status_extended *s; int invalid_buff_id_retry = 0; wil_dbg_txrx(wil, "buff_id is not updated yet by HW, (swhead 0x%x)\n", sring->swhead); if (++invalid_buff_id_retry > MAX_INVALID_BUFF_ID_RETRY) break; /* Read the status message again */ s = (struct wil_rx_status_extended *) (sring->va + (sring->elem_size * sring->swhead)); *(struct wil_rx_status_extended *)msg = *s; buff_id = le16_to_cpu(wil_rx_status_get_buff_id(msg)); } if (unlikely(!wil_val_in_range(buff_id, 1, wil->rx_buff_mgmt.size))) { wil_err(wil, "Corrupt buff_id=%d, sring->swhead=%d\n", buff_id, sring->swhead); wil_rx_status_reset_buff_id(sring); wil_sring_advance_swhead(sring); sring->invalid_buff_id_cnt++; goto again; } wil_sring_advance_swhead(sring); /* Extract the SKB from the rx_buff management array */ skb = wil->rx_buff_mgmt.buff_arr[buff_id].skb; wil->rx_buff_mgmt.buff_arr[buff_id].skb = NULL; if (!skb) { wil_err(wil, "No Rx skb at buff_id %d\n", buff_id); wil_rx_status_reset_buff_id(sring); /* Move the buffer from the active list to the free list */ list_move(&wil->rx_buff_mgmt.buff_arr[buff_id].list, list_move_tail(&wil->rx_buff_mgmt.buff_arr[buff_id].list, &wil->rx_buff_mgmt.free); wil_sring_advance_swhead(sring); sring->invalid_buff_id_cnt++; goto again; } wil_rx_status_reset_buff_id(sring); wil_sring_advance_swhead(sring); memcpy(&pa, skb->cb, sizeof(pa)); dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE); dmalen = le16_to_cpu(wil_rx_status_get_length(msg)); Loading @@ -927,7 +955,7 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil, sizeof(struct wil_rx_status_extended), false); /* Move the buffer from the active list to the free list */ list_move(&wil->rx_buff_mgmt.buff_arr[buff_id].list, list_move_tail(&wil->rx_buff_mgmt.buff_arr[buff_id].list, &wil->rx_buff_mgmt.free); eop = wil_rx_status_get_eop(msg); Loading drivers/net/wireless/ath/wil6210/txrx_edma.h +7 −1 Original line number Diff line number Diff line /* * Copyright (c) 2012-2016,2018, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2016,2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -427,6 +427,12 @@ static inline int wil_rx_status_get_eop(void *msg) /* EoP = End of Packet */ 30, 30); } static inline void wil_rx_status_reset_buff_id(struct wil_status_ring *s) { ((struct wil_rx_status_compressed *) (s->va + (s->elem_size * s->swhead)))->buff_id = 0; } static inline __le16 wil_rx_status_get_buff_id(void *msg) { return ((struct wil_rx_status_compressed *)msg)->buff_id; Loading drivers/net/wireless/ath/wil6210/wil6210.h +1 −0 Original line number Diff line number Diff line Loading @@ -567,6 +567,7 @@ struct wil_status_ring { bool is_rx; u8 desc_rdy_pol; /* Expected descriptor ready bit polarity */ struct wil_ring_rx_data rx_data; u32 invalid_buff_id_cnt; /* relevant only for RX */ }; #define WIL_STA_TID_NUM (16) Loading Loading
drivers/net/wireless/ath/wil6210/debugfs.c +2 −0 Original line number Diff line number Diff line Loading @@ -218,6 +218,8 @@ static void wil_print_sring(struct seq_file *s, struct wil6210_priv *wil, seq_puts(s, "???\n"); } seq_printf(s, " desc_rdy_pol = %d\n", sring->desc_rdy_pol); seq_printf(s, " invalid_buff_id_cnt = %d\n", sring->invalid_buff_id_cnt); if (sring->va && (sring->size <= (1 << WIL_RING_SIZE_ORDER_MAX))) { uint i; Loading
drivers/net/wireless/ath/wil6210/txrx_edma.c +40 −12 Original line number Diff line number Diff line /* * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -29,6 +29,7 @@ #define WIL_EDMA_MAX_DATA_OFFSET (2) /* RX buffer size must be aligned to 4 bytes */ #define WIL_EDMA_RX_BUF_LEN_DEFAULT (2048) #define MAX_INVALID_BUFF_ID_RETRY (3) static void wil_tx_desc_unmap_edma(struct device *dev, union wil_tx_desc *desc, Loading Loading @@ -313,7 +314,8 @@ static int wil_init_rx_buff_arr(struct wil6210_priv *wil, struct list_head *free = &wil->rx_buff_mgmt.free; int i; wil->rx_buff_mgmt.buff_arr = kcalloc(size, sizeof(struct wil_rx_buff), wil->rx_buff_mgmt.buff_arr = kcalloc(size + 1, sizeof(struct wil_rx_buff), GFP_KERNEL); if (!wil->rx_buff_mgmt.buff_arr) return -ENOMEM; Loading @@ -322,14 +324,16 @@ static int wil_init_rx_buff_arr(struct wil6210_priv *wil, INIT_LIST_HEAD(active); INIT_LIST_HEAD(free); /* Linkify the list */ /* Linkify the list. * buffer id 0 should not be used (marks invalid id). */ buff_arr = wil->rx_buff_mgmt.buff_arr; for (i = 0; i < size; i++) { for (i = 1; i <= size; i++) { list_add(&buff_arr[i].list, free); buff_arr[i].id = i; } wil->rx_buff_mgmt.size = size; wil->rx_buff_mgmt.size = size + 1; return 0; } Loading Loading @@ -893,26 +897,50 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil, /* Extract the buffer ID from the status message */ buff_id = le16_to_cpu(wil_rx_status_get_buff_id(msg)); if (unlikely(!wil_val_in_range(buff_id, 0, wil->rx_buff_mgmt.size))) { while (!buff_id) { struct wil_rx_status_extended *s; int invalid_buff_id_retry = 0; wil_dbg_txrx(wil, "buff_id is not updated yet by HW, (swhead 0x%x)\n", sring->swhead); if (++invalid_buff_id_retry > MAX_INVALID_BUFF_ID_RETRY) break; /* Read the status message again */ s = (struct wil_rx_status_extended *) (sring->va + (sring->elem_size * sring->swhead)); *(struct wil_rx_status_extended *)msg = *s; buff_id = le16_to_cpu(wil_rx_status_get_buff_id(msg)); } if (unlikely(!wil_val_in_range(buff_id, 1, wil->rx_buff_mgmt.size))) { wil_err(wil, "Corrupt buff_id=%d, sring->swhead=%d\n", buff_id, sring->swhead); wil_rx_status_reset_buff_id(sring); wil_sring_advance_swhead(sring); sring->invalid_buff_id_cnt++; goto again; } wil_sring_advance_swhead(sring); /* Extract the SKB from the rx_buff management array */ skb = wil->rx_buff_mgmt.buff_arr[buff_id].skb; wil->rx_buff_mgmt.buff_arr[buff_id].skb = NULL; if (!skb) { wil_err(wil, "No Rx skb at buff_id %d\n", buff_id); wil_rx_status_reset_buff_id(sring); /* Move the buffer from the active list to the free list */ list_move(&wil->rx_buff_mgmt.buff_arr[buff_id].list, list_move_tail(&wil->rx_buff_mgmt.buff_arr[buff_id].list, &wil->rx_buff_mgmt.free); wil_sring_advance_swhead(sring); sring->invalid_buff_id_cnt++; goto again; } wil_rx_status_reset_buff_id(sring); wil_sring_advance_swhead(sring); memcpy(&pa, skb->cb, sizeof(pa)); dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE); dmalen = le16_to_cpu(wil_rx_status_get_length(msg)); Loading @@ -927,7 +955,7 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil, sizeof(struct wil_rx_status_extended), false); /* Move the buffer from the active list to the free list */ list_move(&wil->rx_buff_mgmt.buff_arr[buff_id].list, list_move_tail(&wil->rx_buff_mgmt.buff_arr[buff_id].list, &wil->rx_buff_mgmt.free); eop = wil_rx_status_get_eop(msg); Loading
drivers/net/wireless/ath/wil6210/txrx_edma.h +7 −1 Original line number Diff line number Diff line /* * Copyright (c) 2012-2016,2018, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2016,2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -427,6 +427,12 @@ static inline int wil_rx_status_get_eop(void *msg) /* EoP = End of Packet */ 30, 30); } static inline void wil_rx_status_reset_buff_id(struct wil_status_ring *s) { ((struct wil_rx_status_compressed *) (s->va + (s->elem_size * s->swhead)))->buff_id = 0; } static inline __le16 wil_rx_status_get_buff_id(void *msg) { return ((struct wil_rx_status_compressed *)msg)->buff_id; Loading
drivers/net/wireless/ath/wil6210/wil6210.h +1 −0 Original line number Diff line number Diff line Loading @@ -567,6 +567,7 @@ struct wil_status_ring { bool is_rx; u8 desc_rdy_pol; /* Expected descriptor ready bit polarity */ struct wil_ring_rx_data rx_data; u32 invalid_buff_id_cnt; /* relevant only for RX */ }; #define WIL_STA_TID_NUM (16) Loading