mwifiex: 4-byte alignment in mwifiex_process_sta_txpd()

In XMIT path, the skb that we get from the kernel itself is not
aligned with 4-byte boundary on some embedded platforms.

Had it not been the presence of tx_pkt_offset field in txpd, 4 byte
memory alignment was not possible without memmove of entire skb.
And that would have increased MIPS instead of reducing.

With this patch few memory cycles can be saved while fetching
interface header and txpd structure because of 4 bytes memory
alignment.

Reported-by: Philip Rakity <prakity@marvell.com>
Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com>
Tested-by: Philip Rakity <prakity@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Yogesh Ashok Powar 2011-07-07 17:37:09 -07:00 committed by John W. Linville
parent 38869d79e5
commit e156103cee
2 changed files with 12 additions and 5 deletions

View File

@ -30,7 +30,9 @@
#define MWIFIEX_MAX_BSS_NUM (1) #define MWIFIEX_MAX_BSS_NUM (1)
#define MWIFIEX_MIN_DATA_HEADER_LEN 32 /* (sizeof(mwifiex_txpd)) */ #define MWIFIEX_MIN_DATA_HEADER_LEN 36 /* sizeof(mwifiex_txpd)
* + 4 byte alignment
*/
#define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2 #define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2
#define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16 #define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16

View File

@ -47,6 +47,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_adapter *adapter = priv->adapter;
struct txpd *local_tx_pd; struct txpd *local_tx_pd;
struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
u8 pad;
if (!skb->len) { if (!skb->len) {
dev_err(adapter->dev, "Tx: bad packet length: %d\n", dev_err(adapter->dev, "Tx: bad packet length: %d\n",
@ -55,15 +56,19 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
return skb->data; return skb->data;
} }
BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN)); /* If skb->data is not aligned; add padding */
skb_push(skb, sizeof(*local_tx_pd)); pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4;
BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN
+ pad));
skb_push(skb, sizeof(*local_tx_pd) + pad);
local_tx_pd = (struct txpd *) skb->data; local_tx_pd = (struct txpd *) skb->data;
memset(local_tx_pd, 0, sizeof(struct txpd)); memset(local_tx_pd, 0, sizeof(struct txpd));
local_tx_pd->bss_num = priv->bss_num; local_tx_pd->bss_num = priv->bss_num;
local_tx_pd->bss_type = priv->bss_type; local_tx_pd->bss_type = priv->bss_type;
local_tx_pd->tx_pkt_length = cpu_to_le16((u16) (skb->len - local_tx_pd->tx_pkt_length = cpu_to_le16((u16) (skb->len -
sizeof(struct txpd))); (sizeof(struct txpd) + pad)));
local_tx_pd->priority = (u8) skb->priority; local_tx_pd->priority = (u8) skb->priority;
local_tx_pd->pkt_delay_2ms = local_tx_pd->pkt_delay_2ms =
@ -88,7 +93,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
} }
/* Offset of actual data */ /* Offset of actual data */
local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd)); local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd) + pad);
/* make space for INTF_HEADER_LEN */ /* make space for INTF_HEADER_LEN */
skb_push(skb, INTF_HEADER_LEN); skb_push(skb, INTF_HEADER_LEN);