diff options
author | Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> | 2013-04-18 07:33:50 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-04-22 15:20:24 -0400 |
commit | 33e611690e6478ebb095e4eb755010343374a2a3 (patch) | |
tree | 354bf88b9fb2581263085687af9c7cddf30318c9 | |
parent | 047445c579dc28772aadaac6b7b37289aad72b22 (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.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/txrx.h | 13 |
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 | */ |
195 | static void wil_rx_add_radiotap_header(struct wil6210_priv *wil, | 195 | static 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 | */ |
319 | static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, | 321 | 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 | 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 | ||
342 | static inline int wil_rxdesc_phy_length(volatile struct vring_rx_desc *d) | 342 | static 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 | ||
347 | static inline int wil_rxdesc_mcs(volatile struct vring_rx_desc *d) | 347 | static 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 | ||
352 | static inline int wil_rxdesc_ds_bits(volatile struct vring_rx_desc *d) | 352 | static 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 | ||
357 | static inline int wil_rxdesc_ftype(volatile struct vring_rx_desc *d) | 357 | static 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 | ||
362 | static 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 */ |