1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) 2017 Solarflare Communications Inc. 5 * All rights reserved. 6 * 7 * This software was jointly developed between OKTET Labs (under contract 8 * for Solarflare) and Solarflare Communications, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright notice, 14 * this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 29 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef _SFC_DP_RX_H 33 #define _SFC_DP_RX_H 34 35 #include <rte_mempool.h> 36 #include <rte_ethdev.h> 37 38 #include "sfc_dp.h" 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif 43 44 /** 45 * Generic receive queue information used on data path. 46 * It must be kept as small as it is possible since it is built into 47 * the structure used on datapath. 48 */ 49 struct sfc_dp_rxq { 50 struct sfc_dp_queue dpq; 51 }; 52 53 /** 54 * Datapath receive queue creation information. 55 * 56 * The structure is used just to pass information from control path to 57 * datapath. It could be just function arguments, but it would be hardly 58 * readable. 59 */ 60 struct sfc_dp_rx_qcreate_info { 61 /** Memory pool to allocate Rx buffer from */ 62 struct rte_mempool *refill_mb_pool; 63 /** Minimum number of unused Rx descriptors to do refill */ 64 unsigned int refill_threshold; 65 /** 66 * Usable mbuf data space in accordance with alignment and 67 * padding requirements imposed by HW. 68 */ 69 unsigned int buf_size; 70 71 /** 72 * Maximum number of Rx descriptors completed in one Rx event. 73 * Just for sanity checks if datapath would like to do. 74 */ 75 unsigned int batch_max; 76 77 /** Pseudo-header size */ 78 unsigned int prefix_size; 79 80 /** Receive queue flags initializer */ 81 unsigned int flags; 82 #define SFC_RXQ_FLAG_RSS_HASH 0x1 83 84 /** Rx queue size */ 85 unsigned int rxq_entries; 86 /** DMA-mapped Rx descriptors ring */ 87 void *rxq_hw_ring; 88 89 /** Associated event queue size */ 90 unsigned int evq_entries; 91 /** Hardware event ring */ 92 void *evq_hw_ring; 93 94 /** The queue index in hardware (required to push right doorbell) */ 95 unsigned int hw_index; 96 /** 97 * Virtual address of the memory-mapped BAR to push Rx refill 98 * doorbell 99 */ 100 volatile void *mem_bar; 101 }; 102 103 /** 104 * Allocate and initialize datapath receive queue. 105 * 106 * @param port_id The port identifier 107 * @param queue_id The queue identifier 108 * @param pci_addr PCI function address 109 * @param socket_id Socket identifier to allocate memory 110 * @param info Receive queue information 111 * @param dp_rxqp Location for generic datapath receive queue pointer 112 * 113 * @return 0 or positive errno. 114 */ 115 typedef int (sfc_dp_rx_qcreate_t)(uint16_t port_id, uint16_t queue_id, 116 const struct rte_pci_addr *pci_addr, 117 int socket_id, 118 const struct sfc_dp_rx_qcreate_info *info, 119 struct sfc_dp_rxq **dp_rxqp); 120 121 /** 122 * Free resources allocated for datapath recevie queue. 123 */ 124 typedef void (sfc_dp_rx_qdestroy_t)(struct sfc_dp_rxq *dp_rxq); 125 126 /** 127 * Receive queue start callback. 128 * 129 * It handovers EvQ to the datapath. 130 */ 131 typedef int (sfc_dp_rx_qstart_t)(struct sfc_dp_rxq *dp_rxq, 132 unsigned int evq_read_ptr); 133 134 /** 135 * Receive queue stop function called before flush. 136 */ 137 typedef void (sfc_dp_rx_qstop_t)(struct sfc_dp_rxq *dp_rxq, 138 unsigned int *evq_read_ptr); 139 140 /** 141 * Receive event handler used during queue flush only. 142 */ 143 typedef bool (sfc_dp_rx_qrx_ev_t)(struct sfc_dp_rxq *dp_rxq, unsigned int id); 144 145 /** 146 * Receive queue purge function called after queue flush. 147 * 148 * Should be used to free unused recevie buffers. 149 */ 150 typedef void (sfc_dp_rx_qpurge_t)(struct sfc_dp_rxq *dp_rxq); 151 152 /** Get packet types recognized/classified */ 153 typedef const uint32_t * (sfc_dp_rx_supported_ptypes_get_t)(void); 154 155 /** Get number of pending Rx descriptors */ 156 typedef unsigned int (sfc_dp_rx_qdesc_npending_t)(struct sfc_dp_rxq *dp_rxq); 157 158 /** Check Rx descriptor status */ 159 typedef int (sfc_dp_rx_qdesc_status_t)(struct sfc_dp_rxq *dp_rxq, 160 uint16_t offset); 161 162 /** Receive datapath definition */ 163 struct sfc_dp_rx { 164 struct sfc_dp dp; 165 166 unsigned int features; 167 #define SFC_DP_RX_FEAT_SCATTER 0x1 168 #define SFC_DP_RX_FEAT_MULTI_PROCESS 0x2 169 sfc_dp_rx_qcreate_t *qcreate; 170 sfc_dp_rx_qdestroy_t *qdestroy; 171 sfc_dp_rx_qstart_t *qstart; 172 sfc_dp_rx_qstop_t *qstop; 173 sfc_dp_rx_qrx_ev_t *qrx_ev; 174 sfc_dp_rx_qpurge_t *qpurge; 175 sfc_dp_rx_supported_ptypes_get_t *supported_ptypes_get; 176 sfc_dp_rx_qdesc_npending_t *qdesc_npending; 177 sfc_dp_rx_qdesc_status_t *qdesc_status; 178 eth_rx_burst_t pkt_burst; 179 }; 180 181 static inline struct sfc_dp_rx * 182 sfc_dp_find_rx_by_name(struct sfc_dp_list *head, const char *name) 183 { 184 struct sfc_dp *p = sfc_dp_find_by_name(head, SFC_DP_RX, name); 185 186 return (p == NULL) ? NULL : container_of(p, struct sfc_dp_rx, dp); 187 } 188 189 static inline struct sfc_dp_rx * 190 sfc_dp_find_rx_by_caps(struct sfc_dp_list *head, unsigned int avail_caps) 191 { 192 struct sfc_dp *p = sfc_dp_find_by_caps(head, SFC_DP_RX, avail_caps); 193 194 return (p == NULL) ? NULL : container_of(p, struct sfc_dp_rx, dp); 195 } 196 197 extern struct sfc_dp_rx sfc_efx_rx; 198 extern struct sfc_dp_rx sfc_ef10_rx; 199 200 #ifdef __cplusplus 201 } 202 #endif 203 #endif /* _SFC_DP_RX_H */ 204