Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
0002 /*
0003  * Copyright(c) 2020 Intel Corporation.
0004  *
0005  */
0006 
0007 #include "netdev.h"
0008 #include "ipoib.h"
0009 
0010 #define HFI1_IPOIB_SKB_PAD ((NET_SKB_PAD) + (NET_IP_ALIGN))
0011 
0012 static void copy_ipoib_buf(struct sk_buff *skb, void *data, int size)
0013 {
0014     void *dst_data;
0015 
0016     skb_checksum_none_assert(skb);
0017     skb->protocol = *((__be16 *)data);
0018 
0019     dst_data = skb_put(skb, size);
0020     memcpy(dst_data, data, size);
0021     skb->mac_header = HFI1_IPOIB_PSEUDO_LEN;
0022     skb_pull(skb, HFI1_IPOIB_ENCAP_LEN);
0023 }
0024 
0025 static struct sk_buff *prepare_frag_skb(struct napi_struct *napi, int size)
0026 {
0027     struct sk_buff *skb;
0028     int skb_size = SKB_DATA_ALIGN(size + HFI1_IPOIB_SKB_PAD);
0029     void *frag;
0030 
0031     skb_size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
0032     skb_size = SKB_DATA_ALIGN(skb_size);
0033     frag = napi_alloc_frag(skb_size);
0034 
0035     if (unlikely(!frag))
0036         return napi_alloc_skb(napi, size);
0037 
0038     skb = build_skb(frag, skb_size);
0039 
0040     if (unlikely(!skb)) {
0041         skb_free_frag(frag);
0042         return NULL;
0043     }
0044 
0045     skb_reserve(skb, HFI1_IPOIB_SKB_PAD);
0046     return skb;
0047 }
0048 
0049 struct sk_buff *hfi1_ipoib_prepare_skb(struct hfi1_netdev_rxq *rxq,
0050                        int size, void *data)
0051 {
0052     struct napi_struct *napi = &rxq->napi;
0053     int skb_size = size + HFI1_IPOIB_ENCAP_LEN;
0054     struct sk_buff *skb;
0055 
0056     /*
0057      * For smaller(4k + skb overhead) allocations we will go using
0058      * napi cache. Otherwise we will try to use napi frag cache.
0059      */
0060     if (size <= SKB_WITH_OVERHEAD(PAGE_SIZE))
0061         skb = napi_alloc_skb(napi, skb_size);
0062     else
0063         skb = prepare_frag_skb(napi, skb_size);
0064 
0065     if (unlikely(!skb))
0066         return NULL;
0067 
0068     copy_ipoib_buf(skb, data, size);
0069 
0070     return skb;
0071 }
0072 
0073 int hfi1_ipoib_rxq_init(struct net_device *netdev)
0074 {
0075     struct hfi1_ipoib_dev_priv *ipoib_priv = hfi1_ipoib_priv(netdev);
0076     struct hfi1_devdata *dd = ipoib_priv->dd;
0077     int ret;
0078 
0079     ret = hfi1_netdev_rx_init(dd);
0080     if (ret)
0081         return ret;
0082 
0083     hfi1_init_aip_rsm(dd);
0084 
0085     return ret;
0086 }
0087 
0088 void hfi1_ipoib_rxq_deinit(struct net_device *netdev)
0089 {
0090     struct hfi1_ipoib_dev_priv *ipoib_priv = hfi1_ipoib_priv(netdev);
0091     struct hfi1_devdata *dd = ipoib_priv->dd;
0092 
0093     hfi1_deinit_aip_rsm(dd);
0094     hfi1_netdev_rx_destroy(dd);
0095 }