18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright(c) 2020 Intel Corporation.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci/*
88c2ecf20Sopenharmony_ci * This file contains HFI1 support for IPOIB functionality
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#ifndef HFI1_IPOIB_H
128c2ecf20Sopenharmony_ci#define HFI1_IPOIB_H
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <linux/types.h>
158c2ecf20Sopenharmony_ci#include <linux/stddef.h>
168c2ecf20Sopenharmony_ci#include <linux/atomic.h>
178c2ecf20Sopenharmony_ci#include <linux/netdevice.h>
188c2ecf20Sopenharmony_ci#include <linux/slab.h>
198c2ecf20Sopenharmony_ci#include <linux/skbuff.h>
208c2ecf20Sopenharmony_ci#include <linux/list.h>
218c2ecf20Sopenharmony_ci#include <linux/if_infiniband.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci#include "hfi.h"
248c2ecf20Sopenharmony_ci#include "iowait.h"
258c2ecf20Sopenharmony_ci#include "netdev.h"
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#include <rdma/ib_verbs.h>
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#define HFI1_IPOIB_ENTROPY_SHIFT   24
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#define HFI1_IPOIB_TXREQ_NAME_LEN   32
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci#define HFI1_IPOIB_PSEUDO_LEN 20
348c2ecf20Sopenharmony_ci#define HFI1_IPOIB_ENCAP_LEN 4
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_cistruct hfi1_ipoib_dev_priv;
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ciunion hfi1_ipoib_flow {
398c2ecf20Sopenharmony_ci	u16 as_int;
408c2ecf20Sopenharmony_ci	struct {
418c2ecf20Sopenharmony_ci		u8 tx_queue;
428c2ecf20Sopenharmony_ci		u8 sc5;
438c2ecf20Sopenharmony_ci	} __attribute__((__packed__));
448c2ecf20Sopenharmony_ci};
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci/**
478c2ecf20Sopenharmony_ci * struct hfi1_ipoib_circ_buf - List of items to be processed
488c2ecf20Sopenharmony_ci * @items: ring of items
498c2ecf20Sopenharmony_ci * @head: ring head
508c2ecf20Sopenharmony_ci * @tail: ring tail
518c2ecf20Sopenharmony_ci * @max_items: max items + 1 that the ring can contain
528c2ecf20Sopenharmony_ci * @producer_lock: producer sync lock
538c2ecf20Sopenharmony_ci * @consumer_lock: consumer sync lock
548c2ecf20Sopenharmony_ci */
558c2ecf20Sopenharmony_cistruct ipoib_txreq;
568c2ecf20Sopenharmony_cistruct hfi1_ipoib_circ_buf {
578c2ecf20Sopenharmony_ci	struct ipoib_txreq **items;
588c2ecf20Sopenharmony_ci	unsigned long head;
598c2ecf20Sopenharmony_ci	unsigned long tail;
608c2ecf20Sopenharmony_ci	unsigned long max_items;
618c2ecf20Sopenharmony_ci	spinlock_t producer_lock; /* head sync lock */
628c2ecf20Sopenharmony_ci	spinlock_t consumer_lock; /* tail sync lock */
638c2ecf20Sopenharmony_ci};
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci/**
668c2ecf20Sopenharmony_ci * struct hfi1_ipoib_txq - IPOIB per Tx queue information
678c2ecf20Sopenharmony_ci * @priv: private pointer
688c2ecf20Sopenharmony_ci * @sde: sdma engine
698c2ecf20Sopenharmony_ci * @tx_list: tx request list
708c2ecf20Sopenharmony_ci * @sent_txreqs: count of txreqs posted to sdma
718c2ecf20Sopenharmony_ci * @stops: count of stops of queue
728c2ecf20Sopenharmony_ci * @ring_full: ring has been filled
738c2ecf20Sopenharmony_ci * @no_desc: descriptor shortage seen
748c2ecf20Sopenharmony_ci * @flow: tracks when list needs to be flushed for a flow change
758c2ecf20Sopenharmony_ci * @q_idx: ipoib Tx queue index
768c2ecf20Sopenharmony_ci * @pkts_sent: indicator packets have been sent from this queue
778c2ecf20Sopenharmony_ci * @wait: iowait structure
788c2ecf20Sopenharmony_ci * @complete_txreqs: count of txreqs completed by sdma
798c2ecf20Sopenharmony_ci * @napi: pointer to tx napi interface
808c2ecf20Sopenharmony_ci * @tx_ring: ring of ipoib txreqs to be reaped by napi callback
818c2ecf20Sopenharmony_ci */
828c2ecf20Sopenharmony_cistruct hfi1_ipoib_txq {
838c2ecf20Sopenharmony_ci	struct hfi1_ipoib_dev_priv *priv;
848c2ecf20Sopenharmony_ci	struct sdma_engine *sde;
858c2ecf20Sopenharmony_ci	struct list_head tx_list;
868c2ecf20Sopenharmony_ci	u64 sent_txreqs;
878c2ecf20Sopenharmony_ci	atomic_t stops;
888c2ecf20Sopenharmony_ci	atomic_t ring_full;
898c2ecf20Sopenharmony_ci	atomic_t no_desc;
908c2ecf20Sopenharmony_ci	union hfi1_ipoib_flow flow;
918c2ecf20Sopenharmony_ci	u8 q_idx;
928c2ecf20Sopenharmony_ci	bool pkts_sent;
938c2ecf20Sopenharmony_ci	struct iowait wait;
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci	atomic64_t ____cacheline_aligned_in_smp complete_txreqs;
968c2ecf20Sopenharmony_ci	struct napi_struct *napi;
978c2ecf20Sopenharmony_ci	struct hfi1_ipoib_circ_buf tx_ring;
988c2ecf20Sopenharmony_ci};
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cistruct hfi1_ipoib_dev_priv {
1018c2ecf20Sopenharmony_ci	struct hfi1_devdata *dd;
1028c2ecf20Sopenharmony_ci	struct net_device   *netdev;
1038c2ecf20Sopenharmony_ci	struct ib_device    *device;
1048c2ecf20Sopenharmony_ci	struct hfi1_ipoib_txq *txqs;
1058c2ecf20Sopenharmony_ci	struct kmem_cache *txreq_cache;
1068c2ecf20Sopenharmony_ci	struct napi_struct *tx_napis;
1078c2ecf20Sopenharmony_ci	u16 pkey;
1088c2ecf20Sopenharmony_ci	u16 pkey_index;
1098c2ecf20Sopenharmony_ci	u32 qkey;
1108c2ecf20Sopenharmony_ci	u8 port_num;
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci	const struct net_device_ops *netdev_ops;
1138c2ecf20Sopenharmony_ci	struct rvt_qp *qp;
1148c2ecf20Sopenharmony_ci	struct pcpu_sw_netstats __percpu *netstats;
1158c2ecf20Sopenharmony_ci};
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci/* hfi1 ipoib rdma netdev's private data structure */
1188c2ecf20Sopenharmony_cistruct hfi1_ipoib_rdma_netdev {
1198c2ecf20Sopenharmony_ci	struct rdma_netdev rn;  /* keep this first */
1208c2ecf20Sopenharmony_ci	/* followed by device private data */
1218c2ecf20Sopenharmony_ci	struct hfi1_ipoib_dev_priv dev_priv;
1228c2ecf20Sopenharmony_ci};
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_cistatic inline struct hfi1_ipoib_dev_priv *
1258c2ecf20Sopenharmony_cihfi1_ipoib_priv(const struct net_device *dev)
1268c2ecf20Sopenharmony_ci{
1278c2ecf20Sopenharmony_ci	return &((struct hfi1_ipoib_rdma_netdev *)netdev_priv(dev))->dev_priv;
1288c2ecf20Sopenharmony_ci}
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_cistatic inline void
1318c2ecf20Sopenharmony_cihfi1_ipoib_update_rx_netstats(struct hfi1_ipoib_dev_priv *priv,
1328c2ecf20Sopenharmony_ci			      u64 packets,
1338c2ecf20Sopenharmony_ci			      u64 bytes)
1348c2ecf20Sopenharmony_ci{
1358c2ecf20Sopenharmony_ci	struct pcpu_sw_netstats *netstats = this_cpu_ptr(priv->netstats);
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	u64_stats_update_begin(&netstats->syncp);
1388c2ecf20Sopenharmony_ci	netstats->rx_packets += packets;
1398c2ecf20Sopenharmony_ci	netstats->rx_bytes += bytes;
1408c2ecf20Sopenharmony_ci	u64_stats_update_end(&netstats->syncp);
1418c2ecf20Sopenharmony_ci}
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_cistatic inline void
1448c2ecf20Sopenharmony_cihfi1_ipoib_update_tx_netstats(struct hfi1_ipoib_dev_priv *priv,
1458c2ecf20Sopenharmony_ci			      u64 packets,
1468c2ecf20Sopenharmony_ci			      u64 bytes)
1478c2ecf20Sopenharmony_ci{
1488c2ecf20Sopenharmony_ci	struct pcpu_sw_netstats *netstats = this_cpu_ptr(priv->netstats);
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci	u64_stats_update_begin(&netstats->syncp);
1518c2ecf20Sopenharmony_ci	netstats->tx_packets += packets;
1528c2ecf20Sopenharmony_ci	netstats->tx_bytes += bytes;
1538c2ecf20Sopenharmony_ci	u64_stats_update_end(&netstats->syncp);
1548c2ecf20Sopenharmony_ci}
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ciint hfi1_ipoib_send_dma(struct net_device *dev,
1578c2ecf20Sopenharmony_ci			struct sk_buff *skb,
1588c2ecf20Sopenharmony_ci			struct ib_ah *address,
1598c2ecf20Sopenharmony_ci			u32 dqpn);
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ciint hfi1_ipoib_txreq_init(struct hfi1_ipoib_dev_priv *priv);
1628c2ecf20Sopenharmony_civoid hfi1_ipoib_txreq_deinit(struct hfi1_ipoib_dev_priv *priv);
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ciint hfi1_ipoib_rxq_init(struct net_device *dev);
1658c2ecf20Sopenharmony_civoid hfi1_ipoib_rxq_deinit(struct net_device *dev);
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_civoid hfi1_ipoib_napi_tx_enable(struct net_device *dev);
1688c2ecf20Sopenharmony_civoid hfi1_ipoib_napi_tx_disable(struct net_device *dev);
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_cistruct sk_buff *hfi1_ipoib_prepare_skb(struct hfi1_netdev_rxq *rxq,
1718c2ecf20Sopenharmony_ci				       int size, void *data);
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ciint hfi1_ipoib_rn_get_params(struct ib_device *device,
1748c2ecf20Sopenharmony_ci			     u8 port_num,
1758c2ecf20Sopenharmony_ci			     enum rdma_netdev_t type,
1768c2ecf20Sopenharmony_ci			     struct rdma_netdev_alloc_params *params);
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci#endif /* _IPOIB_H */
179