1 /****************************************************************************
2 * Copyright 2002-2005: Level 5 Networks Inc.
3 * Copyright 2005-2008: Solarflare Communications Inc,
4 * 9501 Jeronimo Road, Suite 250,
5 * Irvine, CA 92618, USA
7 * Maintained by Solarflare Communications
8 * <linux-xen-drivers@solarflare.com>
9 * <onload-dev@solarflare.com>
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published
13 * by the Free Software Foundation, incorporated herein by reference.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 ****************************************************************************
27 * \brief Virtual Interface
31 #ifndef __EFAB_EF_VI_H__
32 #define __EFAB_EF_VI_H__
35 /**********************************************************************
36 * Primitive types ****************************************************
37 **********************************************************************/
39 /* We standardise on the types from stdint.h and synthesise these types
40 * for compilers/platforms that don't provide them */
42 # include <linux/types.h>
43 # define EF_VI_ALIGN(x) __attribute__ ((aligned (x)))
44 # define ef_vi_inline static inline
48 /**********************************************************************
49 * Types **************************************************************
50 **********************************************************************/
52 typedef uint32_t ef_eventq_ptr;
54 typedef uint64_t ef_addr;
55 typedef char* ef_vi_ioaddr_t;
57 /**********************************************************************
58 * ef_event ***********************************************************
59 **********************************************************************/
61 /*! \i_ef_vi A DMA request identifier.
63 ** This is an integer token specified by the transport and associated
64 ** with a DMA request. It is returned to the VI user with DMA completion
65 ** events. It is typically used to identify the buffer associated with
68 typedef int ef_request_id;
75 typedef ef_vi_qword ef_hw_event;
77 #define EF_REQUEST_ID_BITS 16u
78 #define EF_REQUEST_ID_MASK ((1u << EF_REQUEST_ID_BITS) - 1u)
80 /*! \i_ef_event An [ef_event] is a token that identifies something that
81 ** has happened. Examples include packets received, packets transmitted
92 /*ef_request_id request_id :EF_REQUEST_ID_BITS;*/
97 struct { /* This *must* have same layout as [rx]. */
100 /*ef_request_id request_id :EF_REQUEST_ID_BITS;*/
104 unsigned subtype :16;
109 /*ef_request_id request_id :EF_REQUEST_ID_BITS;*/
115 /*ef_request_id request_id :EF_REQUEST_ID_BITS;*/
117 unsigned subtype :16;
132 #define EF_EVENT_TYPE(e) ((e).generic.type)
134 /** Good data was received. */
136 /** Packets have been sent. */
138 /** Data received and buffer consumed, but something is wrong. */
139 EF_EVENT_TYPE_RX_DISCARD,
140 /** Transmit of packet failed. */
141 EF_EVENT_TYPE_TX_ERROR,
142 /** Received packet was truncated due to lack of descriptors. */
143 EF_EVENT_TYPE_RX_NO_DESC_TRUNC,
144 /** Software generated event. */
146 /** Event queue overflow. */
150 #define EF_EVENT_RX_BYTES(e) ((e).rx.len)
151 #define EF_EVENT_RX_Q_ID(e) ((e).rx.q_id)
152 #define EF_EVENT_RX_CONT(e) ((e).rx.flags & EF_EVENT_FLAG_CONT)
153 #define EF_EVENT_RX_SOP(e) ((e).rx.flags & EF_EVENT_FLAG_SOP)
154 #define EF_EVENT_RX_ISCSI_OKAY(e) ((e).rx.flags & EF_EVENT_FLAG_ISCSI_OK)
155 #define EF_EVENT_FLAG_SOP 0x1
156 #define EF_EVENT_FLAG_CONT 0x2
157 #define EF_EVENT_FLAG_ISCSI_OK 0x4
159 #define EF_EVENT_TX_Q_ID(e) ((e).tx.q_id)
161 #define EF_EVENT_RX_DISCARD_Q_ID(e) ((e).rx_discard.q_id)
162 #define EF_EVENT_RX_DISCARD_LEN(e) ((e).rx_discard.len)
163 #define EF_EVENT_RX_DISCARD_TYPE(e) ((e).rx_discard.subtype)
165 EF_EVENT_RX_DISCARD_CSUM_BAD,
166 EF_EVENT_RX_DISCARD_CRC_BAD,
167 EF_EVENT_RX_DISCARD_TRUNC,
168 EF_EVENT_RX_DISCARD_RIGHTS,
169 EF_EVENT_RX_DISCARD_OTHER,
172 #define EF_EVENT_TX_ERROR_Q_ID(e) ((e).tx_error.q_id)
173 #define EF_EVENT_TX_ERROR_TYPE(e) ((e).tx_error.subtype)
175 EF_EVENT_TX_ERROR_RIGHTS,
176 EF_EVENT_TX_ERROR_OFLOW,
177 EF_EVENT_TX_ERROR_2BIG,
178 EF_EVENT_TX_ERROR_BUS,
181 #define EF_EVENT_RX_NO_DESC_TRUNC_Q_ID(e) ((e).rx_no_desc_trunc.q_id)
183 #define EF_EVENT_SW_DATA_MASK 0xffff
184 #define EF_EVENT_SW_DATA(e) ((e).sw.data)
186 #define EF_EVENT_FMT "[ev:%x:%08x:%08x]"
187 #define EF_EVENT_PRI_ARG(e) (unsigned) (e).generic.type, \
188 (unsigned) (e).generic.ev.u32[1], \
189 (unsigned) (e).generic.ev.u32[0]
191 #define EF_GET_HW_EV(e) ((e).generic.ev)
192 #define EF_GET_HW_EV_PTR(e) (&(e).generic.ev)
193 #define EF_GET_HW_EV_U64(e) ((e).generic.ev.u64[0])
196 /* ***************** */
198 /*! Used by netif shared state. Must use types of explicit size. */
200 uint16_t rx_last_desc_ptr; /* for RX duplicates */
201 uint8_t bad_sop; /* bad SOP detected */
202 uint8_t frag_num; /* next fragment #, 0=>SOP */
206 /* Max number of ports on any SF NIC. */
207 #define EFAB_DMAQS_PER_EVQ_MAX 32
210 ef_eventq_ptr evq_ptr;
212 ef_rx_dup_state_t rx_dup_state[EFAB_DMAQS_PER_EVQ_MAX];
216 /*! \i_ef_base [ef_iovec] is similar the standard [struct iovec]. An
217 ** array of these is used to designate a scatter/gather list of I/O
221 ef_addr iov_base EF_VI_ALIGN(8);
225 /* Falcon constants */
226 #define TX_EV_DESC_PTR_LBN 0
229 /**********************************************************************
230 * ef_vi **************************************************************
231 **********************************************************************/
234 EF_VI_RX_SCATTER = 0x1,
235 EF_VI_ISCSI_RX_HDIG = 0x2,
236 EF_VI_ISCSI_TX_HDIG = 0x4,
237 EF_VI_ISCSI_RX_DDIG = 0x8,
238 EF_VI_ISCSI_TX_DDIG = 0x10,
239 EF_VI_TX_PHYS_ADDR = 0x20,
240 EF_VI_RX_PHYS_ADDR = 0x40,
241 EF_VI_TX_IP_CSUM_DIS = 0x80,
242 EF_VI_TX_TCPUDP_CSUM_DIS= 0x100,
243 EF_VI_TX_TCPUDP_ONLY = 0x200,
244 /* Flags in range 0xXXXX0000 are for internal use. */
262 unsigned misalign_mask;
276 /* Followed by request id fifos. */
279 /*! \i_ef_vi A virtual interface.
281 ** An [ef_vi] represents a virtual interface on a specific NIC. A
282 ** virtual interface is a collection of an event queue and two DMA queues
283 ** used to pass Ethernet frames between the transport implementation and
286 typedef struct ef_vi {
289 unsigned vi_resource_id;
290 unsigned vi_resource_handle_hack;
293 char* vi_mem_mmap_ptr;
294 int vi_mem_mmap_bytes;
295 char* vi_io_mmap_ptr;
296 int vi_io_mmap_bytes;
298 ef_eventq_state* evq_state;
301 ef_vi_ioaddr_t evq_timer_reg;
305 ef_vi_state* ep_state;
306 enum ef_vi_flags vi_flags;
315 struct ef_vi_nic_type {
318 unsigned char revision;
322 /* This structure is opaque to the client & used to pass mapping data
323 * from the resource manager to the ef_vi lib. for ef_vi_init().
327 # define VI_MAPPING_VERSION 0x02 /*Byte: Increment me if struct altered*/
328 # define VI_MAPPING_SIGNATURE (0xBA1150 + VI_MAPPING_VERSION)
330 struct ef_vi_nic_type nic_type;
336 ef_vi_ioaddr_t evq_timer_reg;
338 unsigned rx_queue_capacity;
339 ef_vi_ioaddr_t rx_dma_ef1;
341 ef_vi_ioaddr_t rx_bell;
343 unsigned tx_queue_capacity;
344 ef_vi_ioaddr_t tx_dma_ef1;
346 ef_vi_ioaddr_t tx_bell;
348 /* This is used by clients to allocate a suitably sized buffer for the
349 * resource manager to fill & ef_vi_init() to use. */
350 #define VI_MAPPINGS_SIZE (sizeof(struct vi_mappings))
353 /**********************************************************************
354 * ef_config **********************************************************
355 **********************************************************************/
358 int log; /* debug logging level */
361 extern struct ef_config_t ef_config;
364 /**********************************************************************
365 * ef_vi **************************************************************
366 **********************************************************************/
368 /* Initialise [data_area] with information required to initialise an ef_vi.
369 * In the following, an unused param should be set to NULL. Note the case
370 * marked (*) of [iobuf_mmap] for falcon/driver; for normal driver this
373 * \param data_area [in,out] required, must ref at least VI_MAPPINGS_SIZE
375 * \param evq_capacity [in] number of events in event queue. Specify 0 for
377 * \param rxq_capacity [in] number of descriptors in RX DMA queue. Specify
379 * \param txq_capacity [in] number of descriptors in TX DMA queue. Specify
381 * \param mmap_info [in] mem-map info for resource
382 * \param io_mmap [in] ef1, required
384 * \param iobuf_mmap [in] ef1, UL: unused
385 * falcon, UL: required
387 extern void ef_vi_init_mapping_vi(void* data_area, struct ef_vi_nic_type,
388 unsigned rxq_capacity,
389 unsigned txq_capacity, int instance,
390 void* io_mmap, void* iobuf_mmap_rx,
391 void* iobuf_mmap_tx, enum ef_vi_flags);
394 extern void ef_vi_init_mapping_evq(void* data_area, struct ef_vi_nic_type,
395 int instance, unsigned evq_bytes,
396 void* base, void* timer_reg);
398 ef_vi_inline unsigned ef_vi_resource_id(ef_vi* vi)
400 return vi->vi_resource_id;
403 ef_vi_inline enum ef_vi_flags ef_vi_flags(ef_vi* vi)
409 /**********************************************************************
410 * Receive interface **************************************************
411 **********************************************************************/
413 /*! \i_ef_vi Returns the amount of space in the RX descriptor ring.
415 ** \return the amount of space in the queue.
417 ef_vi_inline int ef_vi_receive_space(ef_vi* vi)
419 ef_vi_rxq_state* qs = &vi->ep_state->rxq;
420 return vi->vi_rxq.mask - (qs->added - qs->removed);
424 /*! \i_ef_vi Returns the fill level of the RX descriptor ring.
426 ** \return the fill level of the queue.
428 ef_vi_inline int ef_vi_receive_fill_level(ef_vi* vi)
430 ef_vi_rxq_state* qs = &vi->ep_state->rxq;
431 return qs->added - qs->removed;
435 ef_vi_inline int ef_vi_receive_capacity(ef_vi* vi)
437 return vi->vi_rxq.mask;
440 /*! \i_ef_vi Complete a receive operation.
442 ** When a receive completion event is received, it should be passed to
443 ** this function. The request-id for the buffer that the packet was
444 ** delivered to is returned.
446 ** After this function returns, more space may be available in the
449 extern ef_request_id ef_vi_receive_done(const ef_vi*, const ef_event*);
451 /*! \i_ef_vi Return request ID indicated by a receive event
453 ef_vi_inline ef_request_id ef_vi_receive_request_id(const ef_vi* vi,
454 const ef_event* ef_ev)
456 const ef_vi_qword* ev = EF_GET_HW_EV_PTR(*ef_ev);
457 return ev->u32[0] & vi->vi_rxq.mask;
461 /*! \i_ef_vi Form a receive descriptor.
463 ** If \c initial_rx_bytes is zero use a reception size at least as large
466 extern int ef_vi_receive_init(ef_vi* vi, ef_addr addr, ef_request_id dma_id,
467 int intial_rx_bytes);
469 /*! \i_ef_vi Submit initialised receive descriptors to the NIC. */
470 extern void ef_vi_receive_push(ef_vi* vi);
472 /*! \i_ef_vi Post a buffer on the receive queue.
474 ** \return 0 on success, or -EAGAIN if the receive queue is full
476 extern int ef_vi_receive_post(ef_vi*, ef_addr addr,
477 ef_request_id dma_id);
479 /**********************************************************************
480 * Transmit interface *************************************************
481 **********************************************************************/
483 /*! \i_ef_vi Return the amount of space (in descriptors) in the transmit
486 ** \return the amount of space in the queue (in descriptors)
488 ef_vi_inline int ef_vi_transmit_space(ef_vi* vi)
490 ef_vi_txq_state* qs = &vi->ep_state->txq;
491 return vi->vi_txq.mask - (qs->added - qs->removed);
495 /*! \i_ef_vi Returns the fill level of the TX descriptor ring.
497 ** \return the fill level of the queue.
499 ef_vi_inline int ef_vi_transmit_fill_level(ef_vi* vi)
501 ef_vi_txq_state* qs = &vi->ep_state->txq;
502 return qs->added - qs->removed;
506 /*! \i_ef_vi Returns the total capacity of the TX descriptor ring.
508 ** \return the capacity of the queue.
510 ef_vi_inline int ef_vi_transmit_capacity(ef_vi* vi)
512 return vi->vi_txq.mask;
516 /*! \i_ef_vi Transmit a packet.
518 ** \param bytes must be greater than ETH_ZLEN.
519 ** \return -EAGAIN if the transmit queue is full, or 0 on success
521 extern int ef_vi_transmit(ef_vi*, ef_addr, int bytes, ef_request_id dma_id);
523 /*! \i_ef_vi Transmit a packet using a gather list.
525 ** \param iov_len must be greater than zero
526 ** \param iov the first must be non-zero in length (but others need not)
528 ** \return -EAGAIN if the queue is full, or 0 on success
530 extern int ef_vi_transmitv(ef_vi*, const ef_iovec* iov, int iov_len,
531 ef_request_id dma_id);
533 /*! \i_ef_vi Initialise a DMA request.
535 ** \return -EAGAIN if the queue is full, or 0 on success
537 extern int ef_vi_transmit_init(ef_vi*, ef_addr, int bytes,
538 ef_request_id dma_id);
540 /*! \i_ef_vi Initialise a DMA request.
542 ** \return -EAGAIN if the queue is full, or 0 on success
544 extern int ef_vi_transmitv_init(ef_vi*, const ef_iovec*, int iov_len,
545 ef_request_id dma_id);
547 /*! \i_ef_vi Submit DMA requests to the NIC.
549 ** The DMA requests must have been initialised using
550 ** ef_vi_transmit_init() or ef_vi_transmitv_init().
552 extern void ef_vi_transmit_push(ef_vi*);
555 /*! \i_ef_vi Maximum number of transmit completions per transmit event. */
556 #define EF_VI_TRANSMIT_BATCH 64
558 /*! \i_ef_vi Determine the set of [ef_request_id]s for each DMA request
559 ** which has been completed by a given transmit completion
562 ** \param ids must point to an array of length EF_VI_TRANSMIT_BATCH
563 ** \return the number of valid [ef_request_id]s (can be zero)
565 extern int ef_vi_transmit_unbundle(ef_vi* ep, const ef_event*,
569 /*! \i_ef_event Returns true if ef_eventq_poll() will return event(s). */
570 extern int ef_eventq_has_event(ef_vi* vi);
572 /*! \i_ef_event Returns true if there are quite a few events in the event
575 ** This looks ahead in the event queue, so has the property that it will
576 ** not ping-pong a cache-line when it is called concurrently with events
579 extern int ef_eventq_has_many_events(ef_vi* evq, int look_ahead);
581 /*! Type of function to handle unknown events arriving on event queue
582 ** Return CI_TRUE iff the event has been handled.
584 typedef int/*bool*/ ef_event_handler_fn(void* priv, ef_vi* evq, ef_event* ev);
586 /*! Standard poll exception routine */
587 extern int/*bool*/ ef_eventq_poll_exception(void* priv, ef_vi* evq,
590 /*! \i_ef_event Retrieve events from the event queue, handle RX/TX events
591 ** and pass any others to an exception handler function
593 ** \return The number of events retrieved.
595 extern int ef_eventq_poll_evs(ef_vi* evq, ef_event* evs, int evs_len,
596 ef_event_handler_fn *exception, void *expt_priv);
598 /*! \i_ef_event Retrieve events from the event queue.
600 ** \return The number of events retrieved.
602 ef_vi_inline int ef_eventq_poll(ef_vi* evq, ef_event* evs, int evs_len)
604 return ef_eventq_poll_evs(evq, evs, evs_len,
605 &ef_eventq_poll_exception, (void*)0);
608 /*! \i_ef_event Returns the capacity of an event queue. */
609 ef_vi_inline int ef_eventq_capacity(ef_vi* vi)
611 return (vi->evq_mask + 1u) / sizeof(ef_hw_event);
614 /* Returns the instance ID of [vi] */
615 ef_vi_inline unsigned ef_vi_instance(ef_vi* vi)
619 /**********************************************************************
620 * Initialisation *****************************************************
621 **********************************************************************/
623 /*! Return size of state buffer of an initialised VI. */
624 extern int ef_vi_state_bytes(ef_vi*);
626 /*! Return size of buffer needed for VI state given sizes of RX and TX
627 ** DMA queues. Queue sizes must be legal sizes (power of 2), or 0 (no
630 extern int ef_vi_calc_state_bytes(int rxq_size, int txq_size);
632 /*! Initialise [ef_vi] from the provided resources. [vvis] must have been
633 ** created by ef_make_vi_data() & remains owned by the caller.
635 extern void ef_vi_init(ef_vi*, void* vi_info, ef_vi_state* state,
636 ef_eventq_state* evq_state, enum ef_vi_flags);
638 extern void ef_vi_state_init(ef_vi*);
639 extern void ef_eventq_state_init(ef_vi*);
641 /*! Convert an efhw device arch to ef_vi_arch, or returns -1 if not
644 extern int ef_vi_arch_from_efhw_arch(int efhw_arch);
647 #endif /* __EFAB_EF_VI_H__ */