mwifiex: make tx packet 64 byte DMA aligned
This patch adds support for DMA alignment of 64 bytes for TX packets. Signed-off-by: Xinming Hu <huxm@marvell.com> Signed-off-by: Avinash Patil <patila@marvell.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
2ab87d5d67
commit
84b313b35f
@ -101,6 +101,13 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
|
|||||||
{
|
{
|
||||||
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);
|
||||||
|
unsigned int pad;
|
||||||
|
int headroom = (priv->adapter->iface_type ==
|
||||||
|
MWIFIEX_USB) ? 0 : INTF_HEADER_LEN;
|
||||||
|
|
||||||
|
pad = ((void *)skb->data - sizeof(*local_tx_pd) -
|
||||||
|
headroom - NULL) & (MWIFIEX_DMA_ALIGN_SZ - 1);
|
||||||
|
skb_push(skb, pad);
|
||||||
|
|
||||||
skb_push(skb, sizeof(*local_tx_pd));
|
skb_push(skb, sizeof(*local_tx_pd));
|
||||||
|
|
||||||
@ -114,10 +121,12 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
|
|||||||
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;
|
||||||
/* Always zero as the data is followed by struct txpd */
|
/* Always zero as the data is followed by struct txpd */
|
||||||
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);
|
||||||
local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU);
|
local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU);
|
||||||
local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len -
|
local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len -
|
||||||
sizeof(*local_tx_pd));
|
sizeof(*local_tx_pd) -
|
||||||
|
pad);
|
||||||
|
|
||||||
if (tx_info->flags & MWIFIEX_BUF_FLAG_TDLS_PKT)
|
if (tx_info->flags & MWIFIEX_BUF_FLAG_TDLS_PKT)
|
||||||
local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_TDLS_PACKET;
|
local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_TDLS_PACKET;
|
||||||
@ -182,7 +191,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
|||||||
ra_list_flags);
|
ra_list_flags);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
|
skb_reserve(skb_aggr, MWIFIEX_MIN_DATA_HEADER_LEN);
|
||||||
tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr);
|
tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr);
|
||||||
|
|
||||||
memset(tx_info_aggr, 0, sizeof(*tx_info_aggr));
|
memset(tx_info_aggr, 0, sizeof(*tx_info_aggr));
|
||||||
|
@ -32,9 +32,12 @@
|
|||||||
|
|
||||||
#define MWIFIEX_MAX_BSS_NUM (3)
|
#define MWIFIEX_MAX_BSS_NUM (3)
|
||||||
|
|
||||||
#define MWIFIEX_MIN_DATA_HEADER_LEN 36 /* sizeof(mwifiex_txpd)
|
#define MWIFIEX_DMA_ALIGN_SZ 64
|
||||||
* + 4 byte alignment
|
#define MAX_TXPD_SZ 32
|
||||||
*/
|
#define INTF_HDR_ALIGN 4
|
||||||
|
|
||||||
|
#define MWIFIEX_MIN_DATA_HEADER_LEN (MWIFIEX_DMA_ALIGN_SZ + INTF_HDR_ALIGN + \
|
||||||
|
MAX_TXPD_SZ)
|
||||||
#define MWIFIEX_MGMT_FRAME_HEADER_SIZE 8 /* sizeof(pkt_type)
|
#define MWIFIEX_MGMT_FRAME_HEADER_SIZE 8 /* sizeof(pkt_type)
|
||||||
* + sizeof(tx_control)
|
* + sizeof(tx_control)
|
||||||
*/
|
*/
|
||||||
|
@ -47,8 +47,10 @@ 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;
|
unsigned int pad;
|
||||||
u16 pkt_type, pkt_offset;
|
u16 pkt_type, pkt_offset;
|
||||||
|
int hroom = (priv->adapter->iface_type == MWIFIEX_USB) ? 0 :
|
||||||
|
INTF_HEADER_LEN;
|
||||||
|
|
||||||
if (!skb->len) {
|
if (!skb->len) {
|
||||||
dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len);
|
dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len);
|
||||||
@ -56,13 +58,12 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
|
|||||||
return skb->data;
|
return skb->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BUG_ON(skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN);
|
||||||
|
|
||||||
pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;
|
pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;
|
||||||
|
|
||||||
/* If skb->data is not aligned; add padding */
|
pad = ((void *)skb->data - (sizeof(*local_tx_pd) + hroom)-
|
||||||
pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4;
|
NULL) & (MWIFIEX_DMA_ALIGN_SZ - 1);
|
||||||
|
|
||||||
BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN
|
|
||||||
+ pad));
|
|
||||||
skb_push(skb, sizeof(*local_tx_pd) + pad);
|
skb_push(skb, sizeof(*local_tx_pd) + pad);
|
||||||
|
|
||||||
local_tx_pd = (struct txpd *) skb->data;
|
local_tx_pd = (struct txpd *) skb->data;
|
||||||
@ -70,8 +71,8 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
|
|||||||
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)));
|
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 =
|
||||||
@ -115,7 +116,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
|
|||||||
local_tx_pd->tx_pkt_offset = cpu_to_le16(pkt_offset);
|
local_tx_pd->tx_pkt_offset = cpu_to_le16(pkt_offset);
|
||||||
|
|
||||||
/* make space for INTF_HEADER_LEN */
|
/* make space for INTF_HEADER_LEN */
|
||||||
skb_push(skb, INTF_HEADER_LEN);
|
skb_push(skb, hroom);
|
||||||
|
|
||||||
if (!local_tx_pd->tx_control)
|
if (!local_tx_pd->tx_control)
|
||||||
/* TxCtrl set by user or default */
|
/* TxCtrl set by user or default */
|
||||||
|
@ -348,8 +348,10 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
|
|||||||
struct mwifiex_adapter *adapter = priv->adapter;
|
struct mwifiex_adapter *adapter = priv->adapter;
|
||||||
struct uap_txpd *txpd;
|
struct uap_txpd *txpd;
|
||||||
struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
|
struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
|
||||||
int pad, len;
|
int pad;
|
||||||
u16 pkt_type;
|
u16 pkt_type, pkt_offset;
|
||||||
|
int hroom = (priv->adapter->iface_type == MWIFIEX_USB) ? 0 :
|
||||||
|
INTF_HEADER_LEN;
|
||||||
|
|
||||||
if (!skb->len) {
|
if (!skb->len) {
|
||||||
dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len);
|
dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len);
|
||||||
@ -357,22 +359,21 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
|
|||||||
return skb->data;
|
return skb->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BUG_ON(skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN);
|
||||||
|
|
||||||
pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;
|
pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;
|
||||||
|
|
||||||
/* If skb->data is not aligned, add padding */
|
pad = ((void *)skb->data - (sizeof(*txpd) + hroom) - NULL) &
|
||||||
pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4;
|
(MWIFIEX_DMA_ALIGN_SZ - 1);
|
||||||
|
|
||||||
len = sizeof(*txpd) + pad;
|
skb_push(skb, sizeof(*txpd) + pad);
|
||||||
|
|
||||||
BUG_ON(skb_headroom(skb) < len + INTF_HEADER_LEN);
|
|
||||||
|
|
||||||
skb_push(skb, len);
|
|
||||||
|
|
||||||
txpd = (struct uap_txpd *)skb->data;
|
txpd = (struct uap_txpd *)skb->data;
|
||||||
memset(txpd, 0, sizeof(*txpd));
|
memset(txpd, 0, sizeof(*txpd));
|
||||||
txpd->bss_num = priv->bss_num;
|
txpd->bss_num = priv->bss_num;
|
||||||
txpd->bss_type = priv->bss_type;
|
txpd->bss_type = priv->bss_type;
|
||||||
txpd->tx_pkt_length = cpu_to_le16((u16)(skb->len - len));
|
txpd->tx_pkt_length = cpu_to_le16((u16)(skb->len - (sizeof(*txpd) +
|
||||||
|
pad)));
|
||||||
txpd->priority = (u8)skb->priority;
|
txpd->priority = (u8)skb->priority;
|
||||||
|
|
||||||
txpd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
|
txpd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
|
||||||
@ -392,16 +393,17 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
|
|||||||
cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[txpd->priority]);
|
cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[txpd->priority]);
|
||||||
|
|
||||||
/* Offset of actual data */
|
/* Offset of actual data */
|
||||||
|
pkt_offset = sizeof(*txpd) + pad;
|
||||||
if (pkt_type == PKT_TYPE_MGMT) {
|
if (pkt_type == PKT_TYPE_MGMT) {
|
||||||
/* Set the packet type and add header for management frame */
|
/* Set the packet type and add header for management frame */
|
||||||
txpd->tx_pkt_type = cpu_to_le16(pkt_type);
|
txpd->tx_pkt_type = cpu_to_le16(pkt_type);
|
||||||
len += MWIFIEX_MGMT_FRAME_HEADER_SIZE;
|
pkt_offset += MWIFIEX_MGMT_FRAME_HEADER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
txpd->tx_pkt_offset = cpu_to_le16(len);
|
txpd->tx_pkt_offset = cpu_to_le16(pkt_offset);
|
||||||
|
|
||||||
/* make space for INTF_HEADER_LEN */
|
/* make space for INTF_HEADER_LEN */
|
||||||
skb_push(skb, INTF_HEADER_LEN);
|
skb_push(skb, hroom);
|
||||||
|
|
||||||
if (!txpd->tx_control)
|
if (!txpd->tx_control)
|
||||||
/* TxCtrl set by user or default */
|
/* TxCtrl set by user or default */
|
||||||
|
Loading…
Reference in New Issue
Block a user