aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorYogesh Ashok Powar <yogeshp@marvell.com>2011-04-28 08:04:48 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-29 15:36:15 -0400
commitff776cecec92fe7cac4a9ce1919576ad6e737e08 (patch)
tree16db08ea4e9a894592780cd6b58d4fa9c77f1e51 /drivers
parentd244f21e79162b829c9af09845421d9b4fac4253 (diff)
mwl8k: Reducing extra_tx_headroom for tx optimization in AP mode
The tx_headroom required for mwl8k driver is 32 bytes and it can use the space for 802.11 header received from mac80211. mwl8k considers the smallest 802.11 frame (CTS2self of 10 bytes) that can be received from mac80211 to compute the extra_tx_headroom as 22 (32 - 10) bytes. When the wireless interface is part of bridge, this extra_tx_headroom requirement results in a memcpy in mac80211 (in function pskb_expand_head) for all the data frames needing L2 forwarding/bridging, when NET_SKB_PAD is defined as 32. This patch reduces the extra_tx_headroom by 8 bytes so that memcpy of data frames in mac80211 is avoided in this case. The resize will be required in driver for frames with 802.11 header size of less than 18 bytes. Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com> Signed-off-by: Pradeep Nemavat <pnemavat@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/mwl8k.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 8a1b26255f03..9f5ecef297e5 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -781,8 +781,10 @@ static inline void mwl8k_remove_dma_header(struct sk_buff *skb, __le16 qos)
781 skb_pull(skb, sizeof(*tr) - hdrlen); 781 skb_pull(skb, sizeof(*tr) - hdrlen);
782} 782}
783 783
784#define REDUCED_TX_HEADROOM 8
785
784static void 786static void
785mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad) 787mwl8k_add_dma_header(struct mwl8k_priv *priv, struct sk_buff *skb, int tail_pad)
786{ 788{
787 struct ieee80211_hdr *wh; 789 struct ieee80211_hdr *wh;
788 int hdrlen; 790 int hdrlen;
@@ -798,6 +800,22 @@ mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad)
798 wh = (struct ieee80211_hdr *)skb->data; 800 wh = (struct ieee80211_hdr *)skb->data;
799 801
800 hdrlen = ieee80211_hdrlen(wh->frame_control); 802 hdrlen = ieee80211_hdrlen(wh->frame_control);
803
804 /*
805 * Check if skb_resize is required because of
806 * tx_headroom adjustment.
807 */
808 if (priv->ap_fw && (hdrlen < (sizeof(struct ieee80211_cts)
809 + REDUCED_TX_HEADROOM))) {
810 if (pskb_expand_head(skb, REDUCED_TX_HEADROOM, 0, GFP_ATOMIC)) {
811
812 wiphy_err(priv->hw->wiphy,
813 "Failed to reallocate TX buffer\n");
814 return;
815 }
816 skb->truesize += REDUCED_TX_HEADROOM;
817 }
818
801 reqd_hdrlen = sizeof(*tr); 819 reqd_hdrlen = sizeof(*tr);
802 820
803 if (hdrlen != reqd_hdrlen) 821 if (hdrlen != reqd_hdrlen)
@@ -820,7 +838,8 @@ mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad)
820 tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad); 838 tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad);
821} 839}
822 840
823static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb) 841static void mwl8k_encapsulate_tx_frame(struct mwl8k_priv *priv,
842 struct sk_buff *skb)
824{ 843{
825 struct ieee80211_hdr *wh; 844 struct ieee80211_hdr *wh;
826 struct ieee80211_tx_info *tx_info; 845 struct ieee80211_tx_info *tx_info;
@@ -861,7 +880,7 @@ static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
861 break; 880 break;
862 } 881 }
863 } 882 }
864 mwl8k_add_dma_header(skb, data_pad); 883 mwl8k_add_dma_header(priv, skb, data_pad);
865} 884}
866 885
867/* 886/*
@@ -1816,9 +1835,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1816 mgmtframe = true; 1835 mgmtframe = true;
1817 1836
1818 if (priv->ap_fw) 1837 if (priv->ap_fw)
1819 mwl8k_encapsulate_tx_frame(skb); 1838 mwl8k_encapsulate_tx_frame(priv, skb);
1820 else 1839 else
1821 mwl8k_add_dma_header(skb, 0); 1840 mwl8k_add_dma_header(priv, skb, 0);
1822 1841
1823 wh = &((struct mwl8k_dma_data *)skb->data)->wh; 1842 wh = &((struct mwl8k_dma_data *)skb->data)->wh;
1824 1843
@@ -5474,6 +5493,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
5474 hw->extra_tx_headroom = 5493 hw->extra_tx_headroom =
5475 sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts); 5494 sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts);
5476 5495
5496 hw->extra_tx_headroom -= priv->ap_fw ? REDUCED_TX_HEADROOM : 0;
5497
5477 hw->channel_change_time = 10; 5498 hw->channel_change_time = 10;
5478 5499
5479 hw->queues = MWL8K_TX_WMM_QUEUES; 5500 hw->queues = MWL8K_TX_WMM_QUEUES;