aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>2013-04-18 07:33:50 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-04-22 15:20:24 -0400
commit33e611690e6478ebb095e4eb755010343374a2a3 (patch)
tree354bf88b9fb2581263085687af9c7cddf30318c9
parent047445c579dc28772aadaac6b7b37289aad72b22 (diff)
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: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c20
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.h13
2 files changed, 23 insertions, 10 deletions
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 1bfa736cc1f2..d8619440d175 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -193,8 +193,7 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring,
193 * - Phy info 193 * - Phy info
194 */ 194 */
195static void wil_rx_add_radiotap_header(struct wil6210_priv *wil, 195static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
196 struct sk_buff *skb, 196 struct sk_buff *skb)
197 volatile struct vring_rx_desc *d)
198{ 197{
199 struct wireless_dev *wdev = wil->wdev; 198 struct wireless_dev *wdev = wil->wdev;
200 struct wil6210_rtap { 199 struct wil6210_rtap {
@@ -218,6 +217,7 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
218 __le16 vendor_skip; 217 __le16 vendor_skip;
219 u8 vendor_data[0]; 218 u8 vendor_data[0];
220 } __packed; 219 } __packed;
220 struct vring_rx_desc *d = wil_skb_rxdesc(skb);
221 struct wil6210_rtap_vendor *rtap_vendor; 221 struct wil6210_rtap_vendor *rtap_vendor;
222 int rtap_len = sizeof(struct wil6210_rtap); 222 int rtap_len = sizeof(struct wil6210_rtap);
223 int phy_length = 0; /* phy info header size, bytes */ 223 int phy_length = 0; /* phy info header size, bytes */
@@ -314,6 +314,8 @@ static void wil_swap_ethaddr(void *data)
314/** 314/**
315 * reap 1 frame from @swhead 315 * reap 1 frame from @swhead
316 * 316 *
317 * Rx descriptor copied to skb->cb
318 *
317 * Safe to call from IRQ 319 * Safe to call from IRQ
318 */ 320 */
319static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, 321static 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 struct device *dev = wil_to_dev(wil); 324 struct device *dev = wil_to_dev(wil);
323 struct net_device *ndev = wil_to_ndev(wil); 325 struct net_device *ndev = wil_to_ndev(wil);
324 volatile struct vring_rx_desc *d; 326 volatile struct vring_rx_desc *d;
327 struct vring_rx_desc *d1;
325 struct sk_buff *skb; 328 struct sk_buff *skb;
326 dma_addr_t pa; 329 dma_addr_t pa;
327 unsigned int sz = RX_BUF_LEN; 330 unsigned int sz = RX_BUF_LEN;
328 u8 ftype; 331 u8 ftype;
329 u8 ds_bits; 332 u8 ds_bits;
330 333
334 BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb));
335
331 if (wil_vring_is_empty(vring)) 336 if (wil_vring_is_empty(vring))
332 return NULL; 337 return NULL;
333 338
@@ -342,11 +347,14 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
342 dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE); 347 dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE);
343 skb_trim(skb, d->dma.length); 348 skb_trim(skb, d->dma.length);
344 349
345 wil->stats.last_mcs_rx = wil_rxdesc_mcs(d); 350 d1 = wil_skb_rxdesc(skb);
351 *d1 = *d;
352
353 wil->stats.last_mcs_rx = wil_rxdesc_mcs(d1);
346 354
347 /* use radiotap header only if required */ 355 /* use radiotap header only if required */
348 if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) 356 if (ndev->type == ARPHRD_IEEE80211_RADIOTAP)
349 wil_rx_add_radiotap_header(wil, skb, d); 357 wil_rx_add_radiotap_header(wil, skb);
350 358
351 wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length); 359 wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length);
352 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4, 360 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 * Driver should recognize it by frame type, that is found 370 * Driver should recognize it by frame type, that is found
363 * in Rx descriptor. If type is not data, it is 802.11 frame as is 371 * in Rx descriptor. If type is not data, it is 802.11 frame as is
364 */ 372 */
365 ftype = wil_rxdesc_ftype(d) << 2; 373 ftype = wil_rxdesc_ftype(d1) << 2;
366 if (ftype != IEEE80211_FTYPE_DATA) { 374 if (ftype != IEEE80211_FTYPE_DATA) {
367 wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype); 375 wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype);
368 /* TODO: process it */ 376 /* TODO: process it */
@@ -377,7 +385,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
377 return NULL; 385 return NULL;
378 } 386 }
379 387
380 ds_bits = wil_rxdesc_ds_bits(d); 388 ds_bits = wil_rxdesc_ds_bits(d1);
381 if (ds_bits == 1) { 389 if (ds_bits == 1) {
382 /* 390 /*
383 * HW bug - in ToDS mode, i.e. Rx on AP side, 391 * HW bug - in ToDS mode, i.e. Rx on AP side,
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index 45a61f597c5c..f0cc48afd861 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -339,24 +339,29 @@ union vring_desc {
339 struct vring_rx_desc rx; 339 struct vring_rx_desc rx;
340} __packed; 340} __packed;
341 341
342static inline int wil_rxdesc_phy_length(volatile struct vring_rx_desc *d) 342static inline int wil_rxdesc_phy_length(struct vring_rx_desc *d)
343{ 343{
344 return WIL_GET_BITS(d->dma.d0, 16, 29); 344 return WIL_GET_BITS(d->dma.d0, 16, 29);
345} 345}
346 346
347static inline int wil_rxdesc_mcs(volatile struct vring_rx_desc *d) 347static inline int wil_rxdesc_mcs(struct vring_rx_desc *d)
348{ 348{
349 return WIL_GET_BITS(d->mac.d1, 21, 24); 349 return WIL_GET_BITS(d->mac.d1, 21, 24);
350} 350}
351 351
352static inline int wil_rxdesc_ds_bits(volatile struct vring_rx_desc *d) 352static inline int wil_rxdesc_ds_bits(struct vring_rx_desc *d)
353{ 353{
354 return WIL_GET_BITS(d->mac.d1, 8, 9); 354 return WIL_GET_BITS(d->mac.d1, 8, 9);
355} 355}
356 356
357static inline int wil_rxdesc_ftype(volatile struct vring_rx_desc *d) 357static inline int wil_rxdesc_ftype(struct vring_rx_desc *d)
358{ 358{
359 return WIL_GET_BITS(d->mac.d0, 10, 11); 359 return WIL_GET_BITS(d->mac.d0, 10, 11);
360} 360}
361 361
362static inline struct vring_rx_desc *wil_skb_rxdesc(struct sk_buff *skb)
363{
364 return (void *)skb->cb;
365}
366
362#endif /* WIL6210_TXRX_H */ 367#endif /* WIL6210_TXRX_H */