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 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 25 static 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 49 struct 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 * For smaller(4k + skb overhead) allocations we will go using 58 * napi cache. Otherwise we will try to use napi frag cache. 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 73 int 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 88 void 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