Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84b313b3 authored by Xinming Hu's avatar Xinming Hu Committed by Kalle Valo
Browse files

mwifiex: make tx packet 64 byte DMA aligned



This patch adds support for DMA alignment of 64 bytes for TX packets.

Signed-off-by: default avatarXinming Hu <huxm@marvell.com>
Signed-off-by: default avatarAvinash Patil <patila@marvell.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 2ab87d5d
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -101,6 +101,13 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
{
	struct txpd *local_tx_pd;
	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));

@@ -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_type = priv->bss_type;
	/* 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_length = cpu_to_le16(skb->len -
						 sizeof(*local_tx_pd));
						 sizeof(*local_tx_pd) -
						 pad);

	if (tx_info->flags & MWIFIEX_BUF_FLAG_TDLS_PKT)
		local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_TDLS_PACKET;
@@ -182,7 +191,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
				       ra_list_flags);
		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);

	memset(tx_info_aggr, 0, sizeof(*tx_info_aggr));
+6 −3
Original line number Diff line number Diff line
@@ -32,9 +32,12 @@

#define MWIFIEX_MAX_BSS_NUM         (3)

#define MWIFIEX_MIN_DATA_HEADER_LEN 36	/* sizeof(mwifiex_txpd)
					 *   + 4 byte alignment
					 */
#define MWIFIEX_DMA_ALIGN_SZ	    64
#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)
						 *   + sizeof(tx_control)
						 */
+10 −9
Original line number Diff line number Diff line
@@ -47,8 +47,10 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
	struct mwifiex_adapter *adapter = priv->adapter;
	struct txpd *local_tx_pd;
	struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
	u8 pad;
	unsigned int pad;
	u16 pkt_type, pkt_offset;
	int hroom = (priv->adapter->iface_type == MWIFIEX_USB) ? 0 :
		       INTF_HEADER_LEN;

	if (!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;
	}

	pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;
	BUG_ON(skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN);

	/* If skb->data is not aligned; add padding */
	pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4;
	pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;

	BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN
				    + pad));
	pad = ((void *)skb->data - (sizeof(*local_tx_pd) + hroom)-
			 NULL) & (MWIFIEX_DMA_ALIGN_SZ - 1);
	skb_push(skb, sizeof(*local_tx_pd) + pad);

	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_type = priv->bss_type;
	local_tx_pd->tx_pkt_length = cpu_to_le16((u16)(skb->len -
						       (sizeof(struct txpd)
							+ pad)));
						       (sizeof(struct txpd) +
							pad)));

	local_tx_pd->priority = (u8) skb->priority;
	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);

	/* make space for INTF_HEADER_LEN */
	skb_push(skb, INTF_HEADER_LEN);
	skb_push(skb, hroom);

	if (!local_tx_pd->tx_control)
		/* TxCtrl set by user or default */
+15 −13
Original line number Diff line number Diff line
@@ -348,8 +348,10 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
	struct mwifiex_adapter *adapter = priv->adapter;
	struct uap_txpd *txpd;
	struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
	int pad, len;
	u16 pkt_type;
	int pad;
	u16 pkt_type, pkt_offset;
	int hroom = (priv->adapter->iface_type == MWIFIEX_USB) ? 0 :
		       INTF_HEADER_LEN;

	if (!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;
	}

	pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;

	/* If skb->data is not aligned, add padding */
	pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4;
	BUG_ON(skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN);

	len = sizeof(*txpd) + pad;
	pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;

	BUG_ON(skb_headroom(skb) < len + INTF_HEADER_LEN);
	pad = ((void *)skb->data - (sizeof(*txpd) + hroom) - NULL) &
			(MWIFIEX_DMA_ALIGN_SZ - 1);

	skb_push(skb, len);
	skb_push(skb, sizeof(*txpd) + pad);

	txpd = (struct uap_txpd *)skb->data;
	memset(txpd, 0, sizeof(*txpd));
	txpd->bss_num = priv->bss_num;
	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->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]);

	/* Offset of actual data */
	pkt_offset = sizeof(*txpd) + pad;
	if (pkt_type == PKT_TYPE_MGMT) {
		/* Set the packet type and add header for management frame */
		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 */
	skb_push(skb, INTF_HEADER_LEN);
	skb_push(skb, hroom);

	if (!txpd->tx_control)
		/* TxCtrl set by user or default */