diff options
Diffstat (limited to 'drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_tx.h')
-rw-r--r-- | drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_tx.h | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_tx.h b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_tx.h new file mode 100644 index 000000000000..f338b975103c --- /dev/null +++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_tx.h @@ -0,0 +1,276 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Marvell Octeon EP (EndPoint) VF Ethernet Driver + * + * Copyright (C) 2020 Marvell. + * + */ + +#ifndef _OCTEP_VF_TX_H_ +#define _OCTEP_VF_TX_H_ + +#define IQ_SEND_OK 0 +#define IQ_SEND_STOP 1 +#define IQ_SEND_FAILED -1 + +#define TX_BUFTYPE_NONE 0 +#define TX_BUFTYPE_NET 1 +#define TX_BUFTYPE_NET_SG 2 +#define NUM_TX_BUFTYPES 3 + +/* Hardware format for Scatter/Gather list + * + * 63 48|47 32|31 16|15 0 + * ----------------------------------------- + * | Len 0 | Len 1 | Len 2 | Len 3 | + * ----------------------------------------- + * | Ptr 0 | + * ----------------------------------------- + * | Ptr 1 | + * ----------------------------------------- + * | Ptr 2 | + * ----------------------------------------- + * | Ptr 3 | + * ----------------------------------------- + */ +struct octep_vf_tx_sglist_desc { + u16 len[4]; + dma_addr_t dma_ptr[4]; +}; + +static_assert(sizeof(struct octep_vf_tx_sglist_desc) == 40); + +/* Each Scatter/Gather entry sent to hardwar hold four pointers. + * So, number of entries required is (MAX_SKB_FRAGS + 1)/4, where '+1' + * is for main skb which also goes as a gather buffer to Octeon hardware. + * To allocate sufficient SGLIST entries for a packet with max fragments, + * align by adding 3 before calcuating max SGLIST entries per packet. + */ +#define OCTEP_VF_SGLIST_ENTRIES_PER_PKT ((MAX_SKB_FRAGS + 1 + 3) / 4) +#define OCTEP_VF_SGLIST_SIZE_PER_PKT \ + (OCTEP_VF_SGLIST_ENTRIES_PER_PKT * sizeof(struct octep_vf_tx_sglist_desc)) + +struct octep_vf_tx_buffer { + struct sk_buff *skb; + dma_addr_t dma; + struct octep_vf_tx_sglist_desc *sglist; + dma_addr_t sglist_dma; + u8 gather; +}; + +#define OCTEP_VF_IQ_TXBUFF_INFO_SIZE (sizeof(struct octep_vf_tx_buffer)) + +/* VF Hardware interface Tx statistics */ +struct octep_vf_iface_tx_stats { + /* Total frames sent on the interface */ + u64 pkts; + + /* Total octets sent on the interface */ + u64 octs; + + /* Packets sent to a broadcast DMAC */ + u64 bcst; + + /* Packets sent to the multicast DMAC */ + u64 mcst; + + /* Packets dropped */ + u64 dropped; + + /* Reserved */ + u64 reserved[13]; +}; + +/* VF Input Queue statistics */ +struct octep_vf_iq_stats { + /* Instructions posted to this queue. */ + u64 instr_posted; + + /* Instructions copied by hardware for processing. */ + u64 instr_completed; + + /* Instructions that could not be processed. */ + u64 instr_dropped; + + /* Bytes sent through this queue. */ + u64 bytes_sent; + + /* Gather entries sent through this queue. */ + u64 sgentry_sent; + + /* Number of transmit failures due to TX_BUSY */ + u64 tx_busy; + + /* Number of times the queue is restarted */ + u64 restart_cnt; +}; + +/* The instruction (input) queue. + * The input queue is used to post raw (instruction) mode data or packet + * data to Octeon device from the host. Each input queue (up to 4) for + * a Octeon device has one such structure to represent it. + */ +struct octep_vf_iq { + u32 q_no; + + struct octep_vf_device *octep_vf_dev; + struct net_device *netdev; + struct device *dev; + struct netdev_queue *netdev_q; + + /* Index in input ring where driver should write the next packet */ + u16 host_write_index; + + /* Index in input ring where Octeon is expected to read next packet */ + u16 octep_vf_read_index; + + /* This index aids in finding the window in the queue where Octeon + * has read the commands. + */ + u16 flush_index; + + /* Statistics for this input queue. */ + struct octep_vf_iq_stats stats; + + /* Pointer to the Virtual Base addr of the input ring. */ + struct octep_vf_tx_desc_hw *desc_ring; + + /* DMA mapped base address of the input descriptor ring. */ + dma_addr_t desc_ring_dma; + + /* Info of Tx buffers pending completion. */ + struct octep_vf_tx_buffer *buff_info; + + /* Base pointer to Scatter/Gather lists for all ring descriptors. */ + struct octep_vf_tx_sglist_desc *sglist; + + /* DMA mapped addr of Scatter Gather Lists */ + dma_addr_t sglist_dma; + + /* Octeon doorbell register for the ring. */ + u8 __iomem *doorbell_reg; + + /* Octeon instruction count register for this ring. */ + u8 __iomem *inst_cnt_reg; + + /* interrupt level register for this ring */ + u8 __iomem *intr_lvl_reg; + + /* Maximum no. of instructions in this queue. */ + u32 max_count; + u32 ring_size_mask; + + u32 pkt_in_done; + u32 pkts_processed; + + u32 status; + + /* Number of instructions pending to be posted to Octeon. */ + u32 fill_cnt; + + /* The max. number of instructions that can be held pending by the + * driver before ringing doorbell. + */ + u32 fill_threshold; +}; + +/* Hardware Tx Instruction Header */ +struct octep_vf_instr_hdr { + /* Data Len */ + u64 tlen:16; + + /* Reserved */ + u64 rsvd:20; + + /* PKIND for SDP */ + u64 pkind:6; + + /* Front Data size */ + u64 fsz:6; + + /* No. of entries in gather list */ + u64 gsz:14; + + /* Gather indicator 1=gather*/ + u64 gather:1; + + /* Reserved3 */ + u64 reserved3:1; +}; + +static_assert(sizeof(struct octep_vf_instr_hdr) == 8); + +/* Tx offload flags */ +#define OCTEP_VF_TX_OFFLOAD_VLAN_INSERT BIT(0) +#define OCTEP_VF_TX_OFFLOAD_IPV4_CKSUM BIT(1) +#define OCTEP_VF_TX_OFFLOAD_UDP_CKSUM BIT(2) +#define OCTEP_VF_TX_OFFLOAD_TCP_CKSUM BIT(3) +#define OCTEP_VF_TX_OFFLOAD_SCTP_CKSUM BIT(4) +#define OCTEP_VF_TX_OFFLOAD_TCP_TSO BIT(5) +#define OCTEP_VF_TX_OFFLOAD_UDP_TSO BIT(6) + +#define OCTEP_VF_TX_OFFLOAD_CKSUM (OCTEP_VF_TX_OFFLOAD_IPV4_CKSUM | \ + OCTEP_VF_TX_OFFLOAD_UDP_CKSUM | \ + OCTEP_VF_TX_OFFLOAD_TCP_CKSUM) + +#define OCTEP_VF_TX_OFFLOAD_TSO (OCTEP_VF_TX_OFFLOAD_TCP_TSO | \ + OCTEP_VF_TX_OFFLOAD_UDP_TSO) + +#define OCTEP_VF_TX_IP_CSUM(flags) ((flags) & \ + (OCTEP_VF_TX_OFFLOAD_IPV4_CKSUM | \ + OCTEP_VF_TX_OFFLOAD_TCP_CKSUM | \ + OCTEP_VF_TX_OFFLOAD_UDP_CKSUM)) + +#define OCTEP_VF_TX_TSO(flags) ((flags) & \ + (OCTEP_VF_TX_OFFLOAD_TCP_TSO | \ + OCTEP_VF_TX_OFFLOAD_UDP_TSO)) + +struct tx_mdata { + /* offload flags */ + u16 ol_flags; + + /* gso size */ + u16 gso_size; + + /* gso flags */ + u16 gso_segs; + + /* reserved */ + u16 rsvd1; + + /* reserved */ + u64 rsvd2; +}; + +static_assert(sizeof(struct tx_mdata) == 16); + +/* 64-byte Tx instruction format. + * Format of instruction for a 64-byte mode input queue. + * + * only first 16-bytes (dptr and ih) are mandatory; rest are optional + * and filled by the driver based on firmware/hardware capabilities. + * These optional headers together called Front Data and its size is + * described by ih->fsz. + */ +struct octep_vf_tx_desc_hw { + /* Pointer where the input data is available. */ + u64 dptr; + + /* Instruction Header. */ + union { + struct octep_vf_instr_hdr ih; + u64 ih64; + }; + + union { + u64 txm64[2]; + struct tx_mdata txm; + }; + + /* Additional headers available in a 64-byte instruction. */ + u64 exhdr[4]; +}; + +static_assert(sizeof(struct octep_vf_tx_desc_hw) == 64); + +#define OCTEP_VF_IQ_DESC_SIZE (sizeof(struct octep_vf_tx_desc_hw)) +#endif /* _OCTEP_VF_TX_H_ */ |