mwifiex: DMA alignment for RX packets
authorAvinash Patil <patila@marvell.com>
Fri, 13 Feb 2015 12:11:08 +0000 (17:41 +0530)
committerKalle Valo <kvalo@codeaurora.org>
Fri, 27 Feb 2015 08:12:44 +0000 (10:12 +0200)
This patch adds support for DMA alignment of sk_buffs
allocated for RX.
Patch also adds support to modify skb allocation flags.

Signed-off-by: Marc Yang <yangyang@marvell.com>
Signed-off-by: Qingshui Gao <gaoqs@marvell.com>
Signed-off-by: Cathy Luo <cluo@marvell.com>
Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/mwifiex/decl.h
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/pcie.c
drivers/net/wireless/mwifiex/sdio.c
drivers/net/wireless/mwifiex/util.c

index 88d0eade6bb128565def33ab001cdb01c864b040..cf2fa110e2514f4e56798768463d57970c1481d6 100644 (file)
@@ -33,6 +33,7 @@
 #define MWIFIEX_MAX_BSS_NUM         (3)
 
 #define MWIFIEX_DMA_ALIGN_SZ       64
+#define MWIFIEX_RX_HEADROOM        64
 #define MAX_TXPD_SZ                32
 #define INTF_HDR_ALIGN              4
 
index 2089a30840435acce5ec41209da78242da869cf2..16be45e9a66acb2d853b5d26c133411ddaf3c378 100644 (file)
@@ -140,6 +140,9 @@ enum {
 
 #define MWIFIEX_DRV_INFO_SIZE_MAX 0x40000
 
+/* Address alignment */
+#define MWIFIEX_ALIGN_ADDR(p, a) (((long)(p) + (a) - 1) & ~((a) - 1))
+
 struct mwifiex_dbg {
        u32 num_cmd_host_to_card_failure;
        u32 num_cmd_sleep_cfm_host_to_card_failure;
@@ -1418,6 +1421,7 @@ u8 mwifiex_adjust_data_rate(struct mwifiex_private *priv,
                            u8 rx_rate, u8 ht_info);
 
 void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter);
+void *mwifiex_alloc_rx_buf(int rx_len, gfp_t flags);
 
 #ifdef CONFIG_DEBUG_FS
 void mwifiex_debugfs_init(void);
index 0640bd67077cdeb9eb1bb85e864f39a7856694a2..4b463c3b99064904ba15c8503cc6f922cfe345ef 100644 (file)
@@ -498,7 +498,8 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
 
        for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
                /* Allocate skb here so that firmware can DMA data from it */
-               skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
+               skb = mwifiex_alloc_rx_buf(MWIFIEX_RX_DATA_BUF_SIZE,
+                                          GFP_KERNEL | GFP_DMA);
                if (!skb) {
                        dev_err(adapter->dev,
                                "Unable to allocate skb for RX ring.\n");
@@ -1297,7 +1298,8 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
                        }
                }
 
-               skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
+               skb_tmp = mwifiex_alloc_rx_buf(MWIFIEX_RX_DATA_BUF_SIZE,
+                                              GFP_KERNEL | GFP_DMA);
                if (!skb_tmp) {
                        dev_err(adapter->dev,
                                "Unable to allocate skb.\n");
index 78a9e863a9345628bb8e4ccecd51bad61716128e..57d85ab442bf3f2569d7ffd434a2b7e45bb314d8 100644 (file)
@@ -1357,7 +1357,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
                        return -1;
                rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
 
-               skb = dev_alloc_skb(rx_len);
+               skb = mwifiex_alloc_rx_buf(rx_len, GFP_KERNEL | GFP_DMA);
                if (!skb)
                        return -1;
 
@@ -1454,7 +1454,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
                        }
                        rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
 
-                       skb = dev_alloc_skb(rx_len);
+                       skb = mwifiex_alloc_rx_buf(rx_len,
+                                                  GFP_KERNEL | GFP_DMA);
 
                        if (!skb) {
                                dev_err(adapter->dev, "%s: failed to alloc skb",
index 47e215b6d5f5925a9628de18b3b962117f18087b..2148a573396b8dfcbcf2dba17843cace3af250a6 100644 (file)
@@ -631,3 +631,26 @@ void mwifiex_hist_data_reset(struct mwifiex_private *priv)
        for (ix = 0; ix < MWIFIEX_MAX_SIG_STRENGTH; ix++)
                atomic_set(&phist_data->sig_str[ix], 0);
 }
+
+void *mwifiex_alloc_rx_buf(int rx_len, gfp_t flags)
+{
+       struct sk_buff *skb;
+       int buf_len, pad;
+
+       buf_len = rx_len + MWIFIEX_RX_HEADROOM + MWIFIEX_DMA_ALIGN_SZ;
+
+       skb = __dev_alloc_skb(buf_len, flags);
+
+       if (!skb)
+               return NULL;
+
+       skb_reserve(skb, MWIFIEX_RX_HEADROOM);
+
+       pad = MWIFIEX_ALIGN_ADDR(skb->data, MWIFIEX_DMA_ALIGN_SZ) -
+             (long)skb->data;
+
+       skb_reserve(skb, pad);
+
+       return skb;
+}
+EXPORT_SYMBOL_GPL(mwifiex_alloc_rx_buf);