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