1ce110ea1SWei Hu /*- 2ce110ea1SWei Hu * SPDX-License-Identifier: BSD-2-Clause 3ce110ea1SWei Hu * 4ce110ea1SWei Hu * Copyright (c) 2021 Microsoft Corp. 5ce110ea1SWei Hu * All rights reserved. 6ce110ea1SWei Hu * 7ce110ea1SWei Hu * Redistribution and use in source and binary forms, with or without 8ce110ea1SWei Hu * modification, are permitted provided that the following conditions 9ce110ea1SWei Hu * are met: 10ce110ea1SWei Hu * 11ce110ea1SWei Hu * 1. Redistributions of source code must retain the above copyright 12ce110ea1SWei Hu * notice, this list of conditions and the following disclaimer. 13ce110ea1SWei Hu * 14ce110ea1SWei Hu * 2. Redistributions in binary form must reproduce the above copyright 15ce110ea1SWei Hu * notice, this list of conditions and the following disclaimer in the 16ce110ea1SWei Hu * documentation and/or other materials provided with the distribution. 17ce110ea1SWei Hu * 18ce110ea1SWei Hu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19ce110ea1SWei Hu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20ce110ea1SWei Hu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21ce110ea1SWei Hu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22ce110ea1SWei Hu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23ce110ea1SWei Hu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24ce110ea1SWei Hu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25ce110ea1SWei Hu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26ce110ea1SWei Hu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27ce110ea1SWei Hu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28ce110ea1SWei Hu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29ce110ea1SWei Hu * 30ce110ea1SWei Hu */ 31ce110ea1SWei Hu 32ce110ea1SWei Hu #ifndef _MANA_H 33ce110ea1SWei Hu #define _MANA_H 34ce110ea1SWei Hu 35ce110ea1SWei Hu #include <sys/types.h> 36ce110ea1SWei Hu #include <sys/proc.h> 37ce110ea1SWei Hu #include <sys/socket.h> 38ce110ea1SWei Hu #include <sys/sysctl.h> 39ce110ea1SWei Hu #include <sys/taskqueue.h> 40ce110ea1SWei Hu #include <sys/counter.h> 41ce110ea1SWei Hu 42ce110ea1SWei Hu #include <net/ethernet.h> 43ce110ea1SWei Hu #include <net/if.h> 44ce110ea1SWei Hu #include <net/if_media.h> 45ce110ea1SWei Hu #include <netinet/tcp_lro.h> 46ce110ea1SWei Hu 47ce110ea1SWei Hu #include "gdma.h" 48ce110ea1SWei Hu #include "hw_channel.h" 49ce110ea1SWei Hu 50ce110ea1SWei Hu 51ce110ea1SWei Hu /* Microsoft Azure Network Adapter (MANA)'s definitions 52ce110ea1SWei Hu * 53ce110ea1SWei Hu * Structures labeled with "HW DATA" are exchanged with the hardware. All of 54ce110ea1SWei Hu * them are naturally aligned and hence don't need __packed. 55ce110ea1SWei Hu */ 56ce110ea1SWei Hu /* MANA protocol version */ 57ce110ea1SWei Hu #define MANA_MAJOR_VERSION 0 58ce110ea1SWei Hu #define MANA_MINOR_VERSION 1 59ce110ea1SWei Hu #define MANA_MICRO_VERSION 1 60ce110ea1SWei Hu 61ce110ea1SWei Hu #define DRV_MODULE_NAME "mana" 62ce110ea1SWei Hu 63ce110ea1SWei Hu #ifndef DRV_MODULE_VERSION 64ce110ea1SWei Hu #define DRV_MODULE_VERSION \ 65ce110ea1SWei Hu __XSTRING(MANA_MAJOR_VERSION) "." \ 66ce110ea1SWei Hu __XSTRING(MANA_MINOR_VERSION) "." \ 67ce110ea1SWei Hu __XSTRING(MANA_MICRO_VERSION) 68ce110ea1SWei Hu #endif 69ce110ea1SWei Hu #define DEVICE_NAME "Microsoft Azure Network Adapter (MANA)" 70ce110ea1SWei Hu #define DEVICE_DESC "MANA adapter" 71ce110ea1SWei Hu 72ce110ea1SWei Hu /* 73ce110ea1SWei Hu * Supported PCI vendor and devices IDs 74ce110ea1SWei Hu */ 75ce110ea1SWei Hu #ifndef PCI_VENDOR_ID_MICROSOFT 76ce110ea1SWei Hu #define PCI_VENDOR_ID_MICROSOFT 0x1414 77ce110ea1SWei Hu #endif 78ce110ea1SWei Hu 79ce110ea1SWei Hu #define PCI_DEV_ID_MANA_VF 0x00ba 80ce110ea1SWei Hu 81ce110ea1SWei Hu typedef struct _mana_vendor_id_t { 82ce110ea1SWei Hu uint16_t vendor_id; 83ce110ea1SWei Hu uint16_t device_id; 84ce110ea1SWei Hu } mana_vendor_id_t; 85ce110ea1SWei Hu 86ce110ea1SWei Hu typedef uint64_t mana_handle_t; 87ce110ea1SWei Hu #define INVALID_MANA_HANDLE ((mana_handle_t)-1) 88ce110ea1SWei Hu 89ce110ea1SWei Hu enum TRI_STATE { 90ce110ea1SWei Hu TRI_STATE_UNKNOWN = -1, 91ce110ea1SWei Hu TRI_STATE_FALSE = 0, 92ce110ea1SWei Hu TRI_STATE_TRUE = 1 93ce110ea1SWei Hu }; 94ce110ea1SWei Hu 95ce110ea1SWei Hu /* Number of entries for hardware indirection table must be in power of 2 */ 96ce110ea1SWei Hu #define MANA_INDIRECT_TABLE_SIZE 64 97ce110ea1SWei Hu #define MANA_INDIRECT_TABLE_MASK (MANA_INDIRECT_TABLE_SIZE - 1) 98ce110ea1SWei Hu 99ce110ea1SWei Hu /* The Toeplitz hash key's length in bytes: should be multiple of 8 */ 100ce110ea1SWei Hu #define MANA_HASH_KEY_SIZE 40 101ce110ea1SWei Hu 102ce110ea1SWei Hu #define COMP_ENTRY_SIZE 64 103ce110ea1SWei Hu 104ce110ea1SWei Hu #define MIN_FRAME_SIZE 146 105ce110ea1SWei Hu #define ADAPTER_MTU_SIZE 1500 106ce110ea1SWei Hu #define DEFAULT_FRAME_SIZE (ADAPTER_MTU_SIZE + 14) 107ce110ea1SWei Hu #define MAX_FRAME_SIZE 4096 108ce110ea1SWei Hu 109*a18e9994SWei Hu /* Unit number of RX buffers. Must be power of two 110*a18e9994SWei Hu * Higher number could fail at allocation. 111*a18e9994SWei Hu */ 112*a18e9994SWei Hu #define MAX_RX_BUFFERS_PER_QUEUE 8192 113*a18e9994SWei Hu #define DEF_RX_BUFFERS_PER_QUEUE 1024 114*a18e9994SWei Hu #define MIN_RX_BUFFERS_PER_QUEUE 128 115ce110ea1SWei Hu 116*a18e9994SWei Hu /* Unit number of TX buffers. Must be power of two 117*a18e9994SWei Hu * Higher number could fail at allocation. 118*a18e9994SWei Hu * The max value is derived as the maximum 119*a18e9994SWei Hu * allocatable pages supported on host per guest 120*a18e9994SWei Hu * through testing. TX buffer size beyond this 121*a18e9994SWei Hu * value is rejected by the hardware. 122*a18e9994SWei Hu */ 123*a18e9994SWei Hu #define MAX_SEND_BUFFERS_PER_QUEUE 16384 124*a18e9994SWei Hu #define DEF_SEND_BUFFERS_PER_QUEUE 1024 125*a18e9994SWei Hu #define MIN_SEND_BUFFERS_PER_QUEUE 128 126ce110ea1SWei Hu 127ce110ea1SWei Hu #define EQ_SIZE (8 * PAGE_SIZE) 128ce110ea1SWei Hu #define LOG2_EQ_THROTTLE 3 129ce110ea1SWei Hu 1301833cf13SWei Hu #define MAX_PORTS_IN_MANA_DEV 8 131ce110ea1SWei Hu 132ce110ea1SWei Hu struct mana_send_buf_info { 133ce110ea1SWei Hu struct mbuf *mbuf; 134ce110ea1SWei Hu bus_dmamap_t dma_map; 135ce110ea1SWei Hu 136ce110ea1SWei Hu /* Required to store the result of mana_gd_post_work_request. 137ce110ea1SWei Hu * gdma_posted_wqe_info.wqe_size_in_bu is required for progressing the 138ce110ea1SWei Hu * work queue when the WQE is consumed. 139ce110ea1SWei Hu */ 140ce110ea1SWei Hu struct gdma_posted_wqe_info wqe_inf; 141ce110ea1SWei Hu }; 142ce110ea1SWei Hu 143ce110ea1SWei Hu struct mana_stats { 144ce110ea1SWei Hu counter_u64_t packets; /* rx, tx */ 145ce110ea1SWei Hu counter_u64_t bytes; /* rx, tx */ 146ce110ea1SWei Hu counter_u64_t stop; /* tx */ 147ce110ea1SWei Hu counter_u64_t wakeup; /* tx */ 148ce110ea1SWei Hu counter_u64_t collapse; /* tx */ 149ce110ea1SWei Hu counter_u64_t collapse_err; /* tx */ 150ce110ea1SWei Hu counter_u64_t dma_mapping_err; /* rx, tx */ 151ce110ea1SWei Hu counter_u64_t mbuf_alloc_fail; /* rx */ 152ce110ea1SWei Hu counter_u64_t alt_chg; /* tx */ 153ce110ea1SWei Hu counter_u64_t alt_reset; /* tx */ 154516b5059SWei Hu counter_u64_t cqe_err; /* tx */ 155516b5059SWei Hu counter_u64_t cqe_unknown_type; /* tx */ 156ce110ea1SWei Hu }; 157ce110ea1SWei Hu 158ce110ea1SWei Hu struct mana_txq { 159ce110ea1SWei Hu struct gdma_queue *gdma_sq; 160ce110ea1SWei Hu 161ce110ea1SWei Hu union { 162ce110ea1SWei Hu uint32_t gdma_txq_id; 163ce110ea1SWei Hu struct { 164ce110ea1SWei Hu uint32_t reserved1 :10; 165ce110ea1SWei Hu uint32_t vsq_frame :14; 166ce110ea1SWei Hu uint32_t reserved2 :8; 167ce110ea1SWei Hu }; 168ce110ea1SWei Hu }; 169ce110ea1SWei Hu 170ce110ea1SWei Hu uint16_t vp_offset; 171ce110ea1SWei Hu 17237d22ce0SJustin Hibbits if_t ndev; 173ce110ea1SWei Hu /* Store index to the array of tx_qp in port structure */ 174ce110ea1SWei Hu int idx; 175ce110ea1SWei Hu /* The alternative txq idx when this txq is under heavy load */ 176ce110ea1SWei Hu int alt_txq_idx; 177ce110ea1SWei Hu 178ce110ea1SWei Hu /* The mbufs are sent to the HW and we are waiting for the CQEs. */ 179ce110ea1SWei Hu struct mana_send_buf_info *tx_buf_info; 180ce110ea1SWei Hu uint16_t next_to_use; 181ce110ea1SWei Hu uint16_t next_to_complete; 182ce110ea1SWei Hu 183ce110ea1SWei Hu atomic_t pending_sends; 184ce110ea1SWei Hu 185ce110ea1SWei Hu struct buf_ring *txq_br; 186ce110ea1SWei Hu struct mtx txq_mtx; 187ce110ea1SWei Hu char txq_mtx_name[16]; 188ce110ea1SWei Hu 189b167e449SWei Hu uint64_t tso_pkts; 190b167e449SWei Hu uint64_t tso_bytes; 191b167e449SWei Hu 192ce110ea1SWei Hu struct task enqueue_task; 193ce110ea1SWei Hu struct taskqueue *enqueue_tq; 194ce110ea1SWei Hu 195ce110ea1SWei Hu struct mana_stats stats; 196ce110ea1SWei Hu }; 197ce110ea1SWei Hu 198ce110ea1SWei Hu 199ce110ea1SWei Hu /* 200ce110ea1SWei Hu * Max WQE size is 512B. The first 8B is for GDMA Out of Band (OOB), 201ce110ea1SWei Hu * next is the Client OOB can be either 8B or 24B. Thus, the max 202ce110ea1SWei Hu * space for SGL entries in a singel WQE is 512 - 8 - 8 = 496B. Since each 203ce110ea1SWei Hu * SGL is 16B in size, the max number of SGLs in a WQE is 496/16 = 31. 204ce110ea1SWei Hu * Save one for emergency use, set the MAX_MBUF_FRAGS allowed to 30. 205ce110ea1SWei Hu */ 206ce110ea1SWei Hu #define MAX_MBUF_FRAGS 30 207ce110ea1SWei Hu #define MANA_TSO_MAXSEG_SZ PAGE_SIZE 208643fd7b4SWei Hu #define MANA_TSO_MAX_SZ IP_MAXPACKET 209ce110ea1SWei Hu 210ce110ea1SWei Hu /* mbuf data and frags dma mappings */ 211ce110ea1SWei Hu struct mana_mbuf_head { 212ce110ea1SWei Hu bus_addr_t dma_handle[MAX_MBUF_FRAGS + 1]; 213ce110ea1SWei Hu 214ce110ea1SWei Hu uint32_t size[MAX_MBUF_FRAGS + 1]; 215ce110ea1SWei Hu }; 216ce110ea1SWei Hu 217ce110ea1SWei Hu #define MANA_HEADROOM sizeof(struct mana_mbuf_head) 218ce110ea1SWei Hu 219ce110ea1SWei Hu enum mana_tx_pkt_format { 220ce110ea1SWei Hu MANA_SHORT_PKT_FMT = 0, 221ce110ea1SWei Hu MANA_LONG_PKT_FMT = 1, 222ce110ea1SWei Hu }; 223ce110ea1SWei Hu 224ce110ea1SWei Hu struct mana_tx_short_oob { 225ce110ea1SWei Hu uint32_t pkt_fmt :2; 226ce110ea1SWei Hu uint32_t is_outer_ipv4 :1; 227ce110ea1SWei Hu uint32_t is_outer_ipv6 :1; 228ce110ea1SWei Hu uint32_t comp_iphdr_csum :1; 229ce110ea1SWei Hu uint32_t comp_tcp_csum :1; 230ce110ea1SWei Hu uint32_t comp_udp_csum :1; 231ce110ea1SWei Hu uint32_t supress_txcqe_gen :1; 232ce110ea1SWei Hu uint32_t vcq_num :24; 233ce110ea1SWei Hu 234ce110ea1SWei Hu uint32_t trans_off :10; /* Transport header offset */ 235ce110ea1SWei Hu uint32_t vsq_frame :14; 236ce110ea1SWei Hu uint32_t short_vp_offset :8; 237ce110ea1SWei Hu }; /* HW DATA */ 238ce110ea1SWei Hu 239ce110ea1SWei Hu struct mana_tx_long_oob { 240ce110ea1SWei Hu uint32_t is_encap :1; 241ce110ea1SWei Hu uint32_t inner_is_ipv6 :1; 242ce110ea1SWei Hu uint32_t inner_tcp_opt :1; 243ce110ea1SWei Hu uint32_t inject_vlan_pri_tag :1; 244ce110ea1SWei Hu uint32_t reserved1 :12; 245ce110ea1SWei Hu uint32_t pcp :3; /* 802.1Q */ 246ce110ea1SWei Hu uint32_t dei :1; /* 802.1Q */ 247ce110ea1SWei Hu uint32_t vlan_id :12; /* 802.1Q */ 248ce110ea1SWei Hu 249ce110ea1SWei Hu uint32_t inner_frame_offset :10; 250ce110ea1SWei Hu uint32_t inner_ip_rel_offset :6; 251ce110ea1SWei Hu uint32_t long_vp_offset :12; 252ce110ea1SWei Hu uint32_t reserved2 :4; 253ce110ea1SWei Hu 254ce110ea1SWei Hu uint32_t reserved3; 255ce110ea1SWei Hu uint32_t reserved4; 256ce110ea1SWei Hu }; /* HW DATA */ 257ce110ea1SWei Hu 258ce110ea1SWei Hu struct mana_tx_oob { 259ce110ea1SWei Hu struct mana_tx_short_oob s_oob; 260ce110ea1SWei Hu struct mana_tx_long_oob l_oob; 261ce110ea1SWei Hu }; /* HW DATA */ 262ce110ea1SWei Hu 263ce110ea1SWei Hu enum mana_cq_type { 264ce110ea1SWei Hu MANA_CQ_TYPE_RX, 265ce110ea1SWei Hu MANA_CQ_TYPE_TX, 266ce110ea1SWei Hu }; 267ce110ea1SWei Hu 268ce110ea1SWei Hu enum mana_cqe_type { 269ce110ea1SWei Hu CQE_INVALID = 0, 270ce110ea1SWei Hu CQE_RX_OKAY = 1, 271ce110ea1SWei Hu CQE_RX_COALESCED_4 = 2, 272ce110ea1SWei Hu CQE_RX_OBJECT_FENCE = 3, 273ce110ea1SWei Hu CQE_RX_TRUNCATED = 4, 274ce110ea1SWei Hu 275ce110ea1SWei Hu CQE_TX_OKAY = 32, 276ce110ea1SWei Hu CQE_TX_SA_DROP = 33, 277ce110ea1SWei Hu CQE_TX_MTU_DROP = 34, 278ce110ea1SWei Hu CQE_TX_INVALID_OOB = 35, 279ce110ea1SWei Hu CQE_TX_INVALID_ETH_TYPE = 36, 280ce110ea1SWei Hu CQE_TX_HDR_PROCESSING_ERROR = 37, 281ce110ea1SWei Hu CQE_TX_VF_DISABLED = 38, 282ce110ea1SWei Hu CQE_TX_VPORT_IDX_OUT_OF_RANGE = 39, 283ce110ea1SWei Hu CQE_TX_VPORT_DISABLED = 40, 284ce110ea1SWei Hu CQE_TX_VLAN_TAGGING_VIOLATION = 41, 285ce110ea1SWei Hu }; 286ce110ea1SWei Hu 287ce110ea1SWei Hu #define MANA_CQE_COMPLETION 1 288ce110ea1SWei Hu 289ce110ea1SWei Hu struct mana_cqe_header { 290ce110ea1SWei Hu uint32_t cqe_type :6; 291ce110ea1SWei Hu uint32_t client_type :2; 292ce110ea1SWei Hu uint32_t vendor_err :24; 293ce110ea1SWei Hu }; /* HW DATA */ 294ce110ea1SWei Hu 295ce110ea1SWei Hu /* NDIS HASH Types */ 296ce110ea1SWei Hu #define NDIS_HASH_IPV4 BIT(0) 297ce110ea1SWei Hu #define NDIS_HASH_TCP_IPV4 BIT(1) 298ce110ea1SWei Hu #define NDIS_HASH_UDP_IPV4 BIT(2) 299ce110ea1SWei Hu #define NDIS_HASH_IPV6 BIT(3) 300ce110ea1SWei Hu #define NDIS_HASH_TCP_IPV6 BIT(4) 301ce110ea1SWei Hu #define NDIS_HASH_UDP_IPV6 BIT(5) 302ce110ea1SWei Hu #define NDIS_HASH_IPV6_EX BIT(6) 303ce110ea1SWei Hu #define NDIS_HASH_TCP_IPV6_EX BIT(7) 304ce110ea1SWei Hu #define NDIS_HASH_UDP_IPV6_EX BIT(8) 305ce110ea1SWei Hu 306ce110ea1SWei Hu #define MANA_HASH_L3 (NDIS_HASH_IPV4 | NDIS_HASH_IPV6 | NDIS_HASH_IPV6_EX) 307ce110ea1SWei Hu #define MANA_HASH_L4 \ 308ce110ea1SWei Hu (NDIS_HASH_TCP_IPV4 | NDIS_HASH_UDP_IPV4 | NDIS_HASH_TCP_IPV6 | \ 309ce110ea1SWei Hu NDIS_HASH_UDP_IPV6 | NDIS_HASH_TCP_IPV6_EX | NDIS_HASH_UDP_IPV6_EX) 310ce110ea1SWei Hu 311ce110ea1SWei Hu #define NDIS_HASH_IPV4_L3_MASK (NDIS_HASH_IPV4) 312ce110ea1SWei Hu #define NDIS_HASH_IPV4_L4_MASK (NDIS_HASH_TCP_IPV4 | NDIS_HASH_UDP_IPV4) 313ce110ea1SWei Hu #define NDIS_HASH_IPV6_L3_MASK (NDIS_HASH_IPV6 | NDIS_HASH_IPV6_EX) 314ce110ea1SWei Hu #define NDIS_HASH_IPV6_L4_MASK \ 315ce110ea1SWei Hu (NDIS_HASH_TCP_IPV6 | NDIS_HASH_UDP_IPV6 | \ 316ce110ea1SWei Hu NDIS_HASH_TCP_IPV6_EX | NDIS_HASH_UDP_IPV6_EX) 317ce110ea1SWei Hu #define NDIS_HASH_IPV4_MASK \ 318ce110ea1SWei Hu (NDIS_HASH_IPV4_L3_MASK | NDIS_HASH_IPV4_L4_MASK) 319ce110ea1SWei Hu #define NDIS_HASH_IPV6_MASK \ 320ce110ea1SWei Hu (NDIS_HASH_IPV6_L3_MASK | NDIS_HASH_IPV6_L4_MASK) 321ce110ea1SWei Hu 322ce110ea1SWei Hu 323ce110ea1SWei Hu struct mana_rxcomp_perpkt_info { 324ce110ea1SWei Hu uint32_t pkt_len :16; 325ce110ea1SWei Hu uint32_t reserved1 :16; 326ce110ea1SWei Hu uint32_t reserved2; 327ce110ea1SWei Hu uint32_t pkt_hash; 328ce110ea1SWei Hu }; /* HW DATA */ 329ce110ea1SWei Hu 330ce110ea1SWei Hu #define MANA_RXCOMP_OOB_NUM_PPI 4 331ce110ea1SWei Hu 332ce110ea1SWei Hu /* Receive completion OOB */ 333ce110ea1SWei Hu struct mana_rxcomp_oob { 334ce110ea1SWei Hu struct mana_cqe_header cqe_hdr; 335ce110ea1SWei Hu 336ce110ea1SWei Hu uint32_t rx_vlan_id :12; 337ce110ea1SWei Hu uint32_t rx_vlantag_present :1; 338ce110ea1SWei Hu uint32_t rx_outer_iphdr_csum_succeed :1; 339ce110ea1SWei Hu uint32_t rx_outer_iphdr_csum_fail :1; 340ce110ea1SWei Hu uint32_t reserved1 :1; 341ce110ea1SWei Hu uint32_t rx_hashtype :9; 342ce110ea1SWei Hu uint32_t rx_iphdr_csum_succeed :1; 343ce110ea1SWei Hu uint32_t rx_iphdr_csum_fail :1; 344ce110ea1SWei Hu uint32_t rx_tcp_csum_succeed :1; 345ce110ea1SWei Hu uint32_t rx_tcp_csum_fail :1; 346ce110ea1SWei Hu uint32_t rx_udp_csum_succeed :1; 347ce110ea1SWei Hu uint32_t rx_udp_csum_fail :1; 348ce110ea1SWei Hu uint32_t reserved2 :1; 349ce110ea1SWei Hu 350ce110ea1SWei Hu struct mana_rxcomp_perpkt_info ppi[MANA_RXCOMP_OOB_NUM_PPI]; 351ce110ea1SWei Hu 352ce110ea1SWei Hu uint32_t rx_wqe_offset; 353ce110ea1SWei Hu }; /* HW DATA */ 354ce110ea1SWei Hu 355ce110ea1SWei Hu struct mana_tx_comp_oob { 356ce110ea1SWei Hu struct mana_cqe_header cqe_hdr; 357ce110ea1SWei Hu 358ce110ea1SWei Hu uint32_t tx_data_offset; 359ce110ea1SWei Hu 360ce110ea1SWei Hu uint32_t tx_sgl_offset :5; 361ce110ea1SWei Hu uint32_t tx_wqe_offset :27; 362ce110ea1SWei Hu 363ce110ea1SWei Hu uint32_t reserved[12]; 364ce110ea1SWei Hu }; /* HW DATA */ 365ce110ea1SWei Hu 366ce110ea1SWei Hu struct mana_rxq; 367ce110ea1SWei Hu 3681833cf13SWei Hu #define CQE_POLLING_BUFFER 512 3691833cf13SWei Hu 370ce110ea1SWei Hu struct mana_cq { 371ce110ea1SWei Hu struct gdma_queue *gdma_cq; 372ce110ea1SWei Hu 373ce110ea1SWei Hu /* Cache the CQ id (used to verify if each CQE comes to the right CQ. */ 374ce110ea1SWei Hu uint32_t gdma_id; 375ce110ea1SWei Hu 376ce110ea1SWei Hu /* Type of the CQ: TX or RX */ 377ce110ea1SWei Hu enum mana_cq_type type; 378ce110ea1SWei Hu 379ce110ea1SWei Hu /* Pointer to the mana_rxq that is pushing RX CQEs to the queue. 380ce110ea1SWei Hu * Only and must be non-NULL if type is MANA_CQ_TYPE_RX. 381ce110ea1SWei Hu */ 382ce110ea1SWei Hu struct mana_rxq *rxq; 383ce110ea1SWei Hu 384ce110ea1SWei Hu /* Pointer to the mana_txq that is pushing TX CQEs to the queue. 385ce110ea1SWei Hu * Only and must be non-NULL if type is MANA_CQ_TYPE_TX. 386ce110ea1SWei Hu */ 387ce110ea1SWei Hu struct mana_txq *txq; 388ce110ea1SWei Hu 3891833cf13SWei Hu /* Taskqueue and related structs */ 3901833cf13SWei Hu struct task cleanup_task; 3911833cf13SWei Hu struct taskqueue *cleanup_tq; 3921833cf13SWei Hu int cpu; 3931833cf13SWei Hu bool do_not_ring_db; 3941833cf13SWei Hu 3951833cf13SWei Hu /* Budget for one cleanup task */ 3961833cf13SWei Hu int work_done; 3971833cf13SWei Hu int budget; 3981833cf13SWei Hu 3991833cf13SWei Hu /* Buffer which the CQ handler can copy the CQE's into. */ 4001833cf13SWei Hu struct gdma_comp gdma_comp_buf[CQE_POLLING_BUFFER]; 401ce110ea1SWei Hu }; 402ce110ea1SWei Hu 403ce110ea1SWei Hu struct mana_recv_buf_oob { 404ce110ea1SWei Hu /* A valid GDMA work request representing the data buffer. */ 405ce110ea1SWei Hu struct gdma_wqe_request wqe_req; 406ce110ea1SWei Hu 407ce110ea1SWei Hu struct mbuf *mbuf; 408ce110ea1SWei Hu bus_dmamap_t dma_map; 409ce110ea1SWei Hu 410ce110ea1SWei Hu /* SGL of the buffer going to be sent as part of the work request. */ 411ce110ea1SWei Hu uint32_t num_sge; 412b685df31SWei Hu struct gdma_sge sgl[MAX_RX_WQE_SGL_ENTRIES]; 413ce110ea1SWei Hu 414ce110ea1SWei Hu /* Required to store the result of mana_gd_post_work_request. 415ce110ea1SWei Hu * gdma_posted_wqe_info.wqe_size_in_bu is required for progressing the 416ce110ea1SWei Hu * work queue when the WQE is consumed. 417ce110ea1SWei Hu */ 418ce110ea1SWei Hu struct gdma_posted_wqe_info wqe_inf; 419ce110ea1SWei Hu }; 420ce110ea1SWei Hu 421ce110ea1SWei Hu struct mana_rxq { 422ce110ea1SWei Hu struct gdma_queue *gdma_rq; 423ce110ea1SWei Hu /* Cache the gdma receive queue id */ 424ce110ea1SWei Hu uint32_t gdma_id; 425ce110ea1SWei Hu 426ce110ea1SWei Hu /* Index of RQ in the vPort, not gdma receive queue id */ 427ce110ea1SWei Hu uint32_t rxq_idx; 428ce110ea1SWei Hu 429ce110ea1SWei Hu uint32_t datasize; 430ce110ea1SWei Hu 431ce110ea1SWei Hu mana_handle_t rxobj; 432ce110ea1SWei Hu 433aa108bc7SWei Hu struct completion fence_event; 434aa108bc7SWei Hu 435ce110ea1SWei Hu struct mana_cq rx_cq; 436ce110ea1SWei Hu 43737d22ce0SJustin Hibbits if_t ndev; 438ce110ea1SWei Hu struct lro_ctrl lro; 439ce110ea1SWei Hu 440ce110ea1SWei Hu /* Total number of receive buffers to be allocated */ 441ce110ea1SWei Hu uint32_t num_rx_buf; 442ce110ea1SWei Hu 443ce110ea1SWei Hu uint32_t buf_index; 444ce110ea1SWei Hu 445b167e449SWei Hu uint64_t lro_tried; 446b167e449SWei Hu uint64_t lro_failed; 447ce110ea1SWei Hu struct mana_stats stats; 448ce110ea1SWei Hu 449ce110ea1SWei Hu /* MUST BE THE LAST MEMBER: 450ce110ea1SWei Hu * Each receive buffer has an associated mana_recv_buf_oob. 451ce110ea1SWei Hu */ 452ce110ea1SWei Hu struct mana_recv_buf_oob rx_oobs[]; 453ce110ea1SWei Hu }; 454ce110ea1SWei Hu 455ce110ea1SWei Hu struct mana_tx_qp { 456ce110ea1SWei Hu struct mana_txq txq; 457ce110ea1SWei Hu 458ce110ea1SWei Hu struct mana_cq tx_cq; 459ce110ea1SWei Hu 460ce110ea1SWei Hu mana_handle_t tx_object; 461ce110ea1SWei Hu }; 462ce110ea1SWei Hu 463ce110ea1SWei Hu struct mana_port_stats { 464ce110ea1SWei Hu counter_u64_t rx_packets; 465ce110ea1SWei Hu counter_u64_t tx_packets; 466ce110ea1SWei Hu 467ce110ea1SWei Hu counter_u64_t rx_bytes; 468ce110ea1SWei Hu counter_u64_t tx_bytes; 469ce110ea1SWei Hu 470ce110ea1SWei Hu counter_u64_t rx_drops; 471ce110ea1SWei Hu counter_u64_t tx_drops; 472ce110ea1SWei Hu 473ce110ea1SWei Hu counter_u64_t stop_queue; 474ce110ea1SWei Hu counter_u64_t wake_queue; 475ce110ea1SWei Hu }; 476ce110ea1SWei Hu 477ce110ea1SWei Hu struct mana_context { 478ce110ea1SWei Hu struct gdma_dev *gdma_dev; 479ce110ea1SWei Hu 480ce110ea1SWei Hu uint16_t num_ports; 481ce110ea1SWei Hu 4821833cf13SWei Hu struct mana_eq *eqs; 4831833cf13SWei Hu 48437d22ce0SJustin Hibbits if_t ports[MAX_PORTS_IN_MANA_DEV]; 485ce110ea1SWei Hu }; 486ce110ea1SWei Hu 487ce110ea1SWei Hu struct mana_port_context { 488ce110ea1SWei Hu struct mana_context *ac; 48937d22ce0SJustin Hibbits if_t ndev; 490ce110ea1SWei Hu struct ifmedia media; 491ce110ea1SWei Hu 492ce110ea1SWei Hu struct sx apc_lock; 493ce110ea1SWei Hu 494ce110ea1SWei Hu /* DMA tag used for queue bufs of the entire port */ 495ce110ea1SWei Hu bus_dma_tag_t rx_buf_tag; 496ce110ea1SWei Hu bus_dma_tag_t tx_buf_tag; 497ce110ea1SWei Hu 498ce110ea1SWei Hu uint8_t mac_addr[ETHER_ADDR_LEN]; 499ce110ea1SWei Hu 500ce110ea1SWei Hu enum TRI_STATE rss_state; 501ce110ea1SWei Hu 502ce110ea1SWei Hu mana_handle_t default_rxobj; 503ce110ea1SWei Hu bool tx_shortform_allowed; 504ce110ea1SWei Hu uint16_t tx_vp_offset; 505ce110ea1SWei Hu 506ce110ea1SWei Hu struct mana_tx_qp *tx_qp; 507ce110ea1SWei Hu 508ce110ea1SWei Hu /* Indirection Table for RX & TX. The values are queue indexes */ 509ce110ea1SWei Hu uint32_t indir_table[MANA_INDIRECT_TABLE_SIZE]; 510ce110ea1SWei Hu 511ce110ea1SWei Hu /* Indirection table containing RxObject Handles */ 512ce110ea1SWei Hu mana_handle_t rxobj_table[MANA_INDIRECT_TABLE_SIZE]; 513ce110ea1SWei Hu 514ce110ea1SWei Hu /* Hash key used by the NIC */ 515ce110ea1SWei Hu uint8_t hashkey[MANA_HASH_KEY_SIZE]; 516ce110ea1SWei Hu 517ce110ea1SWei Hu /* This points to an array of num_queues of RQ pointers. */ 518ce110ea1SWei Hu struct mana_rxq **rxqs; 519ce110ea1SWei Hu 520ce110ea1SWei Hu /* Create num_queues EQs, SQs, SQ-CQs, RQs and RQ-CQs, respectively. */ 521ce110ea1SWei Hu unsigned int max_queues; 522ce110ea1SWei Hu unsigned int num_queues; 523ce110ea1SWei Hu 524*a18e9994SWei Hu unsigned int tx_queue_size; 525*a18e9994SWei Hu unsigned int rx_queue_size; 526*a18e9994SWei Hu 527ce110ea1SWei Hu mana_handle_t port_handle; 528ce110ea1SWei Hu 529b685df31SWei Hu int vport_use_count; 530b685df31SWei Hu 531ce110ea1SWei Hu uint16_t port_idx; 532ce110ea1SWei Hu 533ce110ea1SWei Hu uint16_t frame_size; 534ce110ea1SWei Hu 535ce110ea1SWei Hu bool port_is_up; 536ce110ea1SWei Hu bool port_st_save; /* Saved port state */ 537ce110ea1SWei Hu 538ce110ea1SWei Hu bool enable_tx_altq; 5391833cf13SWei Hu 540ce110ea1SWei Hu bool bind_cleanup_thread_cpu; 5411833cf13SWei Hu int last_tx_cq_bind_cpu; 5421833cf13SWei Hu int last_rx_cq_bind_cpu; 543ce110ea1SWei Hu 544ce110ea1SWei Hu struct mana_port_stats port_stats; 545ce110ea1SWei Hu 546ce110ea1SWei Hu struct sysctl_oid_list *port_list; 547ce110ea1SWei Hu struct sysctl_ctx_list que_sysctl_ctx; 548ce110ea1SWei Hu }; 549ce110ea1SWei Hu 550ce110ea1SWei Hu #define MANA_APC_LOCK_INIT(apc) \ 551ce110ea1SWei Hu sx_init(&(apc)->apc_lock, "MANA port lock") 552ce110ea1SWei Hu #define MANA_APC_LOCK_DESTROY(apc) sx_destroy(&(apc)->apc_lock) 553ce110ea1SWei Hu #define MANA_APC_LOCK_LOCK(apc) sx_xlock(&(apc)->apc_lock) 554ce110ea1SWei Hu #define MANA_APC_LOCK_UNLOCK(apc) sx_unlock(&(apc)->apc_lock) 555ce110ea1SWei Hu 556ce110ea1SWei Hu int mana_config_rss(struct mana_port_context *ac, enum TRI_STATE rx, 557ce110ea1SWei Hu bool update_hash, bool update_tab); 558ce110ea1SWei Hu 55937d22ce0SJustin Hibbits int mana_alloc_queues(if_t ndev); 56037d22ce0SJustin Hibbits int mana_attach(if_t ndev); 56137d22ce0SJustin Hibbits int mana_detach(if_t ndev); 562ce110ea1SWei Hu 563ce110ea1SWei Hu int mana_probe(struct gdma_dev *gd); 564ce110ea1SWei Hu void mana_remove(struct gdma_dev *gd); 565ce110ea1SWei Hu 566ce110ea1SWei Hu struct mana_obj_spec { 567ce110ea1SWei Hu uint32_t queue_index; 568ce110ea1SWei Hu uint64_t gdma_region; 569ce110ea1SWei Hu uint32_t queue_size; 570ce110ea1SWei Hu uint32_t attached_eq; 571ce110ea1SWei Hu uint32_t modr_ctx_id; 572ce110ea1SWei Hu }; 573ce110ea1SWei Hu 574ce110ea1SWei Hu enum mana_command_code { 575ce110ea1SWei Hu MANA_QUERY_DEV_CONFIG = 0x20001, 576ce110ea1SWei Hu MANA_QUERY_GF_STAT = 0x20002, 577ce110ea1SWei Hu MANA_CONFIG_VPORT_TX = 0x20003, 578ce110ea1SWei Hu MANA_CREATE_WQ_OBJ = 0x20004, 579ce110ea1SWei Hu MANA_DESTROY_WQ_OBJ = 0x20005, 580ce110ea1SWei Hu MANA_FENCE_RQ = 0x20006, 581ce110ea1SWei Hu MANA_CONFIG_VPORT_RX = 0x20007, 582ce110ea1SWei Hu MANA_QUERY_VPORT_CONFIG = 0x20008, 583ce110ea1SWei Hu }; 584ce110ea1SWei Hu 585ce110ea1SWei Hu /* Query Device Configuration */ 586ce110ea1SWei Hu struct mana_query_device_cfg_req { 587ce110ea1SWei Hu struct gdma_req_hdr hdr; 588ce110ea1SWei Hu 589ce110ea1SWei Hu /* Driver Capability flags */ 590ce110ea1SWei Hu uint64_t drv_cap_flags1; 591ce110ea1SWei Hu uint64_t drv_cap_flags2; 592ce110ea1SWei Hu uint64_t drv_cap_flags3; 593ce110ea1SWei Hu uint64_t drv_cap_flags4; 594ce110ea1SWei Hu 595ce110ea1SWei Hu uint32_t proto_major_ver; 596ce110ea1SWei Hu uint32_t proto_minor_ver; 597ce110ea1SWei Hu uint32_t proto_micro_ver; 598ce110ea1SWei Hu 599ce110ea1SWei Hu uint32_t reserved; 600ce110ea1SWei Hu }; /* HW DATA */ 601ce110ea1SWei Hu 602ce110ea1SWei Hu struct mana_query_device_cfg_resp { 603ce110ea1SWei Hu struct gdma_resp_hdr hdr; 604ce110ea1SWei Hu 605ce110ea1SWei Hu uint64_t pf_cap_flags1; 606ce110ea1SWei Hu uint64_t pf_cap_flags2; 607ce110ea1SWei Hu uint64_t pf_cap_flags3; 608ce110ea1SWei Hu uint64_t pf_cap_flags4; 609ce110ea1SWei Hu 610ce110ea1SWei Hu uint16_t max_num_vports; 611ce110ea1SWei Hu uint16_t reserved; 612ce110ea1SWei Hu uint32_t max_num_eqs; 613ce110ea1SWei Hu }; /* HW DATA */ 614ce110ea1SWei Hu 615ce110ea1SWei Hu /* Query vPort Configuration */ 616ce110ea1SWei Hu struct mana_query_vport_cfg_req { 617ce110ea1SWei Hu struct gdma_req_hdr hdr; 618ce110ea1SWei Hu uint32_t vport_index; 619ce110ea1SWei Hu }; /* HW DATA */ 620ce110ea1SWei Hu 621ce110ea1SWei Hu struct mana_query_vport_cfg_resp { 622ce110ea1SWei Hu struct gdma_resp_hdr hdr; 623ce110ea1SWei Hu uint32_t max_num_sq; 624ce110ea1SWei Hu uint32_t max_num_rq; 625ce110ea1SWei Hu uint32_t num_indirection_ent; 626ce110ea1SWei Hu uint32_t reserved1; 627ce110ea1SWei Hu uint8_t mac_addr[6]; 628ce110ea1SWei Hu uint8_t reserved2[2]; 629ce110ea1SWei Hu mana_handle_t vport; 630ce110ea1SWei Hu }; /* HW DATA */ 631ce110ea1SWei Hu 632ce110ea1SWei Hu /* Configure vPort */ 633ce110ea1SWei Hu struct mana_config_vport_req { 634ce110ea1SWei Hu struct gdma_req_hdr hdr; 635ce110ea1SWei Hu mana_handle_t vport; 636ce110ea1SWei Hu uint32_t pdid; 637ce110ea1SWei Hu uint32_t doorbell_pageid; 638ce110ea1SWei Hu }; /* HW DATA */ 639ce110ea1SWei Hu 640ce110ea1SWei Hu struct mana_config_vport_resp { 641ce110ea1SWei Hu struct gdma_resp_hdr hdr; 642ce110ea1SWei Hu uint16_t tx_vport_offset; 643ce110ea1SWei Hu uint8_t short_form_allowed; 644ce110ea1SWei Hu uint8_t reserved; 645ce110ea1SWei Hu }; /* HW DATA */ 646ce110ea1SWei Hu 647ce110ea1SWei Hu /* Create WQ Object */ 648ce110ea1SWei Hu struct mana_create_wqobj_req { 649ce110ea1SWei Hu struct gdma_req_hdr hdr; 650ce110ea1SWei Hu mana_handle_t vport; 651ce110ea1SWei Hu uint32_t wq_type; 652ce110ea1SWei Hu uint32_t reserved; 653ce110ea1SWei Hu uint64_t wq_gdma_region; 654ce110ea1SWei Hu uint64_t cq_gdma_region; 655ce110ea1SWei Hu uint32_t wq_size; 656ce110ea1SWei Hu uint32_t cq_size; 657ce110ea1SWei Hu uint32_t cq_moderation_ctx_id; 658ce110ea1SWei Hu uint32_t cq_parent_qid; 659ce110ea1SWei Hu }; /* HW DATA */ 660ce110ea1SWei Hu 661ce110ea1SWei Hu struct mana_create_wqobj_resp { 662ce110ea1SWei Hu struct gdma_resp_hdr hdr; 663ce110ea1SWei Hu uint32_t wq_id; 664ce110ea1SWei Hu uint32_t cq_id; 665ce110ea1SWei Hu mana_handle_t wq_obj; 666ce110ea1SWei Hu }; /* HW DATA */ 667ce110ea1SWei Hu 668ce110ea1SWei Hu /* Destroy WQ Object */ 669ce110ea1SWei Hu struct mana_destroy_wqobj_req { 670ce110ea1SWei Hu struct gdma_req_hdr hdr; 671ce110ea1SWei Hu uint32_t wq_type; 672ce110ea1SWei Hu uint32_t reserved; 673ce110ea1SWei Hu mana_handle_t wq_obj_handle; 674ce110ea1SWei Hu }; /* HW DATA */ 675ce110ea1SWei Hu 676ce110ea1SWei Hu struct mana_destroy_wqobj_resp { 677ce110ea1SWei Hu struct gdma_resp_hdr hdr; 678ce110ea1SWei Hu }; /* HW DATA */ 679ce110ea1SWei Hu 680ce110ea1SWei Hu /* Fence RQ */ 681ce110ea1SWei Hu struct mana_fence_rq_req { 682ce110ea1SWei Hu struct gdma_req_hdr hdr; 683ce110ea1SWei Hu mana_handle_t wq_obj_handle; 684ce110ea1SWei Hu }; /* HW DATA */ 685ce110ea1SWei Hu 686ce110ea1SWei Hu struct mana_fence_rq_resp { 687ce110ea1SWei Hu struct gdma_resp_hdr hdr; 688ce110ea1SWei Hu }; /* HW DATA */ 689ce110ea1SWei Hu 690ce110ea1SWei Hu /* Configure vPort Rx Steering */ 691ce110ea1SWei Hu struct mana_cfg_rx_steer_req { 692ce110ea1SWei Hu struct gdma_req_hdr hdr; 693ce110ea1SWei Hu mana_handle_t vport; 694ce110ea1SWei Hu uint16_t num_indir_entries; 695ce110ea1SWei Hu uint16_t indir_tab_offset; 696ce110ea1SWei Hu uint32_t rx_enable; 697ce110ea1SWei Hu uint32_t rss_enable; 698ce110ea1SWei Hu uint8_t update_default_rxobj; 699ce110ea1SWei Hu uint8_t update_hashkey; 700ce110ea1SWei Hu uint8_t update_indir_tab; 701ce110ea1SWei Hu uint8_t reserved; 702ce110ea1SWei Hu mana_handle_t default_rxobj; 703ce110ea1SWei Hu uint8_t hashkey[MANA_HASH_KEY_SIZE]; 704ce110ea1SWei Hu }; /* HW DATA */ 705ce110ea1SWei Hu 706ce110ea1SWei Hu struct mana_cfg_rx_steer_resp { 707ce110ea1SWei Hu struct gdma_resp_hdr hdr; 708ce110ea1SWei Hu }; /* HW DATA */ 709ce110ea1SWei Hu 710ce110ea1SWei Hu #define MANA_MAX_NUM_QUEUES 16 711ce110ea1SWei Hu 712ce110ea1SWei Hu #define MANA_SHORT_VPORT_OFFSET_MAX ((1U << 8) - 1) 713ce110ea1SWei Hu 714ce110ea1SWei Hu struct mana_tx_package { 715ce110ea1SWei Hu struct gdma_wqe_request wqe_req; 716ce110ea1SWei Hu struct gdma_sge sgl_array[MAX_MBUF_FRAGS]; 717ce110ea1SWei Hu 718ce110ea1SWei Hu struct mana_tx_oob tx_oob; 719ce110ea1SWei Hu 720ce110ea1SWei Hu struct gdma_posted_wqe_info wqe_info; 721ce110ea1SWei Hu }; 722ce110ea1SWei Hu 723ce110ea1SWei Hu int mana_restart(struct mana_port_context *apc); 724ce110ea1SWei Hu 725b685df31SWei Hu int mana_create_wq_obj(struct mana_port_context *apc, 726b685df31SWei Hu mana_handle_t vport, 727b685df31SWei Hu uint32_t wq_type, struct mana_obj_spec *wq_spec, 728b685df31SWei Hu struct mana_obj_spec *cq_spec, 729b685df31SWei Hu mana_handle_t *wq_obj); 730b685df31SWei Hu 731b685df31SWei Hu void mana_destroy_wq_obj(struct mana_port_context *apc, uint32_t wq_type, 732b685df31SWei Hu mana_handle_t wq_obj); 733b685df31SWei Hu 734b685df31SWei Hu int mana_cfg_vport(struct mana_port_context *apc, uint32_t protection_dom_id, 735b685df31SWei Hu uint32_t doorbell_pg_id); 736b685df31SWei Hu 737b685df31SWei Hu void mana_uncfg_vport(struct mana_port_context *apc); 738ce110ea1SWei Hu #endif /* _MANA_H */ 739