1*d48523cbSMartin Habets /* SPDX-License-Identifier: GPL-2.0-only */ 2*d48523cbSMartin Habets /**************************************************************************** 3*d48523cbSMartin Habets * Driver for Solarflare network controllers and boards 4*d48523cbSMartin Habets * Copyright 2010-2012 Solarflare Communications Inc. 5*d48523cbSMartin Habets */ 6*d48523cbSMartin Habets #ifndef _VFDI_H 7*d48523cbSMartin Habets #define _VFDI_H 8*d48523cbSMartin Habets 9*d48523cbSMartin Habets /** 10*d48523cbSMartin Habets * DOC: Virtual Function Driver Interface 11*d48523cbSMartin Habets * 12*d48523cbSMartin Habets * This file contains software structures used to form a two way 13*d48523cbSMartin Habets * communication channel between the VF driver and the PF driver, 14*d48523cbSMartin Habets * named Virtual Function Driver Interface (VFDI). 15*d48523cbSMartin Habets * 16*d48523cbSMartin Habets * For the purposes of VFDI, a page is a memory region with size and 17*d48523cbSMartin Habets * alignment of 4K. All addresses are DMA addresses to be used within 18*d48523cbSMartin Habets * the domain of the relevant VF. 19*d48523cbSMartin Habets * 20*d48523cbSMartin Habets * The only hardware-defined channels for a VF driver to communicate 21*d48523cbSMartin Habets * with the PF driver are the event mailboxes (%FR_CZ_USR_EV 22*d48523cbSMartin Habets * registers). Writing to these registers generates an event with 23*d48523cbSMartin Habets * EV_CODE = EV_CODE_USR_EV, USER_QID set to the index of the mailbox 24*d48523cbSMartin Habets * and USER_EV_REG_VALUE set to the value written. The PF driver may 25*d48523cbSMartin Habets * direct or disable delivery of these events by setting 26*d48523cbSMartin Habets * %FR_CZ_USR_EV_CFG. 27*d48523cbSMartin Habets * 28*d48523cbSMartin Habets * The PF driver can send arbitrary events to arbitrary event queues. 29*d48523cbSMartin Habets * However, for consistency, VFDI events from the PF are defined to 30*d48523cbSMartin Habets * follow the same form and be sent to the first event queue assigned 31*d48523cbSMartin Habets * to the VF while that queue is enabled by the VF driver. 32*d48523cbSMartin Habets * 33*d48523cbSMartin Habets * The general form of the variable bits of VFDI events is: 34*d48523cbSMartin Habets * 35*d48523cbSMartin Habets * 0 16 24 31 36*d48523cbSMartin Habets * | DATA | TYPE | SEQ | 37*d48523cbSMartin Habets * 38*d48523cbSMartin Habets * SEQ is a sequence number which should be incremented by 1 (modulo 39*d48523cbSMartin Habets * 256) for each event. The sequence numbers used in each direction 40*d48523cbSMartin Habets * are independent. 41*d48523cbSMartin Habets * 42*d48523cbSMartin Habets * The VF submits requests of type &struct vfdi_req by sending the 43*d48523cbSMartin Habets * address of the request (ADDR) in a series of 4 events: 44*d48523cbSMartin Habets * 45*d48523cbSMartin Habets * 0 16 24 31 46*d48523cbSMartin Habets * | ADDR[0:15] | VFDI_EV_TYPE_REQ_WORD0 | SEQ | 47*d48523cbSMartin Habets * | ADDR[16:31] | VFDI_EV_TYPE_REQ_WORD1 | SEQ+1 | 48*d48523cbSMartin Habets * | ADDR[32:47] | VFDI_EV_TYPE_REQ_WORD2 | SEQ+2 | 49*d48523cbSMartin Habets * | ADDR[48:63] | VFDI_EV_TYPE_REQ_WORD3 | SEQ+3 | 50*d48523cbSMartin Habets * 51*d48523cbSMartin Habets * The address must be page-aligned. After receiving such a valid 52*d48523cbSMartin Habets * series of events, the PF driver will attempt to read the request 53*d48523cbSMartin Habets * and write a response to the same address. In case of an invalid 54*d48523cbSMartin Habets * sequence of events or a DMA error, there will be no response. 55*d48523cbSMartin Habets * 56*d48523cbSMartin Habets * The VF driver may request that the PF driver writes status 57*d48523cbSMartin Habets * information into its domain asynchronously. After writing the 58*d48523cbSMartin Habets * status, the PF driver will send an event of the form: 59*d48523cbSMartin Habets * 60*d48523cbSMartin Habets * 0 16 24 31 61*d48523cbSMartin Habets * | reserved | VFDI_EV_TYPE_STATUS | SEQ | 62*d48523cbSMartin Habets * 63*d48523cbSMartin Habets * In case the VF must be reset for any reason, the PF driver will 64*d48523cbSMartin Habets * send an event of the form: 65*d48523cbSMartin Habets * 66*d48523cbSMartin Habets * 0 16 24 31 67*d48523cbSMartin Habets * | reserved | VFDI_EV_TYPE_RESET | SEQ | 68*d48523cbSMartin Habets * 69*d48523cbSMartin Habets * It is then the responsibility of the VF driver to request 70*d48523cbSMartin Habets * reinitialisation of its queues. 71*d48523cbSMartin Habets */ 72*d48523cbSMartin Habets #define VFDI_EV_SEQ_LBN 24 73*d48523cbSMartin Habets #define VFDI_EV_SEQ_WIDTH 8 74*d48523cbSMartin Habets #define VFDI_EV_TYPE_LBN 16 75*d48523cbSMartin Habets #define VFDI_EV_TYPE_WIDTH 8 76*d48523cbSMartin Habets #define VFDI_EV_TYPE_REQ_WORD0 0 77*d48523cbSMartin Habets #define VFDI_EV_TYPE_REQ_WORD1 1 78*d48523cbSMartin Habets #define VFDI_EV_TYPE_REQ_WORD2 2 79*d48523cbSMartin Habets #define VFDI_EV_TYPE_REQ_WORD3 3 80*d48523cbSMartin Habets #define VFDI_EV_TYPE_STATUS 4 81*d48523cbSMartin Habets #define VFDI_EV_TYPE_RESET 5 82*d48523cbSMartin Habets #define VFDI_EV_DATA_LBN 0 83*d48523cbSMartin Habets #define VFDI_EV_DATA_WIDTH 16 84*d48523cbSMartin Habets 85*d48523cbSMartin Habets struct vfdi_endpoint { 86*d48523cbSMartin Habets u8 mac_addr[ETH_ALEN]; 87*d48523cbSMartin Habets __be16 tci; 88*d48523cbSMartin Habets }; 89*d48523cbSMartin Habets 90*d48523cbSMartin Habets /** 91*d48523cbSMartin Habets * enum vfdi_op - VFDI operation enumeration 92*d48523cbSMartin Habets * @VFDI_OP_RESPONSE: Indicates a response to the request. 93*d48523cbSMartin Habets * @VFDI_OP_INIT_EVQ: Initialize SRAM entries and initialize an EVQ. 94*d48523cbSMartin Habets * @VFDI_OP_INIT_RXQ: Initialize SRAM entries and initialize an RXQ. 95*d48523cbSMartin Habets * @VFDI_OP_INIT_TXQ: Initialize SRAM entries and initialize a TXQ. 96*d48523cbSMartin Habets * @VFDI_OP_FINI_ALL_QUEUES: Flush all queues, finalize all queues, then 97*d48523cbSMartin Habets * finalize the SRAM entries. 98*d48523cbSMartin Habets * @VFDI_OP_INSERT_FILTER: Insert a MAC filter targeting the given RXQ. 99*d48523cbSMartin Habets * @VFDI_OP_REMOVE_ALL_FILTERS: Remove all filters. 100*d48523cbSMartin Habets * @VFDI_OP_SET_STATUS_PAGE: Set the DMA page(s) used for status updates 101*d48523cbSMartin Habets * from PF and write the initial status. 102*d48523cbSMartin Habets * @VFDI_OP_CLEAR_STATUS_PAGE: Clear the DMA page(s) used for status 103*d48523cbSMartin Habets * updates from PF. 104*d48523cbSMartin Habets */ 105*d48523cbSMartin Habets enum vfdi_op { 106*d48523cbSMartin Habets VFDI_OP_RESPONSE = 0, 107*d48523cbSMartin Habets VFDI_OP_INIT_EVQ = 1, 108*d48523cbSMartin Habets VFDI_OP_INIT_RXQ = 2, 109*d48523cbSMartin Habets VFDI_OP_INIT_TXQ = 3, 110*d48523cbSMartin Habets VFDI_OP_FINI_ALL_QUEUES = 4, 111*d48523cbSMartin Habets VFDI_OP_INSERT_FILTER = 5, 112*d48523cbSMartin Habets VFDI_OP_REMOVE_ALL_FILTERS = 6, 113*d48523cbSMartin Habets VFDI_OP_SET_STATUS_PAGE = 7, 114*d48523cbSMartin Habets VFDI_OP_CLEAR_STATUS_PAGE = 8, 115*d48523cbSMartin Habets VFDI_OP_LIMIT, 116*d48523cbSMartin Habets }; 117*d48523cbSMartin Habets 118*d48523cbSMartin Habets /* Response codes for VFDI operations. Other values may be used in future. */ 119*d48523cbSMartin Habets #define VFDI_RC_SUCCESS 0 120*d48523cbSMartin Habets #define VFDI_RC_ENOMEM (-12) 121*d48523cbSMartin Habets #define VFDI_RC_EINVAL (-22) 122*d48523cbSMartin Habets #define VFDI_RC_EOPNOTSUPP (-95) 123*d48523cbSMartin Habets #define VFDI_RC_ETIMEDOUT (-110) 124*d48523cbSMartin Habets 125*d48523cbSMartin Habets /** 126*d48523cbSMartin Habets * struct vfdi_req - Request from VF driver to PF driver 127*d48523cbSMartin Habets * @op: Operation code or response indicator, taken from &enum vfdi_op. 128*d48523cbSMartin Habets * @rc: Response code. Set to 0 on success or a negative error code on failure. 129*d48523cbSMartin Habets * @u.init_evq.index: Index of event queue to create. 130*d48523cbSMartin Habets * @u.init_evq.buf_count: Number of 4k buffers backing event queue. 131*d48523cbSMartin Habets * @u.init_evq.addr: Array of length %u.init_evq.buf_count containing DMA 132*d48523cbSMartin Habets * address of each page backing the event queue. 133*d48523cbSMartin Habets * @u.init_rxq.index: Index of receive queue to create. 134*d48523cbSMartin Habets * @u.init_rxq.buf_count: Number of 4k buffers backing receive queue. 135*d48523cbSMartin Habets * @u.init_rxq.evq: Instance of event queue to target receive events at. 136*d48523cbSMartin Habets * @u.init_rxq.label: Label used in receive events. 137*d48523cbSMartin Habets * @u.init_rxq.flags: Unused. 138*d48523cbSMartin Habets * @u.init_rxq.addr: Array of length %u.init_rxq.buf_count containing DMA 139*d48523cbSMartin Habets * address of each page backing the receive queue. 140*d48523cbSMartin Habets * @u.init_txq.index: Index of transmit queue to create. 141*d48523cbSMartin Habets * @u.init_txq.buf_count: Number of 4k buffers backing transmit queue. 142*d48523cbSMartin Habets * @u.init_txq.evq: Instance of event queue to target transmit completion 143*d48523cbSMartin Habets * events at. 144*d48523cbSMartin Habets * @u.init_txq.label: Label used in transmit completion events. 145*d48523cbSMartin Habets * @u.init_txq.flags: Checksum offload flags. 146*d48523cbSMartin Habets * @u.init_txq.addr: Array of length %u.init_txq.buf_count containing DMA 147*d48523cbSMartin Habets * address of each page backing the transmit queue. 148*d48523cbSMartin Habets * @u.mac_filter.rxq: Insert MAC filter at VF local address/VLAN targeting 149*d48523cbSMartin Habets * all traffic at this receive queue. 150*d48523cbSMartin Habets * @u.mac_filter.flags: MAC filter flags. 151*d48523cbSMartin Habets * @u.set_status_page.dma_addr: Base address for the &struct vfdi_status. 152*d48523cbSMartin Habets * This address must be page-aligned and the PF may write up to a 153*d48523cbSMartin Habets * whole page (allowing for extension of the structure). 154*d48523cbSMartin Habets * @u.set_status_page.peer_page_count: Number of additional pages the VF 155*d48523cbSMartin Habets * has provided into which peer addresses may be DMAd. 156*d48523cbSMartin Habets * @u.set_status_page.peer_page_addr: Array of DMA addresses of pages. 157*d48523cbSMartin Habets * If the number of peers exceeds 256, then the VF must provide 158*d48523cbSMartin Habets * additional pages in this array. The PF will then DMA up to 159*d48523cbSMartin Habets * 512 vfdi_endpoint structures into each page. These addresses 160*d48523cbSMartin Habets * must be page-aligned. 161*d48523cbSMartin Habets */ 162*d48523cbSMartin Habets struct vfdi_req { 163*d48523cbSMartin Habets u32 op; 164*d48523cbSMartin Habets u32 reserved1; 165*d48523cbSMartin Habets s32 rc; 166*d48523cbSMartin Habets u32 reserved2; 167*d48523cbSMartin Habets union { 168*d48523cbSMartin Habets struct { 169*d48523cbSMartin Habets u32 index; 170*d48523cbSMartin Habets u32 buf_count; 171*d48523cbSMartin Habets u64 addr[]; 172*d48523cbSMartin Habets } init_evq; 173*d48523cbSMartin Habets struct { 174*d48523cbSMartin Habets u32 index; 175*d48523cbSMartin Habets u32 buf_count; 176*d48523cbSMartin Habets u32 evq; 177*d48523cbSMartin Habets u32 label; 178*d48523cbSMartin Habets u32 flags; 179*d48523cbSMartin Habets #define VFDI_RXQ_FLAG_SCATTER_EN 1 180*d48523cbSMartin Habets u32 reserved; 181*d48523cbSMartin Habets u64 addr[]; 182*d48523cbSMartin Habets } init_rxq; 183*d48523cbSMartin Habets struct { 184*d48523cbSMartin Habets u32 index; 185*d48523cbSMartin Habets u32 buf_count; 186*d48523cbSMartin Habets u32 evq; 187*d48523cbSMartin Habets u32 label; 188*d48523cbSMartin Habets u32 flags; 189*d48523cbSMartin Habets #define VFDI_TXQ_FLAG_IP_CSUM_DIS 1 190*d48523cbSMartin Habets #define VFDI_TXQ_FLAG_TCPUDP_CSUM_DIS 2 191*d48523cbSMartin Habets u32 reserved; 192*d48523cbSMartin Habets u64 addr[]; 193*d48523cbSMartin Habets } init_txq; 194*d48523cbSMartin Habets struct { 195*d48523cbSMartin Habets u32 rxq; 196*d48523cbSMartin Habets u32 flags; 197*d48523cbSMartin Habets #define VFDI_MAC_FILTER_FLAG_RSS 1 198*d48523cbSMartin Habets #define VFDI_MAC_FILTER_FLAG_SCATTER 2 199*d48523cbSMartin Habets } mac_filter; 200*d48523cbSMartin Habets struct { 201*d48523cbSMartin Habets u64 dma_addr; 202*d48523cbSMartin Habets u64 peer_page_count; 203*d48523cbSMartin Habets u64 peer_page_addr[]; 204*d48523cbSMartin Habets } set_status_page; 205*d48523cbSMartin Habets } u; 206*d48523cbSMartin Habets }; 207*d48523cbSMartin Habets 208*d48523cbSMartin Habets /** 209*d48523cbSMartin Habets * struct vfdi_status - Status provided by PF driver to VF driver 210*d48523cbSMartin Habets * @generation_start: A generation count DMA'd to VF *before* the 211*d48523cbSMartin Habets * rest of the structure. 212*d48523cbSMartin Habets * @generation_end: A generation count DMA'd to VF *after* the 213*d48523cbSMartin Habets * rest of the structure. 214*d48523cbSMartin Habets * @version: Version of this structure; currently set to 1. Later 215*d48523cbSMartin Habets * versions must either be layout-compatible or only be sent to VFs 216*d48523cbSMartin Habets * that specifically request them. 217*d48523cbSMartin Habets * @length: Total length of this structure including embedded tables 218*d48523cbSMartin Habets * @vi_scale: log2 the number of VIs available on this VF. This quantity 219*d48523cbSMartin Habets * is used by the hardware for register decoding. 220*d48523cbSMartin Habets * @max_tx_channels: The maximum number of transmit queues the VF can use. 221*d48523cbSMartin Habets * @rss_rxq_count: The number of receive queues present in the shared RSS 222*d48523cbSMartin Habets * indirection table. 223*d48523cbSMartin Habets * @peer_count: Total number of peers in the complete peer list. If larger 224*d48523cbSMartin Habets * than ARRAY_SIZE(%peers), then the VF must provide sufficient 225*d48523cbSMartin Habets * additional pages each of which is filled with vfdi_endpoint structures. 226*d48523cbSMartin Habets * @local: The MAC address and outer VLAN tag of *this* VF 227*d48523cbSMartin Habets * @peers: Table of peer addresses. The @tci fields in these structures 228*d48523cbSMartin Habets * are currently unused and must be ignored. Additional peers are 229*d48523cbSMartin Habets * written into any additional pages provided by the VF. 230*d48523cbSMartin Habets * @timer_quantum_ns: Timer quantum (nominal period between timer ticks) 231*d48523cbSMartin Habets * for interrupt moderation timers, in nanoseconds. This member is only 232*d48523cbSMartin Habets * present if @length is sufficiently large. 233*d48523cbSMartin Habets */ 234*d48523cbSMartin Habets struct vfdi_status { 235*d48523cbSMartin Habets u32 generation_start; 236*d48523cbSMartin Habets u32 generation_end; 237*d48523cbSMartin Habets u32 version; 238*d48523cbSMartin Habets u32 length; 239*d48523cbSMartin Habets u8 vi_scale; 240*d48523cbSMartin Habets u8 max_tx_channels; 241*d48523cbSMartin Habets u8 rss_rxq_count; 242*d48523cbSMartin Habets u8 reserved1; 243*d48523cbSMartin Habets u16 peer_count; 244*d48523cbSMartin Habets u16 reserved2; 245*d48523cbSMartin Habets struct vfdi_endpoint local; 246*d48523cbSMartin Habets struct vfdi_endpoint peers[256]; 247*d48523cbSMartin Habets 248*d48523cbSMartin Habets /* Members below here extend version 1 of this structure */ 249*d48523cbSMartin Habets u32 timer_quantum_ns; 250*d48523cbSMartin Habets }; 251*d48523cbSMartin Habets 252*d48523cbSMartin Habets #endif 253