1*4882a593Smuzhiyun // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright(c) 2020 Intel Corporation.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include "netdev.h"
8*4882a593Smuzhiyun #include "ipoib.h"
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #define HFI1_IPOIB_SKB_PAD ((NET_SKB_PAD) + (NET_IP_ALIGN))
11*4882a593Smuzhiyun
copy_ipoib_buf(struct sk_buff * skb,void * data,int size)12*4882a593Smuzhiyun static void copy_ipoib_buf(struct sk_buff *skb, void *data, int size)
13*4882a593Smuzhiyun {
14*4882a593Smuzhiyun void *dst_data;
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun skb_checksum_none_assert(skb);
17*4882a593Smuzhiyun skb->protocol = *((__be16 *)data);
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun dst_data = skb_put(skb, size);
20*4882a593Smuzhiyun memcpy(dst_data, data, size);
21*4882a593Smuzhiyun skb->mac_header = HFI1_IPOIB_PSEUDO_LEN;
22*4882a593Smuzhiyun skb_pull(skb, HFI1_IPOIB_ENCAP_LEN);
23*4882a593Smuzhiyun }
24*4882a593Smuzhiyun
prepare_frag_skb(struct napi_struct * napi,int size)25*4882a593Smuzhiyun static struct sk_buff *prepare_frag_skb(struct napi_struct *napi, int size)
26*4882a593Smuzhiyun {
27*4882a593Smuzhiyun struct sk_buff *skb;
28*4882a593Smuzhiyun int skb_size = SKB_DATA_ALIGN(size + HFI1_IPOIB_SKB_PAD);
29*4882a593Smuzhiyun void *frag;
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun skb_size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
32*4882a593Smuzhiyun skb_size = SKB_DATA_ALIGN(skb_size);
33*4882a593Smuzhiyun frag = napi_alloc_frag(skb_size);
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun if (unlikely(!frag))
36*4882a593Smuzhiyun return napi_alloc_skb(napi, size);
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun skb = build_skb(frag, skb_size);
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun if (unlikely(!skb)) {
41*4882a593Smuzhiyun skb_free_frag(frag);
42*4882a593Smuzhiyun return NULL;
43*4882a593Smuzhiyun }
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun skb_reserve(skb, HFI1_IPOIB_SKB_PAD);
46*4882a593Smuzhiyun return skb;
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun
hfi1_ipoib_prepare_skb(struct hfi1_netdev_rxq * rxq,int size,void * data)49*4882a593Smuzhiyun struct sk_buff *hfi1_ipoib_prepare_skb(struct hfi1_netdev_rxq *rxq,
50*4882a593Smuzhiyun int size, void *data)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun struct napi_struct *napi = &rxq->napi;
53*4882a593Smuzhiyun int skb_size = size + HFI1_IPOIB_ENCAP_LEN;
54*4882a593Smuzhiyun struct sk_buff *skb;
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun /*
57*4882a593Smuzhiyun * For smaller(4k + skb overhead) allocations we will go using
58*4882a593Smuzhiyun * napi cache. Otherwise we will try to use napi frag cache.
59*4882a593Smuzhiyun */
60*4882a593Smuzhiyun if (size <= SKB_WITH_OVERHEAD(PAGE_SIZE))
61*4882a593Smuzhiyun skb = napi_alloc_skb(napi, skb_size);
62*4882a593Smuzhiyun else
63*4882a593Smuzhiyun skb = prepare_frag_skb(napi, skb_size);
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun if (unlikely(!skb))
66*4882a593Smuzhiyun return NULL;
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun copy_ipoib_buf(skb, data, size);
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun return skb;
71*4882a593Smuzhiyun }
72*4882a593Smuzhiyun
hfi1_ipoib_rxq_init(struct net_device * netdev)73*4882a593Smuzhiyun int hfi1_ipoib_rxq_init(struct net_device *netdev)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun struct hfi1_ipoib_dev_priv *ipoib_priv = hfi1_ipoib_priv(netdev);
76*4882a593Smuzhiyun struct hfi1_devdata *dd = ipoib_priv->dd;
77*4882a593Smuzhiyun int ret;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun ret = hfi1_netdev_rx_init(dd);
80*4882a593Smuzhiyun if (ret)
81*4882a593Smuzhiyun return ret;
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun hfi1_init_aip_rsm(dd);
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun return ret;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun
hfi1_ipoib_rxq_deinit(struct net_device * netdev)88*4882a593Smuzhiyun void hfi1_ipoib_rxq_deinit(struct net_device *netdev)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun struct hfi1_ipoib_dev_priv *ipoib_priv = hfi1_ipoib_priv(netdev);
91*4882a593Smuzhiyun struct hfi1_devdata *dd = ipoib_priv->dd;
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun hfi1_deinit_aip_rsm(dd);
94*4882a593Smuzhiyun hfi1_netdev_rx_destroy(dd);
95*4882a593Smuzhiyun }
96