162306a36Sopenharmony_ci/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
262306a36Sopenharmony_ci/* Copyright (C) 2019 Netronome Systems, Inc. */
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#ifndef _NFP_DP_NFDK_H_
562306a36Sopenharmony_ci#define _NFP_DP_NFDK_H_
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/bitops.h>
862306a36Sopenharmony_ci#include <linux/types.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#define NFDK_TX_DESC_PER_SIMPLE_PKT	2
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#define NFDK_TX_MAX_DATA_PER_HEAD	SZ_4K
1362306a36Sopenharmony_ci#define NFDK_TX_MAX_DATA_PER_DESC	SZ_16K
1462306a36Sopenharmony_ci#define NFDK_TX_DESC_BLOCK_SZ		256
1562306a36Sopenharmony_ci#define NFDK_TX_DESC_BLOCK_CNT		(NFDK_TX_DESC_BLOCK_SZ /	\
1662306a36Sopenharmony_ci					 sizeof(struct nfp_nfdk_tx_desc))
1762306a36Sopenharmony_ci#define NFDK_TX_DESC_STOP_CNT		(NFDK_TX_DESC_BLOCK_CNT *	\
1862306a36Sopenharmony_ci					 NFDK_TX_DESC_PER_SIMPLE_PKT)
1962306a36Sopenharmony_ci#define NFDK_TX_MAX_DATA_PER_BLOCK	SZ_64K
2062306a36Sopenharmony_ci#define NFDK_TX_DESC_GATHER_MAX		17
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/* TX descriptor format */
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#define NFDK_DESC_TX_MSS_MASK		GENMASK(13, 0)
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define NFDK_DESC_TX_CHAIN_META		BIT(3)
2762306a36Sopenharmony_ci#define NFDK_DESC_TX_ENCAP		BIT(2)
2862306a36Sopenharmony_ci#define NFDK_DESC_TX_L4_CSUM		BIT(1)
2962306a36Sopenharmony_ci#define NFDK_DESC_TX_L3_CSUM		BIT(0)
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define NFDK_DESC_TX_DMA_LEN_HEAD	GENMASK(11, 0)
3262306a36Sopenharmony_ci#define NFDK_DESC_TX_TYPE_HEAD		GENMASK(15, 12)
3362306a36Sopenharmony_ci#define NFDK_DESC_TX_DMA_LEN		GENMASK(13, 0)
3462306a36Sopenharmony_ci#define NFDK_DESC_TX_TYPE_NOP		0
3562306a36Sopenharmony_ci#define NFDK_DESC_TX_TYPE_GATHER	1
3662306a36Sopenharmony_ci#define NFDK_DESC_TX_TYPE_TSO		2
3762306a36Sopenharmony_ci#define NFDK_DESC_TX_TYPE_SIMPLE	8
3862306a36Sopenharmony_ci#define NFDK_DESC_TX_EOP		BIT(14)
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci#define NFDK_META_LEN			GENMASK(7, 0)
4162306a36Sopenharmony_ci#define NFDK_META_FIELDS		GENMASK(31, 8)
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci#define D_BLOCK_CPL(idx)		(NFDK_TX_DESC_BLOCK_CNT -	\
4462306a36Sopenharmony_ci					 (idx) % NFDK_TX_DESC_BLOCK_CNT)
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistruct nfp_nfdk_tx_desc {
4762306a36Sopenharmony_ci	union {
4862306a36Sopenharmony_ci		struct {
4962306a36Sopenharmony_ci			__le16 dma_addr_hi;  /* High bits of host buf address */
5062306a36Sopenharmony_ci			__le16 dma_len_type; /* Length to DMA for this desc */
5162306a36Sopenharmony_ci			__le32 dma_addr_lo;  /* Low 32bit of host buf addr */
5262306a36Sopenharmony_ci		};
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci		struct {
5562306a36Sopenharmony_ci			__le16 mss;	/* MSS to be used for LSO */
5662306a36Sopenharmony_ci			u8 lso_hdrlen;  /* LSO, TCP payload offset */
5762306a36Sopenharmony_ci			u8 lso_totsegs; /* LSO, total segments */
5862306a36Sopenharmony_ci			u8 l3_offset;   /* L3 header offset */
5962306a36Sopenharmony_ci			u8 l4_offset;   /* L4 header offset */
6062306a36Sopenharmony_ci			__le16 lso_meta_res; /* Rsvd bits in TSO metadata */
6162306a36Sopenharmony_ci		};
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci		struct {
6462306a36Sopenharmony_ci			u8 flags;	/* TX Flags, see @NFDK_DESC_TX_* */
6562306a36Sopenharmony_ci			u8 reserved[7];	/* meta byte placeholder */
6662306a36Sopenharmony_ci		};
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci		__le32 vals[2];
6962306a36Sopenharmony_ci		__le64 raw;
7062306a36Sopenharmony_ci	};
7162306a36Sopenharmony_ci};
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci/* The device don't make use of the 2 or 3 least significant bits of the address
7462306a36Sopenharmony_ci * due to alignment constraints. The driver can make use of those bits to carry
7562306a36Sopenharmony_ci * information about the buffer before giving it to the device.
7662306a36Sopenharmony_ci *
7762306a36Sopenharmony_ci * NOTE: The driver must clear the lower bits before handing the buffer to the
7862306a36Sopenharmony_ci * device.
7962306a36Sopenharmony_ci *
8062306a36Sopenharmony_ci * - NFDK_TX_BUF_INFO_SOP - Start of a packet
8162306a36Sopenharmony_ci *   Mark the buffer as a start of a packet. This is used in the XDP TX process
8262306a36Sopenharmony_ci *   to stash virtual and DMA address so that they can be recycled when the TX
8362306a36Sopenharmony_ci *   operation is completed.
8462306a36Sopenharmony_ci */
8562306a36Sopenharmony_ci#define NFDK_TX_BUF_PTR(val) ((val) & ~(sizeof(void *) - 1))
8662306a36Sopenharmony_ci#define NFDK_TX_BUF_INFO(val) ((val) & (sizeof(void *) - 1))
8762306a36Sopenharmony_ci#define NFDK_TX_BUF_INFO_SOP BIT(0)
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_cistruct nfp_nfdk_tx_buf {
9062306a36Sopenharmony_ci	union {
9162306a36Sopenharmony_ci		/* First slot */
9262306a36Sopenharmony_ci		union {
9362306a36Sopenharmony_ci			struct sk_buff *skb;
9462306a36Sopenharmony_ci			void *frag;
9562306a36Sopenharmony_ci			unsigned long val;
9662306a36Sopenharmony_ci		};
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci		/* 1 + nr_frags next slots */
9962306a36Sopenharmony_ci		dma_addr_t dma_addr;
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci		/* TSO (optional) */
10262306a36Sopenharmony_ci		struct {
10362306a36Sopenharmony_ci			u32 pkt_cnt;
10462306a36Sopenharmony_ci			u32 real_len;
10562306a36Sopenharmony_ci		};
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci		u64 raw;
10862306a36Sopenharmony_ci	};
10962306a36Sopenharmony_ci};
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_cistatic inline int nfp_nfdk_headlen_to_segs(unsigned int headlen)
11262306a36Sopenharmony_ci{
11362306a36Sopenharmony_ci	/* First descriptor fits less data, so adjust for that */
11462306a36Sopenharmony_ci	return DIV_ROUND_UP(headlen +
11562306a36Sopenharmony_ci			    NFDK_TX_MAX_DATA_PER_DESC -
11662306a36Sopenharmony_ci			    NFDK_TX_MAX_DATA_PER_HEAD,
11762306a36Sopenharmony_ci			    NFDK_TX_MAX_DATA_PER_DESC);
11862306a36Sopenharmony_ci}
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ciint nfp_nfdk_poll(struct napi_struct *napi, int budget);
12162306a36Sopenharmony_cinetdev_tx_t nfp_nfdk_tx(struct sk_buff *skb, struct net_device *netdev);
12262306a36Sopenharmony_cibool
12362306a36Sopenharmony_cinfp_nfdk_ctrl_tx_one(struct nfp_net *nn, struct nfp_net_r_vector *r_vec,
12462306a36Sopenharmony_ci		     struct sk_buff *skb, bool old);
12562306a36Sopenharmony_civoid nfp_nfdk_ctrl_poll(struct tasklet_struct *t);
12662306a36Sopenharmony_civoid nfp_nfdk_rx_ring_fill_freelist(struct nfp_net_dp *dp,
12762306a36Sopenharmony_ci				    struct nfp_net_rx_ring *rx_ring);
12862306a36Sopenharmony_ci#ifndef CONFIG_NFP_NET_IPSEC
12962306a36Sopenharmony_cistatic inline u64 nfp_nfdk_ipsec_tx(u64 flags, struct sk_buff *skb)
13062306a36Sopenharmony_ci{
13162306a36Sopenharmony_ci	return flags;
13262306a36Sopenharmony_ci}
13362306a36Sopenharmony_ci#else
13462306a36Sopenharmony_ciu64 nfp_nfdk_ipsec_tx(u64 flags, struct sk_buff *skb);
13562306a36Sopenharmony_ci#endif
13662306a36Sopenharmony_ci#endif
137