Commit 33e61169 authored by Vladimir Kondratiev's avatar Vladimir Kondratiev Committed by John W. Linville

wil6210: Use cached copy of Rx descriptor

Rx descriptors stored in non-cacheable memory area for DMA.
Non-cacheable memory causes long access time from CPU.

Copy rx descriptor to the skb->cb, and use this copy.
It provides faster memory access, and will be usefull to keep
Rx information for later processing (BACK reorder)
Signed-off-by: default avatarVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 047445c5
...@@ -193,8 +193,7 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring, ...@@ -193,8 +193,7 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring,
* - Phy info * - Phy info
*/ */
static void wil_rx_add_radiotap_header(struct wil6210_priv *wil, static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
struct sk_buff *skb, struct sk_buff *skb)
volatile struct vring_rx_desc *d)
{ {
struct wireless_dev *wdev = wil->wdev; struct wireless_dev *wdev = wil->wdev;
struct wil6210_rtap { struct wil6210_rtap {
...@@ -218,6 +217,7 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil, ...@@ -218,6 +217,7 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
__le16 vendor_skip; __le16 vendor_skip;
u8 vendor_data[0]; u8 vendor_data[0];
} __packed; } __packed;
struct vring_rx_desc *d = wil_skb_rxdesc(skb);
struct wil6210_rtap_vendor *rtap_vendor; struct wil6210_rtap_vendor *rtap_vendor;
int rtap_len = sizeof(struct wil6210_rtap); int rtap_len = sizeof(struct wil6210_rtap);
int phy_length = 0; /* phy info header size, bytes */ int phy_length = 0; /* phy info header size, bytes */
...@@ -314,6 +314,8 @@ static void wil_swap_ethaddr(void *data) ...@@ -314,6 +314,8 @@ static void wil_swap_ethaddr(void *data)
/** /**
* reap 1 frame from @swhead * reap 1 frame from @swhead
* *
* Rx descriptor copied to skb->cb
*
* Safe to call from IRQ * Safe to call from IRQ
*/ */
static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
...@@ -322,12 +324,15 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, ...@@ -322,12 +324,15 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
struct device *dev = wil_to_dev(wil); struct device *dev = wil_to_dev(wil);
struct net_device *ndev = wil_to_ndev(wil); struct net_device *ndev = wil_to_ndev(wil);
volatile struct vring_rx_desc *d; volatile struct vring_rx_desc *d;
struct vring_rx_desc *d1;
struct sk_buff *skb; struct sk_buff *skb;
dma_addr_t pa; dma_addr_t pa;
unsigned int sz = RX_BUF_LEN; unsigned int sz = RX_BUF_LEN;
u8 ftype; u8 ftype;
u8 ds_bits; u8 ds_bits;
BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb));
if (wil_vring_is_empty(vring)) if (wil_vring_is_empty(vring))
return NULL; return NULL;
...@@ -342,11 +347,14 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, ...@@ -342,11 +347,14 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE); dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE);
skb_trim(skb, d->dma.length); skb_trim(skb, d->dma.length);
wil->stats.last_mcs_rx = wil_rxdesc_mcs(d); d1 = wil_skb_rxdesc(skb);
*d1 = *d;
wil->stats.last_mcs_rx = wil_rxdesc_mcs(d1);
/* use radiotap header only if required */ /* use radiotap header only if required */
if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) if (ndev->type == ARPHRD_IEEE80211_RADIOTAP)
wil_rx_add_radiotap_header(wil, skb, d); wil_rx_add_radiotap_header(wil, skb);
wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length); wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length);
wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4, wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4,
...@@ -362,7 +370,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, ...@@ -362,7 +370,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
* Driver should recognize it by frame type, that is found * Driver should recognize it by frame type, that is found
* in Rx descriptor. If type is not data, it is 802.11 frame as is * in Rx descriptor. If type is not data, it is 802.11 frame as is
*/ */
ftype = wil_rxdesc_ftype(d) << 2; ftype = wil_rxdesc_ftype(d1) << 2;
if (ftype != IEEE80211_FTYPE_DATA) { if (ftype != IEEE80211_FTYPE_DATA) {
wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype); wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype);
/* TODO: process it */ /* TODO: process it */
...@@ -377,7 +385,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, ...@@ -377,7 +385,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
return NULL; return NULL;
} }
ds_bits = wil_rxdesc_ds_bits(d); ds_bits = wil_rxdesc_ds_bits(d1);
if (ds_bits == 1) { if (ds_bits == 1) {
/* /*
* HW bug - in ToDS mode, i.e. Rx on AP side, * HW bug - in ToDS mode, i.e. Rx on AP side,
......
...@@ -339,24 +339,29 @@ union vring_desc { ...@@ -339,24 +339,29 @@ union vring_desc {
struct vring_rx_desc rx; struct vring_rx_desc rx;
} __packed; } __packed;
static inline int wil_rxdesc_phy_length(volatile struct vring_rx_desc *d) static inline int wil_rxdesc_phy_length(struct vring_rx_desc *d)
{ {
return WIL_GET_BITS(d->dma.d0, 16, 29); return WIL_GET_BITS(d->dma.d0, 16, 29);
} }
static inline int wil_rxdesc_mcs(volatile struct vring_rx_desc *d) static inline int wil_rxdesc_mcs(struct vring_rx_desc *d)
{ {
return WIL_GET_BITS(d->mac.d1, 21, 24); return WIL_GET_BITS(d->mac.d1, 21, 24);
} }
static inline int wil_rxdesc_ds_bits(volatile struct vring_rx_desc *d) static inline int wil_rxdesc_ds_bits(struct vring_rx_desc *d)
{ {
return WIL_GET_BITS(d->mac.d1, 8, 9); return WIL_GET_BITS(d->mac.d1, 8, 9);
} }
static inline int wil_rxdesc_ftype(volatile struct vring_rx_desc *d) static inline int wil_rxdesc_ftype(struct vring_rx_desc *d)
{ {
return WIL_GET_BITS(d->mac.d0, 10, 11); return WIL_GET_BITS(d->mac.d0, 10, 11);
} }
static inline struct vring_rx_desc *wil_skb_rxdesc(struct sk_buff *skb)
{
return (void *)skb->cb;
}
#endif /* WIL6210_TXRX_H */ #endif /* WIL6210_TXRX_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment