xref: /openbmc/linux/drivers/infiniband/hw/hfi1/ipoib_rx.c (revision 370caa5b5880cd988645735c2d5d1d597c258e39)
16991abcbSKaike Wan // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
26991abcbSKaike Wan /*
36991abcbSKaike Wan  * Copyright(c) 2020 Intel Corporation.
46991abcbSKaike Wan  *
56991abcbSKaike Wan  */
66991abcbSKaike Wan 
76991abcbSKaike Wan #include "netdev.h"
86991abcbSKaike Wan #include "ipoib.h"
96991abcbSKaike Wan 
106991abcbSKaike Wan #define HFI1_IPOIB_SKB_PAD ((NET_SKB_PAD) + (NET_IP_ALIGN))
116991abcbSKaike Wan 
126991abcbSKaike Wan static void copy_ipoib_buf(struct sk_buff *skb, void *data, int size)
136991abcbSKaike Wan {
146991abcbSKaike Wan 	void *dst_data;
156991abcbSKaike Wan 
166991abcbSKaike Wan 	skb_checksum_none_assert(skb);
176991abcbSKaike Wan 	skb->protocol = *((__be16 *)data);
186991abcbSKaike Wan 
196991abcbSKaike Wan 	dst_data = skb_put(skb, size);
206991abcbSKaike Wan 	memcpy(dst_data, data, size);
216991abcbSKaike Wan 	skb->mac_header = HFI1_IPOIB_PSEUDO_LEN;
226991abcbSKaike Wan 	skb_pull(skb, HFI1_IPOIB_ENCAP_LEN);
236991abcbSKaike Wan }
246991abcbSKaike Wan 
256991abcbSKaike Wan static struct sk_buff *prepare_frag_skb(struct napi_struct *napi, int size)
266991abcbSKaike Wan {
276991abcbSKaike Wan 	struct sk_buff *skb;
286991abcbSKaike Wan 	int skb_size = SKB_DATA_ALIGN(size + HFI1_IPOIB_SKB_PAD);
296991abcbSKaike Wan 	void *frag;
306991abcbSKaike Wan 
316991abcbSKaike Wan 	skb_size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
326991abcbSKaike Wan 	skb_size = SKB_DATA_ALIGN(skb_size);
336991abcbSKaike Wan 	frag = napi_alloc_frag(skb_size);
346991abcbSKaike Wan 
356991abcbSKaike Wan 	if (unlikely(!frag))
366991abcbSKaike Wan 		return napi_alloc_skb(napi, size);
376991abcbSKaike Wan 
386991abcbSKaike Wan 	skb = build_skb(frag, skb_size);
396991abcbSKaike Wan 
406991abcbSKaike Wan 	if (unlikely(!skb)) {
416991abcbSKaike Wan 		skb_free_frag(frag);
426991abcbSKaike Wan 		return NULL;
436991abcbSKaike Wan 	}
446991abcbSKaike Wan 
456991abcbSKaike Wan 	skb_reserve(skb, HFI1_IPOIB_SKB_PAD);
466991abcbSKaike Wan 	return skb;
476991abcbSKaike Wan }
486991abcbSKaike Wan 
496991abcbSKaike Wan struct sk_buff *hfi1_ipoib_prepare_skb(struct hfi1_netdev_rxq *rxq,
506991abcbSKaike Wan 				       int size, void *data)
516991abcbSKaike Wan {
526991abcbSKaike Wan 	struct napi_struct *napi = &rxq->napi;
536991abcbSKaike Wan 	int skb_size = size + HFI1_IPOIB_ENCAP_LEN;
546991abcbSKaike Wan 	struct sk_buff *skb;
556991abcbSKaike Wan 
566991abcbSKaike Wan 	/*
576991abcbSKaike Wan 	 * For smaller(4k + skb overhead) allocations we will go using
586991abcbSKaike Wan 	 * napi cache. Otherwise we will try to use napi frag cache.
596991abcbSKaike Wan 	 */
606991abcbSKaike Wan 	if (size <= SKB_WITH_OVERHEAD(PAGE_SIZE))
616991abcbSKaike Wan 		skb = napi_alloc_skb(napi, skb_size);
626991abcbSKaike Wan 	else
636991abcbSKaike Wan 		skb = prepare_frag_skb(napi, skb_size);
646991abcbSKaike Wan 
656991abcbSKaike Wan 	if (unlikely(!skb))
666991abcbSKaike Wan 		return NULL;
676991abcbSKaike Wan 
686991abcbSKaike Wan 	copy_ipoib_buf(skb, data, size);
696991abcbSKaike Wan 
706991abcbSKaike Wan 	return skb;
716991abcbSKaike Wan }
72*370caa5bSGrzegorz Andrejczuk 
73*370caa5bSGrzegorz Andrejczuk int hfi1_ipoib_rxq_init(struct net_device *netdev)
74*370caa5bSGrzegorz Andrejczuk {
75*370caa5bSGrzegorz Andrejczuk 	struct hfi1_ipoib_dev_priv *ipoib_priv = hfi1_ipoib_priv(netdev);
76*370caa5bSGrzegorz Andrejczuk 	struct hfi1_devdata *dd = ipoib_priv->dd;
77*370caa5bSGrzegorz Andrejczuk 
78*370caa5bSGrzegorz Andrejczuk 	return hfi1_netdev_rx_init(dd);
79*370caa5bSGrzegorz Andrejczuk }
80*370caa5bSGrzegorz Andrejczuk 
81*370caa5bSGrzegorz Andrejczuk void hfi1_ipoib_rxq_deinit(struct net_device *netdev)
82*370caa5bSGrzegorz Andrejczuk {
83*370caa5bSGrzegorz Andrejczuk 	struct hfi1_ipoib_dev_priv *ipoib_priv = hfi1_ipoib_priv(netdev);
84*370caa5bSGrzegorz Andrejczuk 	struct hfi1_devdata *dd = ipoib_priv->dd;
85*370caa5bSGrzegorz Andrejczuk 
86*370caa5bSGrzegorz Andrejczuk 	hfi1_netdev_rx_destroy(dd);
87*370caa5bSGrzegorz Andrejczuk }
88