static u8 __tipc_build_gap_ack_blks(struct tipc_gap_ack_blks *ga,
				    struct tipc_link *l, u8 start_index)
{
	struct tipc_gap_ack *gacks = &ga->gacks[start_index];
	struct sk_buff *skb = skb_peek(&l->deferdq);
	u16 expect, seqno = 0;
	u8 n = 0;

	if (!skb)
		return 0;

	expect = buf_seqno(skb);
	skb_queue_walk(&l->deferdq, skb) {
		seqno = buf_seqno(skb);
		if (unlikely(more(seqno, expect))) {
			gacks[n].ack = htons(expect - 1);
			gacks[n].gap = htons(seqno - expect);
			if (++n >= MAX_GAP_ACK_BLKS / 2) {
				pr_info_ratelimited("Gacks on %s: %d, ql: %d!\n",
						    l->name, n,
						    skb_queue_len(&l->deferdq));
				return n;
			}
		} else if (unlikely(less(seqno, expect))) {
			pr_warn("Unexpected skb in deferdq!\n");
			continue;
		}
		expect = seqno + 1;
	}

	/* last block */
	gacks[n].ack = htons(seqno);
	gacks[n].gap = 0;
	n++;
	return n;
}
static u8 __tipc_build_gap_ack_blks(struct tipc_gap_ack_blks *ga,
				    struct tipc_link *l, u8 start_index)
{
	struct tipc_gap_ack *gacks = &ga->gacks[start_index];
	struct sk_buff *skb = skb_peek(&l->deferdq);
	u16 expect, seqno = 0;
	u8 n = 0;

	if (!skb)
		return 0;

	expect = buf_seqno(skb);
	skb_queue_walk(&l->deferdq, skb) {
		seqno = buf_seqno(skb);
		if (unlikely(more(seqno, expect))) {
			gacks[n].ack = htons(expect - 1);
			gacks[n].gap = htons(seqno - expect);
			if (++n >= MAX_GAP_ACK_BLKS / 2) {
				pr_info_ratelimited("Gacks on %s: %d, ql: %d!\n",
						    l->name, n,
						    skb_queue_len(&l->deferdq));
				return n;
			}
		} else if (unlikely(less(seqno, expect))) {
			pr_warn("Unexpected skb in deferdq!\n");
			continue;
		}
		expect = seqno + 1;
	}

	 
	gacks[n].ack = htons(seqno);
	gacks[n].gap = 0;
	n++;
	return n;
}