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

Commit 6f266e91 authored by Arik Nemtsov's avatar Arik Nemtsov Committed by Luciano Coelho
Browse files

wlcore/wl12xx: add hw op for setting frame length in tx_hw_desc



Each chip family indicates the length of a frame to the HW differently.
This includes different padding, alignment and other fields in the HW Tx
descriptor.

Put all wl12xx specific code in a hw op.

Signed-off-by: default avatarArik Nemtsov <arik@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent 4a3b97ee
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -609,6 +609,41 @@ wl12xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
	}
}

static void
wl12xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
			    struct sk_buff *skb)
{
	u32 aligned_len = wlcore_calc_packet_alignment(wl, skb->len);

	if (wl->chip.id == CHIP_ID_1283_PG20) {
		desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
		desc->length = cpu_to_le16(aligned_len >> 2);

		wl1271_debug(DEBUG_TX,
			     "tx_fill_hdr: hlid: %d len: %d life: %d mem: %d extra: %d",
			     desc->hlid,
			     le16_to_cpu(desc->length),
			     le16_to_cpu(desc->life_time),
			     desc->wl128x_mem.total_mem_blocks,
			     desc->wl128x_mem.extra_bytes);
	} else {
		/* calculate number of padding bytes */
		int pad = aligned_len - skb->len;
		desc->tx_attr |=
			cpu_to_le16(pad << TX_HW_ATTR_OFST_LAST_WORD_PAD);

		/* Store the aligned length in terms of words */
		desc->length = cpu_to_le16(aligned_len >> 2);

		wl1271_debug(DEBUG_TX,
			     "tx_fill_hdr: pad: %d hlid: %d len: %d life: %d mem: %d",
			     pad, desc->hlid,
			     le16_to_cpu(desc->length),
			     le16_to_cpu(desc->life_time),
			     desc->wl127x_mem.total_mem_blocks);
	}
}

static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
{
	bool supported = false;
@@ -679,6 +714,7 @@ static struct wlcore_ops wl12xx_ops = {
	.ack_event		= wl12xx_ack_event,
	.calc_tx_blocks		= wl12xx_calc_tx_blocks,
	.set_tx_desc_blocks	= wl12xx_set_tx_desc_blocks,
	.set_tx_desc_data_len	= wl12xx_set_tx_desc_data_len,
	.get_pg_ver		= wl12xx_get_pg_ver,
	.get_mac		= wl12xx_get_mac,
};
+11 −0
Original line number Diff line number Diff line
@@ -43,4 +43,15 @@ wlcore_hw_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
	return wl->ops->set_tx_desc_blocks(wl, desc, blks, spare_blks);
}

static inline void
wlcore_hw_set_tx_desc_data_len(struct wl1271 *wl,
			       struct wl1271_tx_hw_descr *desc,
			       struct sk_buff *skb)
{
	if (!wl->ops->set_tx_desc_data_len)
		BUG_ON(1);

	wl->ops->set_tx_desc_data_len(wl, desc, skb);
}

#endif
+4 −32
Original line number Diff line number Diff line
@@ -251,7 +251,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
{
	struct timespec ts;
	struct wl1271_tx_hw_descr *desc;
	int aligned_len, ac, rate_idx;
	int ac, rate_idx;
	s64 hosttime;
	u16 tx_attr = 0;
	__le16 frame_control;
@@ -324,44 +324,16 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
	}

	tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY;
	desc->reserved = 0;

	aligned_len = wlcore_calc_packet_alignment(wl, skb->len);

	if (wl->chip.id == CHIP_ID_1283_PG20) {
		desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
		desc->length = cpu_to_le16(aligned_len >> 2);

		wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d "
			     "tx_attr: 0x%x len: %d life: %d mem: %d",
			     desc->hlid, tx_attr,
			     le16_to_cpu(desc->length),
			     le16_to_cpu(desc->life_time),
			     desc->wl128x_mem.total_mem_blocks);
	} else {
		int pad;

		/* Store the aligned length in terms of words */
		desc->length = cpu_to_le16(aligned_len >> 2);

		/* calculate number of padding bytes */
		pad = aligned_len - skb->len;
		tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD;

		wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d hlid: %d "
			     "tx_attr: 0x%x len: %d life: %d mem: %d", pad,
			     desc->hlid, tx_attr,
			     le16_to_cpu(desc->length),
			     le16_to_cpu(desc->life_time),
			     desc->wl127x_mem.total_mem_blocks);
	}

	/* for WEP shared auth - no fw encryption is needed */
	if (ieee80211_is_auth(frame_control) &&
	    ieee80211_has_protected(frame_control))
		tx_attr |= TX_HW_ATTR_HOST_ENCRYPT;

	desc->reserved = 0;
	desc->tx_attr = cpu_to_le16(tx_attr);

	wlcore_hw_set_tx_desc_data_len(wl, desc, skb);
}

/* caller must hold wl->mutex */
+3 −0
Original line number Diff line number Diff line
@@ -41,6 +41,9 @@ struct wlcore_ops {
	void (*set_tx_desc_blocks)(struct wl1271 *wl,
				   struct wl1271_tx_hw_descr *desc,
				   u32 blks, u32 spare_blks);
	void (*set_tx_desc_data_len)(struct wl1271 *wl,
				     struct wl1271_tx_hw_descr *desc,
				     struct sk_buff *skb);
	s8 (*get_pg_ver)(struct wl1271 *wl);
	void (*get_mac)(struct wl1271 *wl);
};