162306a36Sopenharmony_ci/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright(c) 2020 Intel Corporation.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci/*
862306a36Sopenharmony_ci * This file contains HFI1 support for IPOIB functionality
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifndef HFI1_IPOIB_H
1262306a36Sopenharmony_ci#define HFI1_IPOIB_H
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/types.h>
1562306a36Sopenharmony_ci#include <linux/stddef.h>
1662306a36Sopenharmony_ci#include <linux/atomic.h>
1762306a36Sopenharmony_ci#include <linux/netdevice.h>
1862306a36Sopenharmony_ci#include <linux/slab.h>
1962306a36Sopenharmony_ci#include <linux/skbuff.h>
2062306a36Sopenharmony_ci#include <linux/list.h>
2162306a36Sopenharmony_ci#include <linux/if_infiniband.h>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#include "hfi.h"
2462306a36Sopenharmony_ci#include "iowait.h"
2562306a36Sopenharmony_ci#include "netdev.h"
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#include <rdma/ib_verbs.h>
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#define HFI1_IPOIB_ENTROPY_SHIFT   24
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define HFI1_IPOIB_TXREQ_NAME_LEN   32
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#define HFI1_IPOIB_PSEUDO_LEN 20
3462306a36Sopenharmony_ci#define HFI1_IPOIB_ENCAP_LEN 4
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_cistruct hfi1_ipoib_dev_priv;
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ciunion hfi1_ipoib_flow {
3962306a36Sopenharmony_ci	u16 as_int;
4062306a36Sopenharmony_ci	struct {
4162306a36Sopenharmony_ci		u8 tx_queue;
4262306a36Sopenharmony_ci		u8 sc5;
4362306a36Sopenharmony_ci	} __attribute__((__packed__));
4462306a36Sopenharmony_ci};
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/**
4762306a36Sopenharmony_ci * struct ipoib_txreq - IPOIB transmit descriptor
4862306a36Sopenharmony_ci * @txreq: sdma transmit request
4962306a36Sopenharmony_ci * @sdma_hdr: 9b ib headers
5062306a36Sopenharmony_ci * @sdma_status: status returned by sdma engine
5162306a36Sopenharmony_ci * @complete: non-zero implies complete
5262306a36Sopenharmony_ci * @priv: ipoib netdev private data
5362306a36Sopenharmony_ci * @txq: txq on which skb was output
5462306a36Sopenharmony_ci * @skb: skb to send
5562306a36Sopenharmony_ci */
5662306a36Sopenharmony_cistruct ipoib_txreq {
5762306a36Sopenharmony_ci	struct sdma_txreq           txreq;
5862306a36Sopenharmony_ci	struct hfi1_sdma_header     *sdma_hdr;
5962306a36Sopenharmony_ci	int                         sdma_status;
6062306a36Sopenharmony_ci	int                         complete;
6162306a36Sopenharmony_ci	struct hfi1_ipoib_dev_priv *priv;
6262306a36Sopenharmony_ci	struct hfi1_ipoib_txq      *txq;
6362306a36Sopenharmony_ci	struct sk_buff             *skb;
6462306a36Sopenharmony_ci};
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci/**
6762306a36Sopenharmony_ci * struct hfi1_ipoib_circ_buf - List of items to be processed
6862306a36Sopenharmony_ci * @items: ring of items each a power of two size
6962306a36Sopenharmony_ci * @max_items: max items + 1 that the ring can contain
7062306a36Sopenharmony_ci * @shift: log2 of size for getting txreq
7162306a36Sopenharmony_ci * @sent_txreqs: count of txreqs posted to sdma
7262306a36Sopenharmony_ci * @tail: ring tail
7362306a36Sopenharmony_ci * @stops: count of stops of queue
7462306a36Sopenharmony_ci * @ring_full: ring has been filled
7562306a36Sopenharmony_ci * @no_desc: descriptor shortage seen
7662306a36Sopenharmony_ci * @complete_txreqs: count of txreqs completed by sdma
7762306a36Sopenharmony_ci * @head: ring head
7862306a36Sopenharmony_ci */
7962306a36Sopenharmony_cistruct hfi1_ipoib_circ_buf {
8062306a36Sopenharmony_ci	void *items;
8162306a36Sopenharmony_ci	u32 max_items;
8262306a36Sopenharmony_ci	u32 shift;
8362306a36Sopenharmony_ci	/* consumer cache line */
8462306a36Sopenharmony_ci	u64 ____cacheline_aligned_in_smp sent_txreqs;
8562306a36Sopenharmony_ci	u32 avail;
8662306a36Sopenharmony_ci	u32 tail;
8762306a36Sopenharmony_ci	atomic_t stops;
8862306a36Sopenharmony_ci	atomic_t ring_full;
8962306a36Sopenharmony_ci	atomic_t no_desc;
9062306a36Sopenharmony_ci	/* producer cache line */
9162306a36Sopenharmony_ci	u64 ____cacheline_aligned_in_smp complete_txreqs;
9262306a36Sopenharmony_ci	u32 head;
9362306a36Sopenharmony_ci};
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci/**
9662306a36Sopenharmony_ci * struct hfi1_ipoib_txq - IPOIB per Tx queue information
9762306a36Sopenharmony_ci * @priv: private pointer
9862306a36Sopenharmony_ci * @sde: sdma engine
9962306a36Sopenharmony_ci * @tx_list: tx request list
10062306a36Sopenharmony_ci * @sent_txreqs: count of txreqs posted to sdma
10162306a36Sopenharmony_ci * @flow: tracks when list needs to be flushed for a flow change
10262306a36Sopenharmony_ci * @q_idx: ipoib Tx queue index
10362306a36Sopenharmony_ci * @pkts_sent: indicator packets have been sent from this queue
10462306a36Sopenharmony_ci * @wait: iowait structure
10562306a36Sopenharmony_ci * @napi: pointer to tx napi interface
10662306a36Sopenharmony_ci * @tx_ring: ring of ipoib txreqs to be reaped by napi callback
10762306a36Sopenharmony_ci */
10862306a36Sopenharmony_cistruct hfi1_ipoib_txq {
10962306a36Sopenharmony_ci	struct napi_struct napi;
11062306a36Sopenharmony_ci	struct hfi1_ipoib_dev_priv *priv;
11162306a36Sopenharmony_ci	struct sdma_engine *sde;
11262306a36Sopenharmony_ci	struct list_head tx_list;
11362306a36Sopenharmony_ci	union hfi1_ipoib_flow flow;
11462306a36Sopenharmony_ci	u8 q_idx;
11562306a36Sopenharmony_ci	bool pkts_sent;
11662306a36Sopenharmony_ci	struct iowait wait;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	struct hfi1_ipoib_circ_buf ____cacheline_aligned_in_smp tx_ring;
11962306a36Sopenharmony_ci};
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_cistruct hfi1_ipoib_dev_priv {
12262306a36Sopenharmony_ci	struct hfi1_devdata *dd;
12362306a36Sopenharmony_ci	struct net_device   *netdev;
12462306a36Sopenharmony_ci	struct ib_device    *device;
12562306a36Sopenharmony_ci	struct hfi1_ipoib_txq *txqs;
12662306a36Sopenharmony_ci	const struct net_device_ops *netdev_ops;
12762306a36Sopenharmony_ci	struct rvt_qp *qp;
12862306a36Sopenharmony_ci	u32 qkey;
12962306a36Sopenharmony_ci	u16 pkey;
13062306a36Sopenharmony_ci	u16 pkey_index;
13162306a36Sopenharmony_ci	u8 port_num;
13262306a36Sopenharmony_ci};
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci/* hfi1 ipoib rdma netdev's private data structure */
13562306a36Sopenharmony_cistruct hfi1_ipoib_rdma_netdev {
13662306a36Sopenharmony_ci	struct rdma_netdev rn;  /* keep this first */
13762306a36Sopenharmony_ci	/* followed by device private data */
13862306a36Sopenharmony_ci	struct hfi1_ipoib_dev_priv dev_priv;
13962306a36Sopenharmony_ci};
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_cistatic inline struct hfi1_ipoib_dev_priv *
14262306a36Sopenharmony_cihfi1_ipoib_priv(const struct net_device *dev)
14362306a36Sopenharmony_ci{
14462306a36Sopenharmony_ci	return &((struct hfi1_ipoib_rdma_netdev *)netdev_priv(dev))->dev_priv;
14562306a36Sopenharmony_ci}
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ciint hfi1_ipoib_send(struct net_device *dev,
14862306a36Sopenharmony_ci		    struct sk_buff *skb,
14962306a36Sopenharmony_ci		    struct ib_ah *address,
15062306a36Sopenharmony_ci		    u32 dqpn);
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ciint hfi1_ipoib_txreq_init(struct hfi1_ipoib_dev_priv *priv);
15362306a36Sopenharmony_civoid hfi1_ipoib_txreq_deinit(struct hfi1_ipoib_dev_priv *priv);
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ciint hfi1_ipoib_rxq_init(struct net_device *dev);
15662306a36Sopenharmony_civoid hfi1_ipoib_rxq_deinit(struct net_device *dev);
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_civoid hfi1_ipoib_napi_tx_enable(struct net_device *dev);
15962306a36Sopenharmony_civoid hfi1_ipoib_napi_tx_disable(struct net_device *dev);
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_cistruct sk_buff *hfi1_ipoib_prepare_skb(struct hfi1_netdev_rxq *rxq,
16262306a36Sopenharmony_ci				       int size, void *data);
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ciint hfi1_ipoib_rn_get_params(struct ib_device *device,
16562306a36Sopenharmony_ci			     u32 port_num,
16662306a36Sopenharmony_ci			     enum rdma_netdev_t type,
16762306a36Sopenharmony_ci			     struct rdma_netdev_alloc_params *params);
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_civoid hfi1_ipoib_tx_timeout(struct net_device *dev, unsigned int q);
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci#endif /* _IPOIB_H */
172