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

Commit a6973386 authored by Linux Build Service Account's avatar Linux Build Service Account
Browse files

Merge b8fea6fa on remote branch

Change-Id: I5cbed2a7df439cbffb10aedb7ea889e2cf9608bc
parents 648fb7a1 b8fea6fa
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1253,7 +1253,7 @@ void qmi_rmnet_work_init(void *port)
		return;

	rmnet_ps_wq = alloc_workqueue("rmnet_powersave_work",
					WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 1);
				      WQ_CPU_INTENSIVE, 1);

	if (!rmnet_ps_wq)
		return;
+28 −0
Original line number Diff line number Diff line
@@ -849,6 +849,16 @@ static struct sk_buff *rmnet_alloc_skb(struct rmnet_frag_descriptor *frag_desc,
		th->seq = frag_desc->tcp_seq;
	}

	if (frag_desc->tcp_flags_set) {
		struct tcphdr *th;
		__be16 *flags;

		th = (struct tcphdr *)
		     (rmnet_map_data_ptr(head_skb) + frag_desc->ip_len);
		flags = (__be16 *)&tcp_flag_word(th);
		*flags = frag_desc->tcp_flags;
	}

	/* Handle csum offloading */
	if (frag_desc->csum_valid && frag_desc->hdrs_valid) {
		/* Set the partial checksum information */
@@ -984,6 +994,24 @@ static void __rmnet_frag_segment_data(struct rmnet_frag_descriptor *coal_desc,
		new_desc->tcp_seq_set = 1;
		new_desc->tcp_seq = htonl(ntohl(th->seq) +
					  coal_desc->data_offset);

		/* Don't allow any dangerous flags to appear in any segments
		 * other than the last.
		 */
		if (th->fin || th->psh) {
			if (offset + dlen < coal_desc->len) {
				__be32 flag_word = tcp_flag_word(th);

				/* Clear the FIN and PSH flags from this
				 * segment.
				 */
				flag_word &= ~TCP_FLAG_FIN;
				flag_word &= ~TCP_FLAG_PSH;

				new_desc->tcp_flags_set = 1;
				new_desc->tcp_flags = *((__be16 *)&flag_word);
			}
		}
	} else if (coal_desc->trans_proto == IPPROTO_UDP) {
		struct udphdr *uh, __uh;

+3 −1
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ struct rmnet_frag_descriptor {
	u32 hash;
	__be32 tcp_seq;
	__be16 ip_id;
	__be16 tcp_flags;
	u16 data_offset;
	u16 gso_size;
	u16 gso_segs;
@@ -53,7 +54,8 @@ struct rmnet_frag_descriptor {
	   ip_id_set:1,
	   tcp_seq_set:1,
	   flush_shs:1,
	   reserved:3;
	   tcp_flags_set:1,
	   reserved:2;
};

/* Descriptor management */
+17 −5
Original line number Diff line number Diff line
@@ -744,22 +744,23 @@ __rmnet_map_segment_coal_skb(struct sk_buff *coal_skb,
	struct rmnet_priv *priv = netdev_priv(coal_skb->dev);
	__sum16 *check = NULL;
	u32 alloc_len;
	u32 dlen = coal_meta->data_len * coal_meta->pkt_count;
	u32 hlen = coal_meta->ip_len + coal_meta->trans_len;
	bool zero_csum = false;

	/* We can avoid copying the data if the SKB we got from the lower-level
	 * drivers was nonlinear.
	 */
	if (skb_is_nonlinear(coal_skb))
		alloc_len = coal_meta->ip_len + coal_meta->trans_len;
		alloc_len = hlen;
	else
		alloc_len = coal_meta->ip_len + coal_meta->trans_len +
			    (coal_meta->data_len * coal_meta->pkt_count);
		alloc_len = hlen + dlen;

	skbn = alloc_skb(alloc_len, GFP_ATOMIC);
	if (!skbn)
		return;

	skb_reserve(skbn, coal_meta->ip_len + coal_meta->trans_len);
	skb_reserve(skbn, hlen);
	rmnet_map_nonlinear_copy(coal_skb, coal_meta, skbn);

	/* Push transport header and update necessary fields */
@@ -771,6 +772,17 @@ __rmnet_map_segment_coal_skb(struct sk_buff *coal_skb,

		th->seq = htonl(ntohl(th->seq) + coal_meta->data_offset);
		check = &th->check;

		/* Don't allow dangerous flags to be set in any segment but the
		 * last one.
		 */
		if (th->fin || th->psh) {
			if (hlen + coal_meta->data_offset + dlen <
			    coal_skb->len) {
				th->fin = 0;
				th->psh = 0;
			}
		}
	} else if (coal_meta->trans_proto == IPPROTO_UDP) {
		struct udphdr *uh = udp_hdr(skbn);

@@ -846,7 +858,7 @@ __rmnet_map_segment_coal_skb(struct sk_buff *coal_skb,
	__skb_queue_tail(list, skbn);

	/* Update meta information to move past the data we just segmented */
	coal_meta->data_offset += coal_meta->data_len * coal_meta->pkt_count;
	coal_meta->data_offset += dlen;
	coal_meta->pkt_id = pkt_id + 1;
	coal_meta->pkt_count = 0;
}