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

Commit 4158149c authored by Arik Nemtsov's avatar Arik Nemtsov Committed by Luciano Coelho
Browse files

wlcore/wl12xx: add hw op for getting rx packet data length



There is a difference in the way chip families report the length of data
in a single Rx packet. Abstract this into a HW op. Refactor the Rx data
handling function to allocate the correct size for the data, and avoid
trimming the skb.

Signed-off-by: default avatarArik Nemtsov <arik@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent b14684a0
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -776,6 +776,19 @@ wl12xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
	return WLCORE_RX_BUF_ALIGNED;
}

static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
				    u32 data_len)
{
	struct wl1271_rx_descriptor *desc = rx_data;

	/* invalid packet */
	if (data_len < sizeof(*desc) ||
	    data_len < sizeof(*desc) + desc->pad_len)
		return 0;

	return data_len - sizeof(*desc) - desc->pad_len;
}

static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
{
	bool supported = false;
@@ -848,6 +861,7 @@ static struct wlcore_ops wl12xx_ops = {
	.set_tx_desc_blocks	= wl12xx_set_tx_desc_blocks,
	.set_tx_desc_data_len	= wl12xx_set_tx_desc_data_len,
	.get_rx_buf_align	= wl12xx_get_rx_buf_align,
	.get_rx_packet_len	= wl12xx_get_rx_packet_len,
	.get_pg_ver		= wl12xx_get_pg_ver,
	.get_mac		= wl12xx_get_mac,
};
+9 −0
Original line number Diff line number Diff line
@@ -72,4 +72,13 @@ wlcore_hw_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
		wl->ops->prepare_read(wl, rx_desc, len);
}

static inline u32
wlcore_hw_get_rx_packet_len(struct wl1271 *wl, void *rx_data, u32 data_len)
{
	if (!wl->ops->get_rx_packet_len)
		BUG_ON(1);

	return wl->ops->get_rx_packet_len(wl, rx_data, data_len);
}

#endif
+12 −6
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
	u8 is_data = 0;
	u8 reserved = 0;
	u16 seq_num;
	u32 pkt_data_len;

	/*
	 * In PLT mode we seem to get frames and mac80211 warns about them,
@@ -118,6 +119,13 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
	if (unlikely(wl->plt))
		return -EINVAL;

	pkt_data_len = wlcore_hw_get_rx_packet_len(wl, data, length);
	if (!pkt_data_len) {
		wl1271_error("Invalid packet arrived from HW. length %d",
			     length);
		return -EINVAL;
	}

	if (rx_align == WLCORE_RX_BUF_UNALIGNED)
		reserved = NET_IP_ALIGN;

@@ -147,8 +155,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
		return -EINVAL;
	}

	/* skb length not included rx descriptor */
	skb = __dev_alloc_skb(length + reserved - sizeof(*desc), GFP_KERNEL);
	/* skb length not including rx descriptor */
	skb = __dev_alloc_skb(pkt_data_len + reserved, GFP_KERNEL);
	if (!skb) {
		wl1271_error("Couldn't allocate RX frame");
		return -ENOMEM;
@@ -157,7 +165,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
	/* reserve the unaligned payload(if any) */
	skb_reserve(skb, reserved);

	buf = skb_put(skb, length - sizeof(*desc));
	buf = skb_put(skb, pkt_data_len);

	/*
	 * Copy packets from aggregation buffer to the skbs without rx
@@ -165,7 +173,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
	 * packets copy the packets in offset of 2 bytes guarantee IP header
	 * payload aligned to 4 bytes.
	 */
	memcpy(buf, data + sizeof(*desc), length - sizeof(*desc));
	memcpy(buf, data + sizeof(*desc), pkt_data_len);
	if (rx_align == WLCORE_RX_BUF_PADDED)
		skb_pull(skb, NET_IP_ALIGN);

@@ -185,8 +193,6 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
		     beacon ? "beacon" : "",
		     seq_num, *hlid);

	skb_trim(skb, skb->len - desc->pad_len);

	skb_queue_tail(&wl->deferred_rx_queue, skb);
	queue_work(wl->freezable_wq, &wl->netstack_work);

+3 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
/* forward declaration */
struct wl1271_tx_hw_descr;
enum wl_rx_buf_align;

struct wlcore_ops {
	int (*identify_chip)(struct wl1271 *wl);
	int (*boot)(struct wl1271 *wl);
@@ -48,6 +49,8 @@ struct wlcore_ops {
	enum wl_rx_buf_align (*get_rx_buf_align)(struct wl1271 *wl,
						 u32 rx_desc);
	void (*prepare_read)(struct wl1271 *wl, u32 rx_desc, u32 len);
	u32 (*get_rx_packet_len)(struct wl1271 *wl, void *rx_data,
				 u32 data_len);
	s8 (*get_pg_ver)(struct wl1271 *wl);
	void (*get_mac)(struct wl1271 *wl);
};