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