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

Commit aef9163f authored by Sean Tranchetti's avatar Sean Tranchetti
Browse files

net: qualcomm: rmnet: Allow nonlinear SKBs on RX path



Receive path though the rmnet driver can now handle nonlinear SKBs
from the lower level drivers along with the linear SKBs it expected
previously.

Change-Id: Ibc5bd977e995c2e9a9b0676e41b6008531c379c4
Signed-off-by: default avatarSean Tranchetti <stranche@codeaurora.org>
parent 1ec82054
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -163,7 +163,7 @@ __rmnet_map_ingress_handler(struct sk_buff *skb,
	skb->dev = ep->egress_dev;

	/* Subtract MAP header */
	skb_pull(skb, sizeof(struct rmnet_map_header));
	pskb_pull(skb, sizeof(struct rmnet_map_header));
	rmnet_set_skb_proto(skb);

	if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4) {
@@ -176,7 +176,7 @@ __rmnet_map_ingress_handler(struct sk_buff *skb,
		qmi_rmnet_work_maybe_restart(port);
#endif

	skb_trim(skb, len);
	pskb_trim(skb, len);
	rmnet_deliver_skb(skb, port);
	return;

+4 −0
Original line number Diff line number Diff line
@@ -136,6 +136,10 @@ struct rmnet_map_dl_ind {

static inline unsigned char *rmnet_map_data_ptr(struct sk_buff *skb)
{
	/* Nonlinear packets we receive are entirely within frag 0 */
	if (skb_is_nonlinear(skb) && skb->len == skb->data_len)
		return skb_frag_address(skb_shinfo(skb)->frags);

	return skb->data;
}

+6 −6
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ static void rmnet_map_send_ack(struct sk_buff *skb,
	struct net_device *dev = skb->dev;

	if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4)
		skb_trim(skb,
		pskb_trim(skb,
			  skb->len - sizeof(struct rmnet_map_dl_csum_trailer));

	skb->protocol = htons(ETH_P_MAP);
@@ -124,7 +124,7 @@ static void rmnet_map_process_flow_start(struct sk_buff *skb,
	if (skb->len < RMNET_DL_IND_HDR_SIZE)
		return;

	skb_pull(skb, RMNET_MAP_CMD_SIZE);
	pskb_pull(skb, RMNET_MAP_CMD_SIZE);

	dlhdr = (struct rmnet_map_dl_ind_hdr *)rmnet_map_data_ptr(skb);

@@ -152,7 +152,7 @@ static void rmnet_map_process_flow_start(struct sk_buff *skb,
		pull_size = sizeof(struct rmnet_map_dl_ind_hdr);
		if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4)
			pull_size += sizeof(struct rmnet_map_dl_csum_trailer);
		skb_pull(skb, pull_size);
		pskb_pull(skb, pull_size);
	}
}

@@ -165,7 +165,7 @@ static void rmnet_map_process_flow_end(struct sk_buff *skb,
	if (skb->len < RMNET_DL_IND_TRL_SIZE)
		return;

	skb_pull(skb, RMNET_MAP_CMD_SIZE);
	pskb_pull(skb, RMNET_MAP_CMD_SIZE);

	dltrl = (struct rmnet_map_dl_ind_trl *)rmnet_map_data_ptr(skb);

@@ -179,7 +179,7 @@ static void rmnet_map_process_flow_end(struct sk_buff *skb,
		pull_size = sizeof(struct rmnet_map_dl_ind_trl);
		if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4)
			pull_size += sizeof(struct rmnet_map_dl_csum_trailer);
		skb_pull(skb, pull_size);
		pskb_pull(skb, pull_size);
	}
}

+23 −7
Original line number Diff line number Diff line
@@ -330,14 +330,30 @@ struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb,
	if (ntohs(maph->pkt_len) == 0)
		return NULL;

	skbn = alloc_skb(packet_len + RMNET_MAP_DEAGGR_SPACING, GFP_ATOMIC);
	if (skb_is_nonlinear(skb)) {
		skb_frag_t *frag0 = skb_shinfo(skb)->frags;
		struct page *page = skb_frag_page(frag0);

		skbn = alloc_skb(RMNET_MAP_DEAGGR_HEADROOM, GFP_ATOMIC);
		if (!skbn)
			return NULL;

		skb_append_pagefrags(skbn, page, frag0->page_offset,
				     packet_len);
		skbn->data_len += packet_len;
		skbn->len += packet_len;
	} else {
		skbn = alloc_skb(packet_len + RMNET_MAP_DEAGGR_SPACING,
				 GFP_ATOMIC);
		if (!skbn)
			return NULL;

		skb_reserve(skbn, RMNET_MAP_DEAGGR_HEADROOM);
		skb_put(skbn, packet_len);
		memcpy(skbn->data, data, packet_len);
	skb_pull(skb, packet_len);
	}

	pskb_pull(skb, packet_len);

	return skbn;
}