0001
0002
0003
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
0058
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 }