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