xref: /openbmc/linux/drivers/infiniband/hw/hfi1/ipoib_rx.c (revision 6991abcb993cf6c0711237b9d393d4f0a2008f1f)
1*6991abcbSKaike Wan // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2*6991abcbSKaike Wan /*
3*6991abcbSKaike Wan  * Copyright(c) 2020 Intel Corporation.
4*6991abcbSKaike Wan  *
5*6991abcbSKaike Wan  */
6*6991abcbSKaike Wan 
7*6991abcbSKaike Wan #include "netdev.h"
8*6991abcbSKaike Wan #include "ipoib.h"
9*6991abcbSKaike Wan 
10*6991abcbSKaike Wan #define HFI1_IPOIB_SKB_PAD ((NET_SKB_PAD) + (NET_IP_ALIGN))
11*6991abcbSKaike Wan 
12*6991abcbSKaike Wan static void copy_ipoib_buf(struct sk_buff *skb, void *data, int size)
13*6991abcbSKaike Wan {
14*6991abcbSKaike Wan 	void *dst_data;
15*6991abcbSKaike Wan 
16*6991abcbSKaike Wan 	skb_checksum_none_assert(skb);
17*6991abcbSKaike Wan 	skb->protocol = *((__be16 *)data);
18*6991abcbSKaike Wan 
19*6991abcbSKaike Wan 	dst_data = skb_put(skb, size);
20*6991abcbSKaike Wan 	memcpy(dst_data, data, size);
21*6991abcbSKaike Wan 	skb->mac_header = HFI1_IPOIB_PSEUDO_LEN;
22*6991abcbSKaike Wan 	skb_pull(skb, HFI1_IPOIB_ENCAP_LEN);
23*6991abcbSKaike Wan }
24*6991abcbSKaike Wan 
25*6991abcbSKaike Wan static struct sk_buff *prepare_frag_skb(struct napi_struct *napi, int size)
26*6991abcbSKaike Wan {
27*6991abcbSKaike Wan 	struct sk_buff *skb;
28*6991abcbSKaike Wan 	int skb_size = SKB_DATA_ALIGN(size + HFI1_IPOIB_SKB_PAD);
29*6991abcbSKaike Wan 	void *frag;
30*6991abcbSKaike Wan 
31*6991abcbSKaike Wan 	skb_size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
32*6991abcbSKaike Wan 	skb_size = SKB_DATA_ALIGN(skb_size);
33*6991abcbSKaike Wan 	frag = napi_alloc_frag(skb_size);
34*6991abcbSKaike Wan 
35*6991abcbSKaike Wan 	if (unlikely(!frag))
36*6991abcbSKaike Wan 		return napi_alloc_skb(napi, size);
37*6991abcbSKaike Wan 
38*6991abcbSKaike Wan 	skb = build_skb(frag, skb_size);
39*6991abcbSKaike Wan 
40*6991abcbSKaike Wan 	if (unlikely(!skb)) {
41*6991abcbSKaike Wan 		skb_free_frag(frag);
42*6991abcbSKaike Wan 		return NULL;
43*6991abcbSKaike Wan 	}
44*6991abcbSKaike Wan 
45*6991abcbSKaike Wan 	skb_reserve(skb, HFI1_IPOIB_SKB_PAD);
46*6991abcbSKaike Wan 	return skb;
47*6991abcbSKaike Wan }
48*6991abcbSKaike Wan 
49*6991abcbSKaike Wan struct sk_buff *hfi1_ipoib_prepare_skb(struct hfi1_netdev_rxq *rxq,
50*6991abcbSKaike Wan 				       int size, void *data)
51*6991abcbSKaike Wan {
52*6991abcbSKaike Wan 	struct napi_struct *napi = &rxq->napi;
53*6991abcbSKaike Wan 	int skb_size = size + HFI1_IPOIB_ENCAP_LEN;
54*6991abcbSKaike Wan 	struct sk_buff *skb;
55*6991abcbSKaike Wan 
56*6991abcbSKaike Wan 	/*
57*6991abcbSKaike Wan 	 * For smaller(4k + skb overhead) allocations we will go using
58*6991abcbSKaike Wan 	 * napi cache. Otherwise we will try to use napi frag cache.
59*6991abcbSKaike Wan 	 */
60*6991abcbSKaike Wan 	if (size <= SKB_WITH_OVERHEAD(PAGE_SIZE))
61*6991abcbSKaike Wan 		skb = napi_alloc_skb(napi, skb_size);
62*6991abcbSKaike Wan 	else
63*6991abcbSKaike Wan 		skb = prepare_frag_skb(napi, skb_size);
64*6991abcbSKaike Wan 
65*6991abcbSKaike Wan 	if (unlikely(!skb))
66*6991abcbSKaike Wan 		return NULL;
67*6991abcbSKaike Wan 
68*6991abcbSKaike Wan 	copy_ipoib_buf(skb, data, size);
69*6991abcbSKaike Wan 
70*6991abcbSKaike Wan 	return skb;
71*6991abcbSKaike Wan }
72