| /* 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_ */ |