linux/drivers/infiniband/hw/hfi1/ipoib_rx.c
<<
>>
Prefs
   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
  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         * 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
  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