vfdi.h 9.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
/****************************************************************************
 * Driver for Solarflare Solarstorm network controllers and boards
 * Copyright 2010-2012 Solarflare Communications Inc.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation, incorporated herein by reference.
 */
#ifndef _VFDI_H
#define _VFDI_H

/**
 * DOC: Virtual Function Driver Interface
 *
 * This file contains software structures used to form a two way
 * communication channel between the VF driver and the PF driver,
 * named Virtual Function Driver Interface (VFDI).
 *
 * For the purposes of VFDI, a page is a memory region with size and
 * alignment of 4K.  All addresses are DMA addresses to be used within
 * the domain of the relevant VF.
 *
 * The only hardware-defined channels for a VF driver to communicate
 * with the PF driver are the event mailboxes (%FR_CZ_USR_EV
 * registers).  Writing to these registers generates an event with
 * EV_CODE = EV_CODE_USR_EV, USER_QID set to the index of the mailbox
 * and USER_EV_REG_VALUE set to the value written.  The PF driver may
 * direct or disable delivery of these events by setting
 * %FR_CZ_USR_EV_CFG.
 *
 * The PF driver can send arbitrary events to arbitrary event queues.
 * However, for consistency, VFDI events from the PF are defined to
 * follow the same form and be sent to the first event queue assigned
 * to the VF while that queue is enabled by the VF driver.
 *
 * The general form of the variable bits of VFDI events is:
 *
 *       0             16                       24   31
 *      | DATA        | TYPE                   | SEQ   |
 *
 * SEQ is a sequence number which should be incremented by 1 (modulo
 * 256) for each event.  The sequence numbers used in each direction
 * are independent.
 *
 * The VF submits requests of type &struct vfdi_req by sending the
 * address of the request (ADDR) in a series of 4 events:
 *
 *       0             16                       24   31
 *      | ADDR[0:15]  | VFDI_EV_TYPE_REQ_WORD0 | SEQ   |
 *      | ADDR[16:31] | VFDI_EV_TYPE_REQ_WORD1 | SEQ+1 |
 *      | ADDR[32:47] | VFDI_EV_TYPE_REQ_WORD2 | SEQ+2 |
 *      | ADDR[48:63] | VFDI_EV_TYPE_REQ_WORD3 | SEQ+3 |
 *
 * The address must be page-aligned.  After receiving such a valid
 * series of events, the PF driver will attempt to read the request
 * and write a response to the same address.  In case of an invalid
 * sequence of events or a DMA error, there will be no response.
 *
 * The VF driver may request that the PF driver writes status
 * information into its domain asynchronously.  After writing the
 * status, the PF driver will send an event of the form:
 *
 *       0             16                       24   31
 *      | reserved    | VFDI_EV_TYPE_STATUS    | SEQ   |
 *
 * In case the VF must be reset for any reason, the PF driver will
 * send an event of the form:
 *
 *       0             16                       24   31
 *      | reserved    | VFDI_EV_TYPE_RESET     | SEQ   |
 *
 * It is then the responsibility of the VF driver to request
 * reinitialisation of its queues.
 */
#define VFDI_EV_SEQ_LBN 24
#define VFDI_EV_SEQ_WIDTH 8
#define VFDI_EV_TYPE_LBN 16
#define VFDI_EV_TYPE_WIDTH 8
#define VFDI_EV_TYPE_REQ_WORD0 0
#define VFDI_EV_TYPE_REQ_WORD1 1
#define VFDI_EV_TYPE_REQ_WORD2 2
#define VFDI_EV_TYPE_REQ_WORD3 3
#define VFDI_EV_TYPE_STATUS 4
#define VFDI_EV_TYPE_RESET 5
#define VFDI_EV_DATA_LBN 0
#define VFDI_EV_DATA_WIDTH 16

struct vfdi_endpoint {
	u8 mac_addr[ETH_ALEN];
	__be16 tci;
};

/**
 * enum vfdi_op - VFDI operation enumeration
 * @VFDI_OP_RESPONSE: Indicates a response to the request.
 * @VFDI_OP_INIT_EVQ: Initialize SRAM entries and initialize an EVQ.
 * @VFDI_OP_INIT_RXQ: Initialize SRAM entries and initialize an RXQ.
 * @VFDI_OP_INIT_TXQ: Initialize SRAM entries and initialize a TXQ.
 * @VFDI_OP_FINI_ALL_QUEUES: Flush all queues, finalize all queues, then
 *	finalize the SRAM entries.
 * @VFDI_OP_INSERT_FILTER: Insert a MAC filter targetting the given RXQ.
 * @VFDI_OP_REMOVE_ALL_FILTERS: Remove all filters.
 * @VFDI_OP_SET_STATUS_PAGE: Set the DMA page(s) used for status updates
 *	from PF and write the initial status.
 * @VFDI_OP_CLEAR_STATUS_PAGE: Clear the DMA page(s) used for status
 *	updates from PF.
 */
enum vfdi_op {
	VFDI_OP_RESPONSE = 0,
	VFDI_OP_INIT_EVQ = 1,
	VFDI_OP_INIT_RXQ = 2,
	VFDI_OP_INIT_TXQ = 3,
	VFDI_OP_FINI_ALL_QUEUES = 4,
	VFDI_OP_INSERT_FILTER = 5,
	VFDI_OP_REMOVE_ALL_FILTERS = 6,
	VFDI_OP_SET_STATUS_PAGE = 7,
	VFDI_OP_CLEAR_STATUS_PAGE = 8,
	VFDI_OP_LIMIT,
};

