aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>2015-03-15 10:00:19 -0400
committerKalle Valo <kvalo@codeaurora.org>2015-03-20 02:33:19 -0400
commitc406ea7c7406f00aa1fb6c697d47d070fd222037 (patch)
tree6d47a0202ed18a8219011422c81de335be8ff25b /drivers/net/wireless/ath
parentcec94d8cf5c2e5347ed9264cc94210e6376c7a46 (diff)
wil6210: Align Rx frames on 4*n+2 by having SNAP
For the networking code and for hardware network accelerators, it is better to have IP header 4*n aligned. On the other side, DMA on Rx path require buffer to be aligned on 4*n as well. Having 14 bytes of Ethernet header, these 2 alignment requests are in contradiction. To solve this, order hardware offload block to not remove SNAP header. This adds extra 6 bytes between addresses and ethertype, making it 20 bytes total. This way, both buffer and IP header are 4*n aligned. Remaining is only to remove SNAP by shifting addresses 6 bytes. This involves data copying, so this feature should be disabled unless required by the platform. Module parameter "rx_align_2" (bool, default - false) introduced to control this feature. Feature is completely disabled when parameter is false. Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c27
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h1
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c5
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.h3
4 files changed, 33 insertions, 3 deletions
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 3feb86c47795..2453470bc191 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -33,6 +33,15 @@ module_param(rtap_include_phy_info, bool, S_IRUGO);
33MODULE_PARM_DESC(rtap_include_phy_info, 33MODULE_PARM_DESC(rtap_include_phy_info,
34 " Include PHY info in the radiotap header, default - no"); 34 " Include PHY info in the radiotap header, default - no");
35 35
36bool rx_align_2;
37module_param(rx_align_2, bool, S_IRUGO);
38MODULE_PARM_DESC(rx_align_2, " align Rx buffers on 4*n+2, default - no");
39
40static inline uint wil_rx_snaplen(void)
41{
42 return rx_align_2 ? 6 : 0;
43}
44
36static inline int wil_vring_is_empty(struct vring *vring) 45static inline int wil_vring_is_empty(struct vring *vring)
37{ 46{
38 return vring->swhead == vring->swtail; 47 return vring->swhead == vring->swtail;
@@ -209,7 +218,7 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring,
209 u32 i, int headroom) 218 u32 i, int headroom)
210{ 219{
211 struct device *dev = wil_to_dev(wil); 220 struct device *dev = wil_to_dev(wil);
212 unsigned int sz = mtu_max + ETH_HLEN; 221 unsigned int sz = mtu_max + ETH_HLEN + wil_rx_snaplen();
213 struct vring_rx_desc dd, *d = &dd; 222 struct vring_rx_desc dd, *d = &dd;
214 volatile struct vring_rx_desc *_d = &vring->va[i].rx; 223 volatile struct vring_rx_desc *_d = &vring->va[i].rx;
215 dma_addr_t pa; 224 dma_addr_t pa;
@@ -365,7 +374,8 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
365 struct vring_rx_desc *d; 374 struct vring_rx_desc *d;
366 struct sk_buff *skb; 375 struct sk_buff *skb;
367 dma_addr_t pa; 376 dma_addr_t pa;
368 unsigned int sz = mtu_max + ETH_HLEN; 377 unsigned int snaplen = wil_rx_snaplen();
378 unsigned int sz = mtu_max + ETH_HLEN + snaplen;
369 u16 dmalen; 379 u16 dmalen;
370 u8 ftype; 380 u8 ftype;
371 int cid; 381 int cid;
@@ -438,7 +448,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
438 return NULL; 448 return NULL;
439 } 449 }
440 450
441 if (unlikely(skb->len < ETH_HLEN)) { 451 if (unlikely(skb->len < ETH_HLEN + snaplen)) {
442 wil_err(wil, "Short frame, len = %d\n", skb->len); 452 wil_err(wil, "Short frame, len = %d\n", skb->len);
443 /* TODO: process it (i.e. BAR) */ 453 /* TODO: process it (i.e. BAR) */
444 kfree_skb(skb); 454 kfree_skb(skb);
@@ -460,6 +470,17 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
460 */ 470 */
461 } 471 }
462 472
473 if (snaplen) {
474 /* Packet layout
475 * +-------+-------+---------+------------+------+
476 * | SA(6) | DA(6) | SNAP(6) | ETHTYPE(2) | DATA |
477 * +-------+-------+---------+------------+------+
478 * Need to remove SNAP, shifting SA and DA forward
479 */
480 memmove(skb->data + snaplen, skb->data, 2 * ETH_ALEN);
481 skb_pull(skb, snaplen);
482 }
483
463 return skb; 484 return skb;
464} 485}
465 486
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index c1a71ab75a0e..a6b096eb7dee 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -28,6 +28,7 @@ extern unsigned int mtu_max;
28extern unsigned short rx_ring_overflow_thrsh; 28extern unsigned short rx_ring_overflow_thrsh;
29extern int agg_wsize; 29extern int agg_wsize;
30extern u32 vring_idle_trsh; 30extern u32 vring_idle_trsh;
31extern bool rx_align_2;
31 32
32#define WIL_NAME "wil6210" 33#define WIL_NAME "wil6210"
33#define WIL_FW_NAME "wil6210.fw" /* code */ 34#define WIL_FW_NAME "wil6210.fw" /* code */
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 021313524913..8c18a46582db 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -1109,6 +1109,11 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
1109 */ 1109 */
1110 cmd.l3_l4_ctrl |= (1 << L3_L4_CTRL_TCPIP_CHECKSUM_EN_POS); 1110 cmd.l3_l4_ctrl |= (1 << L3_L4_CTRL_TCPIP_CHECKSUM_EN_POS);
1111 } 1111 }
1112
1113 if (rx_align_2)
1114 cmd.l2_802_3_offload_ctrl |=
1115 L2_802_3_OFFLOAD_CTRL_SNAP_KEEP_MSK;
1116
1112 /* typical time for secure PCP is 840ms */ 1117 /* typical time for secure PCP is 840ms */
1113 rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd), 1118 rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd),
1114 WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000); 1119 WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h
index 8a4af613e191..0979650e675d 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -687,6 +687,9 @@ struct wmi_cfg_rx_chain_cmd {
687 #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_POS (0) 687 #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_POS (0)
688 #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_LEN (1) 688 #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_LEN (1)
689 #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_MSK (0x1) 689 #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_MSK (0x1)
690 #define L2_802_3_OFFLOAD_CTRL_SNAP_KEEP_POS (1)
691 #define L2_802_3_OFFLOAD_CTRL_SNAP_KEEP_LEN (1)
692 #define L2_802_3_OFFLOAD_CTRL_SNAP_KEEP_MSK (0x2)
690 u8 l2_802_3_offload_ctrl; 693 u8 l2_802_3_offload_ctrl;
691 694
692 #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_QOS_POS (0) 695 #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_QOS_POS (0)