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