/* Response codes for VFDI operations. Other values may be used in future. */
#define VFDI_RC_SUCCESS		0
#define VFDI_RC_ENOMEM		(-12)
#define VFDI_RC_EINVAL		(-22)
#define VFDI_RC_EOPNOTSUPP	(-95)
#define VFDI_RC_ETIMEDOUT	(-110)

/**
 * struct vfdi_req - Request from VF driver to PF driver
 * @op: Operation code or response indicator, taken from &enum vfdi_op.
 * @rc: Response code.  Set to 0 on success or a negative error code on failure.
 * @u.init_evq.index: Index of event queue to create.
 * @u.init_evq.buf_count: Number of 4k buffers backing event queue.
 * @u.init_evq.addr: Array of length %u.init_evq.buf_count containing DMA
 *	address of each page backing the event queue.
 * @u.init_rxq.index: Index of receive queue to create.
 * @u.init_rxq.buf_count: Number of 4k buffers backing receive queue.
 * @u.init_rxq.evq: Instance of event queue to target receive events at.
 * @u.init_rxq.label: Label used in receive events.
 * @u.init_rxq.flags: Unused.
 * @u.init_rxq.addr: Array of length %u.init_rxq.buf_count containing DMA
 *	address of each page backing the receive queue.
 * @u.init_txq.index: Index of transmit queue to create.
 * @u.init_txq.buf_count: Number of 4k buffers backing transmit queue.
 * @u.init_txq.evq: Instance of event queue to target transmit completion
 *	events at.
 * @u.init_txq.label: Label used in transmit completion events.
 * @u.init_txq.flags: Checksum offload flags.
 * @u.init_txq.addr: Array of length %u.init_txq.buf_count containing DMA
 *	address of each page backing the transmit queue.
 * @u.mac_filter.rxq: Insert MAC filter at VF local address/VLAN targetting
 *	all traffic at this receive queue.
 * @u.mac_filter.flags: MAC filter flags.
 * @u.set_status_page.dma_addr: Base address for the &struct vfdi_status.
 *	This address must be such that the structure fits within a page.
 * @u.set_status_page.peer_page_count: Number of additional pages the VF
 *	has provided into which peer addresses may be DMAd.
 * @u.set_status_page.peer_page_addr: Array of DMA addresses of pages.
 *	If the number of peers exceeds 256, then the VF must provide
 *	additional pages in this array. The PF will then DMA up to
 *	512 vfdi_endpoint structures into each page.  These addresses
 *	must be page-aligned.
 */
struct vfdi_req {
	u32 op;
	u32 reserved1;
	s32 rc;
	u32 reserved2;
	union {
		struct {
			u32 index;
			u32 buf_count;
			u64 addr[];
		} init_evq;
		struct {
			u32 index;
			u32 buf_count;
			u32 evq;
			u32 label;
			u32 flags;
#define VFDI_RXQ_FLAG_SCATTER_EN 1
			u32 reserved;
			u64 addr[];
		} init_rxq;
		struct {
			u32 index;
			u32 buf_count;
			u32 evq;
			u32 label;
			u32 flags;
#define VFDI_TXQ_FLAG_IP_CSUM_DIS 1
#define VFDI_TXQ_FLAG_TCPUDP_CSUM_DIS 2
			u32 reserved;
			u64 addr[];
		} init_txq;
		struct {
			u32 rxq;
			u32 flags;
#define VFDI_MAC_FILTER_FLAG_RSS 1
#define VFDI_MAC_FILTER_FLAG_SCATTER 2
		} mac_filter;
		struct {
			u64 dma_addr;
			u64 peer_page_count;
			u64 peer_page_addr[];
		} set_status_page;
	} u;
};

/**
 * struct vfdi_status - Status provided by PF driver to VF driver
 * @generation_start: A generation count DMA'd to VF *before* the
 *	rest of the structure.
 * @generation_end: A generation count DMA'd to VF *after* the
 *	rest of the structure.
 * @version: Version of this structure; currently set to 1.  Later
 *	versions must either be layout-compatible or only be sent to VFs
 *	that specifically request them.
 * @length: Total length of this structure including embedded tables
 * @vi_scale: log2 the number of VIs available on this VF. This quantity
 *	is used by the hardware for register decoding.
 * @max_tx_channels: The maximum number of transmit queues the VF can use.
 * @rss_rxq_count: The number of receive queues present in the shared RSS
 *	indirection table.
 * @peer_count: Total number of peers in the complete peer list. If larger
 *	than ARRAY_SIZE(%peers), then the VF must provide sufficient
 *	additional pages each of which is filled with vfdi_endpoint structures.
 * @local: The MAC address and outer VLAN tag of *this* VF
 * @peers: Table of peer addresses.  The @tci fields in these structures
 *	are currently unused and must be ignored.  Additional peers are
 *	written into any additional pages provided by the VF.
 * @timer_quantum_ns: Timer quantum (nominal period between timer ticks)
 *	for interrupt moderation timers, in nanoseconds. This member is only
 *	present if @length is sufficiently large.
 */
struct vfdi_status {
	u32 generation_start;
	u32 generation_end;
	u32 version;
	u32 length;
	u8 vi_scale;
	u8 max_tx_channels;
	u8 rss_rxq_count;
	u8 reserved1;
	u16 peer_count;
	u16 reserved2;
	struct vfdi_endpoint local;
	struct vfdi_endpoint peers[256];

	/* Members below here extend version 1 of this structure */
	u32 timer_quantum_ns;
};

#endif