1 1.20 joe /* $NetBSD: if_iavf.c,v 1.20 2025/03/23 18:38:49 joe Exp $ */ 2 1.1 yamaguch 3 1.1 yamaguch /* 4 1.1 yamaguch * Copyright (c) 2013-2015, Intel Corporation 5 1.1 yamaguch * All rights reserved. 6 1.1 yamaguch 7 1.1 yamaguch * Redistribution and use in source and binary forms, with or without 8 1.1 yamaguch * modification, are permitted provided that the following conditions are met: 9 1.1 yamaguch * 10 1.1 yamaguch * 1. Redistributions of source code must retain the above copyright notice, 11 1.1 yamaguch * this list of conditions and the following disclaimer. 12 1.1 yamaguch * 13 1.1 yamaguch * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 yamaguch * notice, this list of conditions and the following disclaimer in the 15 1.1 yamaguch * documentation and/or other materials provided with the distribution. 16 1.1 yamaguch * 17 1.1 yamaguch * 3. Neither the name of the Intel Corporation nor the names of its 18 1.1 yamaguch * contributors may be used to endorse or promote products derived from 19 1.1 yamaguch * this software without specific prior written permission. 20 1.1 yamaguch * 21 1.1 yamaguch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 1.1 yamaguch * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 1.1 yamaguch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 1.1 yamaguch * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 25 1.1 yamaguch * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 1.1 yamaguch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 1.1 yamaguch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 1.1 yamaguch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 1.1 yamaguch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 1.1 yamaguch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 1.1 yamaguch * POSSIBILITY OF SUCH DAMAGE. 32 1.1 yamaguch */ 33 1.1 yamaguch 34 1.1 yamaguch /* 35 1.1 yamaguch * Copyright (c) 2016,2017 David Gwynne <dlg (at) openbsd.org> 36 1.1 yamaguch * Copyright (c) 2019 Jonathan Matthew <jmatthew (at) openbsd.org> 37 1.1 yamaguch * 38 1.1 yamaguch * Permission to use, copy, modify, and distribute this software for any 39 1.1 yamaguch * purpose with or without fee is hereby granted, provided that the above 40 1.1 yamaguch * copyright notice and this permission notice appear in all copies. 41 1.1 yamaguch * 42 1.1 yamaguch * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 43 1.1 yamaguch * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 44 1.1 yamaguch * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 45 1.1 yamaguch * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 46 1.1 yamaguch * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 47 1.1 yamaguch * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 48 1.1 yamaguch * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 49 1.1 yamaguch */ 50 1.1 yamaguch 51 1.1 yamaguch /* 52 1.1 yamaguch * Copyright (c) 2020 Internet Initiative Japan, Inc. 53 1.1 yamaguch * All rights reserved. 54 1.1 yamaguch * 55 1.1 yamaguch * Redistribution and use in source and binary forms, with or without 56 1.1 yamaguch * modification, are permitted provided that the following conditions 57 1.1 yamaguch * are met: 58 1.1 yamaguch * 1. Redistributions of source code must retain the above copyright 59 1.1 yamaguch * notice, this list of conditions and the following disclaimer. 60 1.1 yamaguch * 2. Redistributions in binary form must reproduce the above copyright 61 1.1 yamaguch * notice, this list of conditions and the following disclaimer in the 62 1.1 yamaguch * documentation and/or other materials provided with the distribution. 63 1.1 yamaguch * 64 1.1 yamaguch * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 65 1.1 yamaguch * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 66 1.1 yamaguch * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 67 1.1 yamaguch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 68 1.1 yamaguch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 69 1.1 yamaguch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 70 1.1 yamaguch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 71 1.1 yamaguch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 72 1.1 yamaguch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 73 1.1 yamaguch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 74 1.1 yamaguch * POSSIBILITY OF SUCH DAMAGE. 75 1.1 yamaguch */ 76 1.1 yamaguch 77 1.1 yamaguch #include <sys/cdefs.h> 78 1.20 joe __KERNEL_RCSID(0, "$NetBSD: if_iavf.c,v 1.20 2025/03/23 18:38:49 joe Exp $"); 79 1.1 yamaguch 80 1.1 yamaguch #include <sys/param.h> 81 1.1 yamaguch #include <sys/types.h> 82 1.1 yamaguch 83 1.1 yamaguch #include <sys/bitops.h> 84 1.1 yamaguch #include <sys/bus.h> 85 1.1 yamaguch #include <sys/cprng.h> 86 1.1 yamaguch #include <sys/cpu.h> 87 1.1 yamaguch #include <sys/device.h> 88 1.1 yamaguch #include <sys/evcnt.h> 89 1.1 yamaguch #include <sys/interrupt.h> 90 1.1 yamaguch #include <sys/kmem.h> 91 1.1 yamaguch #include <sys/module.h> 92 1.1 yamaguch #include <sys/mutex.h> 93 1.1 yamaguch #include <sys/pcq.h> 94 1.1 yamaguch #include <sys/queue.h> 95 1.1 yamaguch #include <sys/syslog.h> 96 1.1 yamaguch #include <sys/workqueue.h> 97 1.6 yamaguch #include <sys/xcall.h> 98 1.1 yamaguch 99 1.1 yamaguch #include <net/bpf.h> 100 1.1 yamaguch #include <net/if.h> 101 1.1 yamaguch #include <net/if_dl.h> 102 1.1 yamaguch #include <net/if_media.h> 103 1.1 yamaguch #include <net/if_ether.h> 104 1.1 yamaguch #include <net/rss_config.h> 105 1.1 yamaguch 106 1.1 yamaguch #include <netinet/tcp.h> /* for struct tcphdr */ 107 1.1 yamaguch #include <netinet/udp.h> /* for struct udphdr */ 108 1.1 yamaguch 109 1.1 yamaguch #include <dev/pci/pcivar.h> 110 1.1 yamaguch #include <dev/pci/pcidevs.h> 111 1.1 yamaguch 112 1.1 yamaguch #include <dev/pci/if_ixlreg.h> 113 1.1 yamaguch #include <dev/pci/if_ixlvar.h> 114 1.1 yamaguch #include <dev/pci/if_iavfvar.h> 115 1.1 yamaguch 116 1.1 yamaguch #include <prop/proplib.h> 117 1.1 yamaguch 118 1.1 yamaguch #define IAVF_PCIREG PCI_MAPREG_START 119 1.1 yamaguch #define IAVF_AQ_NUM 256 120 1.1 yamaguch #define IAVF_AQ_MASK (IAVF_AQ_NUM-1) 121 1.1 yamaguch #define IAVF_AQ_ALIGN 64 122 1.1 yamaguch #define IAVF_AQ_BUFLEN 4096 123 1.1 yamaguch #define I40E_AQ_LARGE_BUF 512 124 1.1 yamaguch #define IAVF_VF_MAJOR 1 125 1.1 yamaguch #define IAVF_VF_MINOR 1 126 1.1 yamaguch 127 1.1 yamaguch #define IAVF_VFR_INPROGRESS 0 128 1.1 yamaguch #define IAVF_VFR_COMPLETED 1 129 1.1 yamaguch #define IAVF_VFR_VFACTIVE 2 130 1.1 yamaguch 131 1.1 yamaguch #define IAVF_REG_VFR 0xdeadbeef 132 1.1 yamaguch 133 1.1 yamaguch #define IAVF_ITR_RX 0x0 134 1.1 yamaguch #define IAVF_ITR_TX 0x1 135 1.1 yamaguch #define IAVF_ITR_MISC 0x2 136 1.1 yamaguch #define IAVF_NOITR 0x3 137 1.1 yamaguch 138 1.1 yamaguch #define IAVF_MTU_ETHERLEN (ETHER_HDR_LEN \ 139 1.1 yamaguch + ETHER_CRC_LEN) 140 1.1 yamaguch #define IAVF_MAX_MTU (9600 - IAVF_MTU_ETHERLEN) 141 1.1 yamaguch #define IAVF_MIN_MTU (ETHER_MIN_LEN - ETHER_CRC_LEN) 142 1.1 yamaguch 143 1.1 yamaguch #define IAVF_WORKQUEUE_PRI PRI_SOFTNET 144 1.1 yamaguch 145 1.1 yamaguch #define IAVF_TX_PKT_DESCS 8 146 1.1 yamaguch #define IAVF_TX_QUEUE_ALIGN 128 147 1.1 yamaguch #define IAVF_RX_QUEUE_ALIGN 128 148 1.1 yamaguch #define IAVF_TX_PKT_MAXSIZE (MCLBYTES * IAVF_TX_PKT_DESCS) 149 1.1 yamaguch #define IAVF_MCLBYTES (MCLBYTES - ETHER_ALIGN) 150 1.1 yamaguch 151 1.1 yamaguch #define IAVF_TICK_INTERVAL (5 * hz) 152 1.1 yamaguch #define IAVF_WATCHDOG_TICKS 3 153 1.1 yamaguch #define IAVF_WATCHDOG_STOP 0 154 1.1 yamaguch 155 1.1 yamaguch #define IAVF_TXRX_PROCESS_UNLIMIT UINT_MAX 156 1.1 yamaguch #define IAVF_TX_PROCESS_LIMIT 256 157 1.1 yamaguch #define IAVF_RX_PROCESS_LIMIT 256 158 1.1 yamaguch #define IAVF_TX_INTR_PROCESS_LIMIT 256 159 1.1 yamaguch #define IAVF_RX_INTR_PROCESS_LIMIT 0U 160 1.1 yamaguch 161 1.1 yamaguch #define IAVF_EXEC_TIMEOUT 3000 162 1.1 yamaguch 163 1.1 yamaguch #define IAVF_IFCAP_RXCSUM (IFCAP_CSUM_IPv4_Rx | \ 164 1.1 yamaguch IFCAP_CSUM_TCPv4_Rx | \ 165 1.1 yamaguch IFCAP_CSUM_UDPv4_Rx | \ 166 1.1 yamaguch IFCAP_CSUM_TCPv6_Rx | \ 167 1.1 yamaguch IFCAP_CSUM_UDPv6_Rx) 168 1.1 yamaguch #define IAVF_IFCAP_TXCSUM (IFCAP_CSUM_IPv4_Tx | \ 169 1.1 yamaguch IFCAP_CSUM_TCPv4_Tx | \ 170 1.1 yamaguch IFCAP_CSUM_UDPv4_Tx | \ 171 1.1 yamaguch IFCAP_CSUM_TCPv6_Tx | \ 172 1.1 yamaguch IFCAP_CSUM_UDPv6_Tx) 173 1.1 yamaguch #define IAVF_CSUM_ALL_OFFLOAD (M_CSUM_IPv4 | \ 174 1.1 yamaguch M_CSUM_TCPv4 | M_CSUM_TCPv6 | \ 175 1.1 yamaguch M_CSUM_UDPv4 | M_CSUM_UDPv6) 176 1.1 yamaguch 177 1.1 yamaguch struct iavf_softc; /* defined */ 178 1.1 yamaguch 179 1.1 yamaguch struct iavf_module_params { 180 1.1 yamaguch int debug; 181 1.1 yamaguch uint32_t rx_itr; 182 1.1 yamaguch uint32_t tx_itr; 183 1.1 yamaguch unsigned int rx_ndescs; 184 1.1 yamaguch unsigned int tx_ndescs; 185 1.1 yamaguch int max_qps; 186 1.1 yamaguch }; 187 1.1 yamaguch 188 1.1 yamaguch struct iavf_product { 189 1.1 yamaguch unsigned int vendor_id; 190 1.1 yamaguch unsigned int product_id; 191 1.1 yamaguch }; 192 1.1 yamaguch 193 1.1 yamaguch struct iavf_link_speed { 194 1.1 yamaguch uint64_t baudrate; 195 1.1 yamaguch uint64_t media; 196 1.1 yamaguch }; 197 1.1 yamaguch 198 1.1 yamaguch struct iavf_aq_regs { 199 1.1 yamaguch bus_size_t atq_tail; 200 1.1 yamaguch bus_size_t atq_head; 201 1.1 yamaguch bus_size_t atq_len; 202 1.1 yamaguch bus_size_t atq_bal; 203 1.1 yamaguch bus_size_t atq_bah; 204 1.1 yamaguch 205 1.1 yamaguch bus_size_t arq_tail; 206 1.1 yamaguch bus_size_t arq_head; 207 1.1 yamaguch bus_size_t arq_len; 208 1.1 yamaguch bus_size_t arq_bal; 209 1.1 yamaguch bus_size_t arq_bah; 210 1.1 yamaguch 211 1.1 yamaguch uint32_t atq_len_enable; 212 1.1 yamaguch uint32_t atq_tail_mask; 213 1.1 yamaguch uint32_t atq_head_mask; 214 1.1 yamaguch 215 1.1 yamaguch uint32_t arq_len_enable; 216 1.1 yamaguch uint32_t arq_tail_mask; 217 1.1 yamaguch uint32_t arq_head_mask; 218 1.1 yamaguch }; 219 1.1 yamaguch 220 1.1 yamaguch struct iavf_work { 221 1.1 yamaguch struct work ixw_cookie; 222 1.1 yamaguch void (*ixw_func)(void *); 223 1.1 yamaguch void *ixw_arg; 224 1.1 yamaguch unsigned int ixw_added; 225 1.1 yamaguch }; 226 1.1 yamaguch 227 1.1 yamaguch struct iavf_tx_map { 228 1.1 yamaguch struct mbuf *txm_m; 229 1.1 yamaguch bus_dmamap_t txm_map; 230 1.1 yamaguch unsigned int txm_eop; 231 1.1 yamaguch }; 232 1.1 yamaguch 233 1.1 yamaguch struct iavf_tx_ring { 234 1.1 yamaguch unsigned int txr_qid; 235 1.1 yamaguch char txr_name[16]; 236 1.1 yamaguch 237 1.1 yamaguch struct iavf_softc *txr_sc; 238 1.1 yamaguch kmutex_t txr_lock; 239 1.1 yamaguch pcq_t *txr_intrq; 240 1.1 yamaguch void *txr_si; 241 1.1 yamaguch unsigned int txr_prod; 242 1.1 yamaguch unsigned int txr_cons; 243 1.1 yamaguch 244 1.1 yamaguch struct iavf_tx_map *txr_maps; 245 1.1 yamaguch struct ixl_dmamem txr_mem; 246 1.1 yamaguch bus_size_t txr_tail; 247 1.1 yamaguch 248 1.1 yamaguch int txr_watchdog; 249 1.1 yamaguch 250 1.1 yamaguch struct evcnt txr_defragged; 251 1.1 yamaguch struct evcnt txr_defrag_failed; 252 1.1 yamaguch struct evcnt txr_pcqdrop; 253 1.1 yamaguch struct evcnt txr_transmitdef; 254 1.1 yamaguch struct evcnt txr_defer; 255 1.1 yamaguch struct evcnt txr_watchdogto; 256 1.1 yamaguch struct evcnt txr_intr; 257 1.1 yamaguch }; 258 1.1 yamaguch 259 1.1 yamaguch struct iavf_rx_map { 260 1.1 yamaguch struct mbuf *rxm_m; 261 1.1 yamaguch bus_dmamap_t rxm_map; 262 1.1 yamaguch }; 263 1.1 yamaguch 264 1.1 yamaguch struct iavf_rx_ring { 265 1.1 yamaguch unsigned int rxr_qid; 266 1.1 yamaguch char rxr_name[16]; 267 1.1 yamaguch 268 1.1 yamaguch struct iavf_softc *rxr_sc; 269 1.1 yamaguch kmutex_t rxr_lock; 270 1.1 yamaguch 271 1.1 yamaguch unsigned int rxr_prod; 272 1.1 yamaguch unsigned int rxr_cons; 273 1.1 yamaguch 274 1.1 yamaguch struct iavf_rx_map *rxr_maps; 275 1.1 yamaguch struct ixl_dmamem rxr_mem; 276 1.1 yamaguch bus_size_t rxr_tail; 277 1.1 yamaguch 278 1.1 yamaguch struct mbuf *rxr_m_head; 279 1.1 yamaguch struct mbuf **rxr_m_tail; 280 1.1 yamaguch 281 1.1 yamaguch struct evcnt rxr_mgethdr_failed; 282 1.1 yamaguch struct evcnt rxr_mgetcl_failed; 283 1.1 yamaguch struct evcnt rxr_mbuf_load_failed; 284 1.1 yamaguch struct evcnt rxr_defer; 285 1.1 yamaguch struct evcnt rxr_intr; 286 1.1 yamaguch }; 287 1.1 yamaguch 288 1.1 yamaguch struct iavf_queue_pair { 289 1.1 yamaguch struct iavf_tx_ring *qp_txr; 290 1.1 yamaguch struct iavf_rx_ring *qp_rxr; 291 1.1 yamaguch struct work qp_work; 292 1.1 yamaguch void *qp_si; 293 1.1 yamaguch bool qp_workqueue; 294 1.1 yamaguch }; 295 1.1 yamaguch 296 1.1 yamaguch struct iavf_stat_counters { 297 1.1 yamaguch struct evcnt isc_rx_bytes; 298 1.1 yamaguch struct evcnt isc_rx_unicast; 299 1.1 yamaguch struct evcnt isc_rx_multicast; 300 1.1 yamaguch struct evcnt isc_rx_broadcast; 301 1.1 yamaguch struct evcnt isc_rx_discards; 302 1.1 yamaguch struct evcnt isc_rx_unknown_protocol; 303 1.1 yamaguch struct evcnt isc_tx_bytes; 304 1.1 yamaguch struct evcnt isc_tx_unicast; 305 1.1 yamaguch struct evcnt isc_tx_multicast; 306 1.1 yamaguch struct evcnt isc_tx_broadcast; 307 1.1 yamaguch struct evcnt isc_tx_discards; 308 1.1 yamaguch struct evcnt isc_tx_errors; 309 1.1 yamaguch }; 310 1.1 yamaguch 311 1.1 yamaguch /* 312 1.1 yamaguch * Locking notes: 313 1.1 yamaguch * + A field in iavf_tx_ring is protected by txr_lock (a spin mutex), and 314 1.1 yamaguch * A field in iavf_rx_ring is protected by rxr_lock (a spin mutex). 315 1.1 yamaguch * - more than one lock must not be held at once. 316 1.1 yamaguch * + fields named sc_atq_*, sc_arq_*, and sc_adminq_* are protected by 317 1.1 yamaguch * sc_adminq_lock(a spin mutex). 318 1.1 yamaguch * - The lock is held while accessing sc_aq_regs 319 1.1 yamaguch * and is not held with txr_lock and rxr_lock together. 320 1.1 yamaguch * + Other fields in iavf_softc is protected by sc_cfg_lock 321 1.1 yamaguch * (an adaptive mutex). 322 1.1 yamaguch * - The lock must be held before acquiring another lock. 323 1.4 yamaguch * 324 1.4 yamaguch * Locking order: 325 1.4 yamaguch * - IFNET_LOCK => sc_cfg_lock => sc_adminq_lock 326 1.4 yamaguch * - sc_cfg_lock => ETHER_LOCK => sc_adminq_lock 327 1.4 yamaguch * - sc_cfg_lock => txr_lock 328 1.4 yamaguch * - sc_cfg_lock => rxr_lock 329 1.1 yamaguch */ 330 1.1 yamaguch 331 1.1 yamaguch struct iavf_softc { 332 1.1 yamaguch device_t sc_dev; 333 1.1 yamaguch enum i40e_mac_type sc_mac_type; 334 1.1 yamaguch int sc_debuglevel; 335 1.1 yamaguch bool sc_attached; 336 1.1 yamaguch bool sc_dead; 337 1.1 yamaguch kmutex_t sc_cfg_lock; 338 1.1 yamaguch callout_t sc_tick; 339 1.1 yamaguch struct ifmedia sc_media; 340 1.1 yamaguch uint64_t sc_media_status; 341 1.1 yamaguch uint64_t sc_media_active; 342 1.1 yamaguch int sc_link_state; 343 1.1 yamaguch 344 1.1 yamaguch const struct iavf_aq_regs * 345 1.1 yamaguch sc_aq_regs; 346 1.1 yamaguch 347 1.1 yamaguch struct ethercom sc_ec; 348 1.1 yamaguch uint8_t sc_enaddr[ETHER_ADDR_LEN]; 349 1.1 yamaguch uint8_t sc_enaddr_fake[ETHER_ADDR_LEN]; 350 1.1 yamaguch uint8_t sc_enaddr_added[ETHER_ADDR_LEN]; 351 1.1 yamaguch uint8_t sc_enaddr_reset[ETHER_ADDR_LEN]; 352 1.1 yamaguch struct if_percpuq *sc_ipq; 353 1.1 yamaguch 354 1.1 yamaguch struct pci_attach_args sc_pa; 355 1.1 yamaguch bus_dma_tag_t sc_dmat; 356 1.1 yamaguch bus_space_tag_t sc_memt; 357 1.1 yamaguch bus_space_handle_t sc_memh; 358 1.1 yamaguch bus_size_t sc_mems; 359 1.1 yamaguch pci_intr_handle_t *sc_ihp; 360 1.1 yamaguch void **sc_ihs; 361 1.1 yamaguch unsigned int sc_nintrs; 362 1.1 yamaguch 363 1.1 yamaguch uint32_t sc_major_ver; 364 1.1 yamaguch uint32_t sc_minor_ver; 365 1.1 yamaguch uint32_t sc_vf_id; 366 1.1 yamaguch uint32_t sc_vf_cap; 367 1.1 yamaguch uint16_t sc_vsi_id; 368 1.1 yamaguch uint16_t sc_qset_handle; 369 1.1 yamaguch uint16_t sc_max_mtu; 370 1.1 yamaguch bool sc_got_vf_resources; 371 1.1 yamaguch bool sc_got_irq_map; 372 1.1 yamaguch unsigned int sc_max_vectors; 373 1.1 yamaguch 374 1.1 yamaguch kmutex_t sc_adminq_lock; 375 1.1 yamaguch kcondvar_t sc_adminq_cv; 376 1.1 yamaguch struct ixl_dmamem sc_atq; 377 1.1 yamaguch unsigned int sc_atq_prod; 378 1.1 yamaguch unsigned int sc_atq_cons; 379 1.1 yamaguch struct ixl_aq_bufs sc_atq_idle; 380 1.1 yamaguch struct ixl_aq_bufs sc_atq_live; 381 1.1 yamaguch struct ixl_dmamem sc_arq; 382 1.1 yamaguch struct ixl_aq_bufs sc_arq_idle; 383 1.1 yamaguch struct ixl_aq_bufs sc_arq_live; 384 1.1 yamaguch unsigned int sc_arq_prod; 385 1.1 yamaguch unsigned int sc_arq_cons; 386 1.1 yamaguch struct iavf_work sc_arq_refill; 387 1.1 yamaguch uint32_t sc_arq_opcode; 388 1.1 yamaguch uint32_t sc_arq_retval; 389 1.1 yamaguch 390 1.1 yamaguch uint32_t sc_tx_itr; 391 1.1 yamaguch uint32_t sc_rx_itr; 392 1.1 yamaguch unsigned int sc_tx_ring_ndescs; 393 1.1 yamaguch unsigned int sc_rx_ring_ndescs; 394 1.1 yamaguch unsigned int sc_nqueue_pairs; 395 1.1 yamaguch unsigned int sc_nqps_alloc; 396 1.1 yamaguch unsigned int sc_nqps_vsi; 397 1.1 yamaguch unsigned int sc_nqps_req; 398 1.1 yamaguch struct iavf_queue_pair *sc_qps; 399 1.1 yamaguch bool sc_txrx_workqueue; 400 1.1 yamaguch u_int sc_tx_intr_process_limit; 401 1.1 yamaguch u_int sc_tx_process_limit; 402 1.1 yamaguch u_int sc_rx_intr_process_limit; 403 1.1 yamaguch u_int sc_rx_process_limit; 404 1.1 yamaguch 405 1.1 yamaguch struct workqueue *sc_workq; 406 1.1 yamaguch struct workqueue *sc_workq_txrx; 407 1.1 yamaguch struct iavf_work sc_reset_task; 408 1.1 yamaguch struct iavf_work sc_wdto_task; 409 1.1 yamaguch struct iavf_work sc_req_queues_task; 410 1.1 yamaguch bool sc_req_queues_retried; 411 1.1 yamaguch bool sc_resetting; 412 1.1 yamaguch bool sc_reset_up; 413 1.1 yamaguch 414 1.1 yamaguch struct sysctllog *sc_sysctllog; 415 1.1 yamaguch struct iavf_stat_counters 416 1.1 yamaguch sc_stat_counters; 417 1.1 yamaguch }; 418 1.1 yamaguch 419 1.1 yamaguch #define IAVF_LOG(_sc, _lvl, _fmt, _args...) \ 420 1.1 yamaguch do { \ 421 1.1 yamaguch if (!(_sc)->sc_attached) { \ 422 1.1 yamaguch switch (_lvl) { \ 423 1.1 yamaguch case LOG_ERR: \ 424 1.1 yamaguch case LOG_WARNING: \ 425 1.1 yamaguch aprint_error_dev((_sc)->sc_dev, _fmt, ##_args); \ 426 1.1 yamaguch break; \ 427 1.1 yamaguch case LOG_INFO: \ 428 1.1 yamaguch aprint_normal_dev((_sc)->sc_dev,_fmt, ##_args); \ 429 1.1 yamaguch break; \ 430 1.1 yamaguch case LOG_DEBUG: \ 431 1.1 yamaguch default: \ 432 1.1 yamaguch aprint_debug_dev((_sc)->sc_dev, _fmt, ##_args); \ 433 1.1 yamaguch } \ 434 1.1 yamaguch } else { \ 435 1.1 yamaguch struct ifnet *_ifp = &(_sc)->sc_ec.ec_if; \ 436 1.1 yamaguch log((_lvl), "%s: " _fmt, _ifp->if_xname, ##_args); \ 437 1.1 yamaguch } \ 438 1.1 yamaguch } while (0) 439 1.1 yamaguch 440 1.1 yamaguch static int iavf_dmamem_alloc(bus_dma_tag_t, struct ixl_dmamem *, 441 1.1 yamaguch bus_size_t, bus_size_t); 442 1.1 yamaguch static void iavf_dmamem_free(bus_dma_tag_t, struct ixl_dmamem *); 443 1.1 yamaguch static struct ixl_aq_buf * 444 1.1 yamaguch iavf_aqb_get(struct iavf_softc *, struct ixl_aq_bufs *); 445 1.1 yamaguch static struct ixl_aq_buf * 446 1.1 yamaguch iavf_aqb_get_locked(struct ixl_aq_bufs *); 447 1.1 yamaguch static void iavf_aqb_put_locked(struct ixl_aq_bufs *, struct ixl_aq_buf *); 448 1.1 yamaguch static void iavf_aqb_clean(struct ixl_aq_bufs *, bus_dma_tag_t); 449 1.1 yamaguch 450 1.1 yamaguch static const struct iavf_product * 451 1.1 yamaguch iavf_lookup(const struct pci_attach_args *); 452 1.1 yamaguch static enum i40e_mac_type 453 1.1 yamaguch iavf_mactype(pci_product_id_t); 454 1.1 yamaguch static void iavf_pci_csr_setup(pci_chipset_tag_t, pcitag_t); 455 1.1 yamaguch static int iavf_wait_active(struct iavf_softc *); 456 1.1 yamaguch static bool iavf_is_etheranyaddr(const uint8_t *); 457 1.1 yamaguch static void iavf_prepare_fakeaddr(struct iavf_softc *); 458 1.1 yamaguch static int iavf_replace_lla(struct ifnet *, 459 1.1 yamaguch const uint8_t *, const uint8_t *); 460 1.1 yamaguch static void iavf_evcnt_attach(struct evcnt *, 461 1.1 yamaguch const char *, const char *); 462 1.1 yamaguch static int iavf_setup_interrupts(struct iavf_softc *); 463 1.1 yamaguch static void iavf_teardown_interrupts(struct iavf_softc *); 464 1.1 yamaguch static int iavf_setup_sysctls(struct iavf_softc *); 465 1.1 yamaguch static void iavf_teardown_sysctls(struct iavf_softc *); 466 1.1 yamaguch static int iavf_setup_stats(struct iavf_softc *); 467 1.1 yamaguch static void iavf_teardown_stats(struct iavf_softc *); 468 1.1 yamaguch static struct workqueue * 469 1.1 yamaguch iavf_workq_create(const char *, pri_t, int, int); 470 1.1 yamaguch static void iavf_workq_destroy(struct workqueue *); 471 1.1 yamaguch static int iavf_work_set(struct iavf_work *, void (*)(void *), void *); 472 1.1 yamaguch static void iavf_work_add(struct workqueue *, struct iavf_work *); 473 1.1 yamaguch static void iavf_work_wait(struct workqueue *, struct iavf_work *); 474 1.1 yamaguch static unsigned int 475 1.1 yamaguch iavf_calc_msix_count(struct iavf_softc *); 476 1.1 yamaguch static unsigned int 477 1.1 yamaguch iavf_calc_queue_pair_size(struct iavf_softc *); 478 1.1 yamaguch static int iavf_queue_pairs_alloc(struct iavf_softc *); 479 1.1 yamaguch static void iavf_queue_pairs_free(struct iavf_softc *); 480 1.1 yamaguch static int iavf_arq_fill(struct iavf_softc *); 481 1.1 yamaguch static void iavf_arq_refill(void *); 482 1.1 yamaguch static int iavf_arq_poll(struct iavf_softc *, uint32_t, int); 483 1.1 yamaguch static void iavf_atq_done(struct iavf_softc *); 484 1.1 yamaguch static int iavf_init_admin_queue(struct iavf_softc *); 485 1.1 yamaguch static void iavf_cleanup_admin_queue(struct iavf_softc *); 486 1.1 yamaguch static int iavf_arq(struct iavf_softc *); 487 1.1 yamaguch static int iavf_adminq_exec(struct iavf_softc *, 488 1.1 yamaguch struct ixl_aq_desc *, struct ixl_aq_buf *); 489 1.1 yamaguch static int iavf_adminq_poll(struct iavf_softc *, 490 1.1 yamaguch struct ixl_aq_desc *, struct ixl_aq_buf *, int); 491 1.1 yamaguch static int iavf_adminq_poll_locked(struct iavf_softc *, 492 1.1 yamaguch struct ixl_aq_desc *, struct ixl_aq_buf *, int); 493 1.1 yamaguch static int iavf_add_multi(struct iavf_softc *, uint8_t *, uint8_t *); 494 1.1 yamaguch static int iavf_del_multi(struct iavf_softc *, uint8_t *, uint8_t *); 495 1.1 yamaguch static void iavf_del_all_multi(struct iavf_softc *); 496 1.1 yamaguch 497 1.1 yamaguch static int iavf_get_version(struct iavf_softc *, struct ixl_aq_buf *); 498 1.1 yamaguch static int iavf_get_vf_resources(struct iavf_softc *, struct ixl_aq_buf *); 499 1.1 yamaguch static int iavf_get_stats(struct iavf_softc *); 500 1.1 yamaguch static int iavf_config_irq_map(struct iavf_softc *, struct ixl_aq_buf *); 501 1.1 yamaguch static int iavf_config_vsi_queues(struct iavf_softc *); 502 1.1 yamaguch static int iavf_config_hena(struct iavf_softc *); 503 1.1 yamaguch static int iavf_config_rss_key(struct iavf_softc *); 504 1.1 yamaguch static int iavf_config_rss_lut(struct iavf_softc *); 505 1.1 yamaguch static int iavf_config_promisc_mode(struct iavf_softc *, int, int); 506 1.1 yamaguch static int iavf_config_vlan_stripping(struct iavf_softc *, int); 507 1.1 yamaguch static int iavf_config_vlan_id(struct iavf_softc *, uint16_t, uint32_t); 508 1.1 yamaguch static int iavf_queue_select(struct iavf_softc *, int); 509 1.1 yamaguch static int iavf_request_queues(struct iavf_softc *, unsigned int); 510 1.1 yamaguch static int iavf_reset_vf(struct iavf_softc *); 511 1.1 yamaguch static int iavf_eth_addr(struct iavf_softc *, const uint8_t *, uint32_t); 512 1.1 yamaguch static void iavf_process_version(struct iavf_softc *, 513 1.1 yamaguch struct ixl_aq_desc *, struct ixl_aq_buf *); 514 1.1 yamaguch static void iavf_process_vf_resources(struct iavf_softc *, 515 1.1 yamaguch struct ixl_aq_desc *, struct ixl_aq_buf *); 516 1.1 yamaguch static void iavf_process_irq_map(struct iavf_softc *, 517 1.1 yamaguch struct ixl_aq_desc *); 518 1.1 yamaguch static void iavf_process_vc_event(struct iavf_softc *, 519 1.1 yamaguch struct ixl_aq_desc *, struct ixl_aq_buf *); 520 1.1 yamaguch static void iavf_process_stats(struct iavf_softc *, 521 1.1 yamaguch struct ixl_aq_desc *, struct ixl_aq_buf *); 522 1.1 yamaguch static void iavf_process_req_queues(struct iavf_softc *, 523 1.1 yamaguch struct ixl_aq_desc *, struct ixl_aq_buf *); 524 1.1 yamaguch 525 1.1 yamaguch static int iavf_intr(void *); 526 1.1 yamaguch static int iavf_queue_intr(void *); 527 1.1 yamaguch static void iavf_tick(void *); 528 1.1 yamaguch static void iavf_tick_halt(void *); 529 1.1 yamaguch static void iavf_reset_request(void *); 530 1.1 yamaguch static void iavf_reset_start(void *); 531 1.1 yamaguch static void iavf_reset(void *); 532 1.1 yamaguch static void iavf_reset_finish(struct iavf_softc *); 533 1.1 yamaguch static int iavf_init(struct ifnet *); 534 1.1 yamaguch static int iavf_init_locked(struct iavf_softc *); 535 1.1 yamaguch static void iavf_stop(struct ifnet *, int); 536 1.1 yamaguch static void iavf_stop_locked(struct iavf_softc *); 537 1.1 yamaguch static int iavf_ioctl(struct ifnet *, u_long, void *); 538 1.1 yamaguch static void iavf_start(struct ifnet *); 539 1.1 yamaguch static int iavf_transmit(struct ifnet *, struct mbuf*); 540 1.1 yamaguch static int iavf_watchdog(struct iavf_tx_ring *); 541 1.1 yamaguch static void iavf_watchdog_timeout(void *); 542 1.1 yamaguch static int iavf_media_change(struct ifnet *); 543 1.1 yamaguch static void iavf_media_status(struct ifnet *, struct ifmediareq *); 544 1.1 yamaguch static int iavf_ifflags_cb(struct ethercom *); 545 1.1 yamaguch static int iavf_vlan_cb(struct ethercom *, uint16_t, bool); 546 1.1 yamaguch static void iavf_deferred_transmit(void *); 547 1.1 yamaguch static void iavf_handle_queue(void *); 548 1.1 yamaguch static void iavf_handle_queue_wk(struct work *, void *); 549 1.1 yamaguch static int iavf_reinit(struct iavf_softc *); 550 1.1 yamaguch static int iavf_rxfill(struct iavf_softc *, struct iavf_rx_ring *); 551 1.1 yamaguch static void iavf_txr_clean(struct iavf_softc *, struct iavf_tx_ring *); 552 1.1 yamaguch static void iavf_rxr_clean(struct iavf_softc *, struct iavf_rx_ring *); 553 1.1 yamaguch static int iavf_txeof(struct iavf_softc *, struct iavf_tx_ring *, 554 1.1 yamaguch u_int, struct evcnt *); 555 1.1 yamaguch static int iavf_rxeof(struct iavf_softc *, struct iavf_rx_ring *, 556 1.1 yamaguch u_int, struct evcnt *); 557 1.1 yamaguch static int iavf_iff(struct iavf_softc *); 558 1.1 yamaguch static int iavf_iff_locked(struct iavf_softc *); 559 1.1 yamaguch static void iavf_post_request_queues(void *); 560 1.1 yamaguch static int iavf_sysctl_itr_handler(SYSCTLFN_PROTO); 561 1.1 yamaguch 562 1.1 yamaguch static int iavf_match(device_t, cfdata_t, void *); 563 1.1 yamaguch static void iavf_attach(device_t, device_t, void*); 564 1.1 yamaguch static int iavf_detach(device_t, int); 565 1.1 yamaguch static int iavf_finalize_teardown(device_t); 566 1.1 yamaguch 567 1.1 yamaguch CFATTACH_DECL3_NEW(iavf, sizeof(struct iavf_softc), 568 1.1 yamaguch iavf_match, iavf_attach, iavf_detach, NULL, NULL, NULL, 569 1.1 yamaguch DVF_DETACH_SHUTDOWN); 570 1.1 yamaguch 571 1.1 yamaguch static const struct iavf_product iavf_products[] = { 572 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_XL710_VF }, 573 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_XL710_VF_HV }, 574 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_X722_VF }, 575 1.1 yamaguch /* required last entry */ 576 1.1 yamaguch {0, 0} 577 1.1 yamaguch }; 578 1.1 yamaguch 579 1.1 yamaguch static const struct iavf_link_speed iavf_link_speeds[] = { 580 1.1 yamaguch { 0, 0 }, 581 1.1 yamaguch { IF_Mbps(100), IFM_100_TX }, 582 1.1 yamaguch { IF_Mbps(1000), IFM_1000_T }, 583 1.1 yamaguch { IF_Gbps(10), IFM_10G_T }, 584 1.1 yamaguch { IF_Gbps(40), IFM_40G_CR4 }, 585 1.1 yamaguch { IF_Gbps(20), IFM_20G_KR2 }, 586 1.1 yamaguch { IF_Gbps(25), IFM_25G_CR } 587 1.1 yamaguch }; 588 1.1 yamaguch 589 1.1 yamaguch static const struct iavf_aq_regs iavf_aq_regs = { 590 1.1 yamaguch .atq_tail = I40E_VF_ATQT1, 591 1.1 yamaguch .atq_tail_mask = I40E_VF_ATQT1_ATQT_MASK, 592 1.1 yamaguch .atq_head = I40E_VF_ATQH1, 593 1.1 yamaguch .atq_head_mask = I40E_VF_ARQH1_ARQH_MASK, 594 1.1 yamaguch .atq_len = I40E_VF_ATQLEN1, 595 1.1 yamaguch .atq_bal = I40E_VF_ATQBAL1, 596 1.1 yamaguch .atq_bah = I40E_VF_ATQBAH1, 597 1.1 yamaguch .atq_len_enable = I40E_VF_ATQLEN1_ATQENABLE_MASK, 598 1.1 yamaguch 599 1.1 yamaguch .arq_tail = I40E_VF_ARQT1, 600 1.1 yamaguch .arq_tail_mask = I40E_VF_ARQT1_ARQT_MASK, 601 1.1 yamaguch .arq_head = I40E_VF_ARQH1, 602 1.1 yamaguch .arq_head_mask = I40E_VF_ARQH1_ARQH_MASK, 603 1.1 yamaguch .arq_len = I40E_VF_ARQLEN1, 604 1.1 yamaguch .arq_bal = I40E_VF_ARQBAL1, 605 1.1 yamaguch .arq_bah = I40E_VF_ARQBAH1, 606 1.1 yamaguch .arq_len_enable = I40E_VF_ARQLEN1_ARQENABLE_MASK, 607 1.1 yamaguch }; 608 1.1 yamaguch 609 1.1 yamaguch static struct iavf_module_params iavf_params = { 610 1.1 yamaguch .debug = 0, 611 1.1 yamaguch .rx_itr = 0x07a, /* 4K intrs/sec */ 612 1.1 yamaguch .tx_itr = 0x07a, /* 4K intrs/sec */ 613 1.1 yamaguch .tx_ndescs = 512, 614 1.1 yamaguch .rx_ndescs = 256, 615 1.1 yamaguch .max_qps = INT_MAX, 616 1.1 yamaguch }; 617 1.1 yamaguch 618 1.1 yamaguch #define delaymsec(_x) DELAY(1000 * (_x)) 619 1.1 yamaguch #define iavf_rd(_s, _r) \ 620 1.1 yamaguch bus_space_read_4((_s)->sc_memt, (_s)->sc_memh, (_r)) 621 1.1 yamaguch #define iavf_wr(_s, _r, _v) \ 622 1.1 yamaguch bus_space_write_4((_s)->sc_memt, (_s)->sc_memh, (_r), (_v)) 623 1.1 yamaguch #define iavf_barrier(_s, _r, _l, _o) \ 624 1.1 yamaguch bus_space_barrier((_s)->sc_memt, (_s)->sc_memh, (_r), (_l), (_o)) 625 1.1 yamaguch #define iavf_flush(_s) (void)iavf_rd((_s), I40E_VFGEN_RSTAT) 626 1.1 yamaguch #define iavf_nqueues(_sc) (1 << ((_sc)->sc_nqueue_pairs - 1)) 627 1.1 yamaguch #define iavf_allqueues(_sc) ((1 << ((_sc)->sc_nqueue_pairs)) - 1) 628 1.1 yamaguch 629 1.1 yamaguch static inline void 630 1.6 yamaguch iavf_intr_barrier(void) 631 1.6 yamaguch { 632 1.6 yamaguch 633 1.6 yamaguch /* make all interrupt handler finished */ 634 1.6 yamaguch xc_barrier(0); 635 1.6 yamaguch } 636 1.6 yamaguch static inline void 637 1.1 yamaguch iavf_intr_enable(struct iavf_softc *sc) 638 1.1 yamaguch { 639 1.1 yamaguch 640 1.1 yamaguch iavf_wr(sc, I40E_VFINT_DYN_CTL01, I40E_VFINT_DYN_CTL0_INTENA_MASK | 641 1.1 yamaguch I40E_VFINT_DYN_CTL0_CLEARPBA_MASK | 642 1.1 yamaguch (IAVF_NOITR << I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT)); 643 1.1 yamaguch iavf_wr(sc, I40E_VFINT_ICR0_ENA1, I40E_VFINT_ICR0_ENA1_ADMINQ_MASK); 644 1.1 yamaguch iavf_flush(sc); 645 1.1 yamaguch } 646 1.1 yamaguch 647 1.1 yamaguch static inline void 648 1.1 yamaguch iavf_intr_disable(struct iavf_softc *sc) 649 1.1 yamaguch { 650 1.1 yamaguch 651 1.1 yamaguch iavf_wr(sc, I40E_VFINT_DYN_CTL01, 652 1.1 yamaguch (IAVF_NOITR << I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT)); 653 1.1 yamaguch iavf_wr(sc, I40E_VFINT_ICR0_ENA1, 0); 654 1.1 yamaguch iavf_flush(sc); 655 1.1 yamaguch } 656 1.1 yamaguch 657 1.1 yamaguch static inline void 658 1.1 yamaguch iavf_queue_intr_enable(struct iavf_softc *sc, unsigned int qid) 659 1.1 yamaguch { 660 1.1 yamaguch 661 1.1 yamaguch iavf_wr(sc, I40E_VFINT_DYN_CTLN1(qid), 662 1.1 yamaguch I40E_VFINT_DYN_CTLN1_INTENA_MASK | 663 1.1 yamaguch I40E_VFINT_DYN_CTLN1_CLEARPBA_MASK | 664 1.1 yamaguch (IAVF_NOITR << I40E_VFINT_DYN_CTLN1_ITR_INDX_SHIFT)); 665 1.1 yamaguch iavf_flush(sc); 666 1.1 yamaguch } 667 1.1 yamaguch 668 1.1 yamaguch static inline void 669 1.1 yamaguch iavf_queue_intr_disable(struct iavf_softc *sc, unsigned int qid) 670 1.1 yamaguch { 671 1.1 yamaguch 672 1.1 yamaguch iavf_wr(sc, I40E_VFINT_DYN_CTLN1(qid), 673 1.1 yamaguch (IAVF_NOITR << I40E_VFINT_DYN_CTLN1_ITR_INDX_SHIFT)); 674 1.1 yamaguch iavf_flush(sc); 675 1.1 yamaguch } 676 1.1 yamaguch 677 1.1 yamaguch static inline void 678 1.1 yamaguch iavf_aq_vc_set_opcode(struct ixl_aq_desc *iaq, uint32_t opcode) 679 1.1 yamaguch { 680 1.1 yamaguch struct iavf_aq_vc *vc; 681 1.1 yamaguch 682 1.1 yamaguch vc = (struct iavf_aq_vc *)&iaq->iaq_cookie; 683 1.1 yamaguch vc->iaq_vc_opcode = htole32(opcode); 684 1.1 yamaguch } 685 1.1 yamaguch 686 1.1 yamaguch static inline uint32_t 687 1.1 yamaguch iavf_aq_vc_get_opcode(const struct ixl_aq_desc *iaq) 688 1.1 yamaguch { 689 1.1 yamaguch const struct iavf_aq_vc *vc; 690 1.1 yamaguch 691 1.1 yamaguch vc = (const struct iavf_aq_vc *)&iaq->iaq_cookie; 692 1.1 yamaguch return le32toh(vc->iaq_vc_opcode); 693 1.1 yamaguch } 694 1.1 yamaguch 695 1.1 yamaguch static inline uint32_t 696 1.1 yamaguch iavf_aq_vc_get_retval(const struct ixl_aq_desc *iaq) 697 1.1 yamaguch { 698 1.1 yamaguch const struct iavf_aq_vc *vc; 699 1.1 yamaguch 700 1.1 yamaguch vc = (const struct iavf_aq_vc *)&iaq->iaq_cookie; 701 1.1 yamaguch return le32toh(vc->iaq_vc_retval); 702 1.1 yamaguch } 703 1.1 yamaguch 704 1.1 yamaguch static int 705 1.1 yamaguch iavf_match(device_t parent, cfdata_t match, void *aux) 706 1.1 yamaguch { 707 1.1 yamaguch const struct pci_attach_args *pa = aux; 708 1.1 yamaguch 709 1.1 yamaguch return (iavf_lookup(pa) != NULL) ? 1 : 0; 710 1.1 yamaguch } 711 1.1 yamaguch 712 1.1 yamaguch static void 713 1.1 yamaguch iavf_attach(device_t parent, device_t self, void *aux) 714 1.1 yamaguch { 715 1.1 yamaguch struct iavf_softc *sc; 716 1.1 yamaguch struct pci_attach_args *pa = aux; 717 1.1 yamaguch struct ifnet *ifp; 718 1.1 yamaguch struct ixl_aq_buf *aqb; 719 1.1 yamaguch pcireg_t memtype; 720 1.1 yamaguch char xnamebuf[MAXCOMLEN]; 721 1.1 yamaguch int error, i; 722 1.1 yamaguch 723 1.1 yamaguch sc = device_private(self); 724 1.1 yamaguch sc->sc_dev = self; 725 1.1 yamaguch ifp = &sc->sc_ec.ec_if; 726 1.1 yamaguch 727 1.1 yamaguch sc->sc_pa = *pa; 728 1.1 yamaguch sc->sc_dmat = (pci_dma64_available(pa)) ? pa->pa_dmat64 : pa->pa_dmat; 729 1.1 yamaguch sc->sc_aq_regs = &iavf_aq_regs; 730 1.1 yamaguch sc->sc_debuglevel = iavf_params.debug; 731 1.1 yamaguch sc->sc_tx_ring_ndescs = iavf_params.tx_ndescs; 732 1.1 yamaguch sc->sc_rx_ring_ndescs = iavf_params.rx_ndescs; 733 1.1 yamaguch sc->sc_tx_itr = iavf_params.tx_itr; 734 1.1 yamaguch sc->sc_rx_itr = iavf_params.rx_itr; 735 1.1 yamaguch sc->sc_nqps_req = MIN(ncpu, iavf_params.max_qps); 736 1.1 yamaguch iavf_prepare_fakeaddr(sc); 737 1.1 yamaguch 738 1.1 yamaguch sc->sc_mac_type = iavf_mactype(PCI_PRODUCT(pa->pa_id)); 739 1.1 yamaguch iavf_pci_csr_setup(pa->pa_pc, pa->pa_tag); 740 1.1 yamaguch 741 1.1 yamaguch memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, IAVF_PCIREG); 742 1.1 yamaguch if (pci_mapreg_map(pa, IAVF_PCIREG, memtype, 0, 743 1.1 yamaguch &sc->sc_memt, &sc->sc_memh, NULL, &sc->sc_mems)) { 744 1.1 yamaguch aprint_error(": unable to map registers\n"); 745 1.1 yamaguch return; 746 1.1 yamaguch } 747 1.1 yamaguch 748 1.1 yamaguch if (iavf_wait_active(sc) != 0) { 749 1.1 yamaguch aprint_error(": VF reset timed out\n"); 750 1.1 yamaguch goto unmap; 751 1.1 yamaguch } 752 1.1 yamaguch 753 1.1 yamaguch mutex_init(&sc->sc_cfg_lock, MUTEX_DEFAULT, IPL_SOFTNET); 754 1.1 yamaguch mutex_init(&sc->sc_adminq_lock, MUTEX_DEFAULT, IPL_NET); 755 1.1 yamaguch SIMPLEQ_INIT(&sc->sc_atq_idle); 756 1.1 yamaguch SIMPLEQ_INIT(&sc->sc_atq_live); 757 1.1 yamaguch SIMPLEQ_INIT(&sc->sc_arq_idle); 758 1.1 yamaguch SIMPLEQ_INIT(&sc->sc_arq_live); 759 1.1 yamaguch sc->sc_arq_cons = 0; 760 1.1 yamaguch sc->sc_arq_prod = 0; 761 1.1 yamaguch aqb = NULL; 762 1.1 yamaguch 763 1.1 yamaguch if (iavf_dmamem_alloc(sc->sc_dmat, &sc->sc_atq, 764 1.1 yamaguch sizeof(struct ixl_aq_desc) * IAVF_AQ_NUM, IAVF_AQ_ALIGN) != 0) { 765 1.1 yamaguch aprint_error(": unable to allocate atq\n"); 766 1.1 yamaguch goto free_mutex; 767 1.1 yamaguch } 768 1.1 yamaguch 769 1.1 yamaguch if (iavf_dmamem_alloc(sc->sc_dmat, &sc->sc_arq, 770 1.1 yamaguch sizeof(struct ixl_aq_desc) * IAVF_AQ_NUM, IAVF_AQ_ALIGN) != 0) { 771 1.1 yamaguch aprint_error(": unable to allocate arq\n"); 772 1.1 yamaguch goto free_atq; 773 1.1 yamaguch } 774 1.1 yamaguch 775 1.1 yamaguch for (i = 0; i < IAVF_AQ_NUM; i++) { 776 1.1 yamaguch aqb = iavf_aqb_get(sc, NULL); 777 1.1 yamaguch if (aqb != NULL) { 778 1.1 yamaguch iavf_aqb_put_locked(&sc->sc_arq_idle, aqb); 779 1.1 yamaguch } 780 1.1 yamaguch } 781 1.1 yamaguch aqb = NULL; 782 1.1 yamaguch 783 1.1 yamaguch if (!iavf_arq_fill(sc)) { 784 1.1 yamaguch aprint_error(": unable to fill arq descriptors\n"); 785 1.1 yamaguch goto free_arq; 786 1.1 yamaguch } 787 1.1 yamaguch 788 1.1 yamaguch if (iavf_init_admin_queue(sc) != 0) { 789 1.1 yamaguch aprint_error(": unable to initialize admin queue\n"); 790 1.1 yamaguch goto shutdown; 791 1.1 yamaguch } 792 1.1 yamaguch 793 1.1 yamaguch aqb = iavf_aqb_get(sc, NULL); 794 1.1 yamaguch if (aqb == NULL) { 795 1.1 yamaguch aprint_error(": unable to allocate buffer for ATQ\n"); 796 1.1 yamaguch goto shutdown; 797 1.1 yamaguch } 798 1.1 yamaguch 799 1.1 yamaguch error = iavf_get_version(sc, aqb); 800 1.1 yamaguch switch (error) { 801 1.1 yamaguch case 0: 802 1.1 yamaguch break; 803 1.1 yamaguch case ETIMEDOUT: 804 1.1 yamaguch aprint_error(": timeout waiting for VF version\n"); 805 1.1 yamaguch goto shutdown; 806 1.1 yamaguch case ENOTSUP: 807 1.1 yamaguch aprint_error(": unsupported VF version %d\n", sc->sc_major_ver); 808 1.1 yamaguch goto shutdown; 809 1.1 yamaguch default: 810 1.1 yamaguch aprint_error(":unable to get VF interface version\n"); 811 1.1 yamaguch goto shutdown; 812 1.1 yamaguch } 813 1.1 yamaguch 814 1.1 yamaguch if (iavf_get_vf_resources(sc, aqb) != 0) { 815 1.1 yamaguch aprint_error(": timeout waiting for VF resources\n"); 816 1.1 yamaguch goto shutdown; 817 1.1 yamaguch } 818 1.1 yamaguch 819 1.1 yamaguch aprint_normal(", VF version %d.%d%s", 820 1.1 yamaguch sc->sc_major_ver, sc->sc_minor_ver, 821 1.1 yamaguch (sc->sc_minor_ver > IAVF_VF_MINOR) ? "(minor mismatch)" : ""); 822 1.1 yamaguch aprint_normal(", VF %d, VSI %d", sc->sc_vf_id, sc->sc_vsi_id); 823 1.1 yamaguch aprint_normal("\n"); 824 1.1 yamaguch aprint_naive("\n"); 825 1.1 yamaguch 826 1.1 yamaguch aprint_normal_dev(self, "Ethernet address %s\n", 827 1.1 yamaguch ether_sprintf(sc->sc_enaddr)); 828 1.1 yamaguch 829 1.1 yamaguch if (iavf_queue_pairs_alloc(sc) != 0) { 830 1.1 yamaguch goto shutdown; 831 1.1 yamaguch } 832 1.1 yamaguch 833 1.1 yamaguch if (iavf_setup_interrupts(sc) != 0) { 834 1.1 yamaguch goto free_queue_pairs; 835 1.1 yamaguch } 836 1.1 yamaguch 837 1.1 yamaguch if (iavf_config_irq_map(sc, aqb) != 0) { 838 1.1 yamaguch aprint_error(", timed out waiting for IRQ map response\n"); 839 1.1 yamaguch goto teardown_intrs; 840 1.1 yamaguch } 841 1.1 yamaguch 842 1.1 yamaguch if (iavf_setup_sysctls(sc) != 0) { 843 1.1 yamaguch goto teardown_intrs; 844 1.1 yamaguch } 845 1.1 yamaguch 846 1.1 yamaguch if (iavf_setup_stats(sc) != 0) { 847 1.1 yamaguch goto teardown_sysctls; 848 1.1 yamaguch } 849 1.1 yamaguch 850 1.1 yamaguch iavf_aqb_put_locked(&sc->sc_atq_idle, aqb); 851 1.1 yamaguch aqb = NULL; 852 1.1 yamaguch 853 1.1 yamaguch snprintf(xnamebuf, sizeof(xnamebuf), 854 1.1 yamaguch "%s_adminq_cv", device_xname(self)); 855 1.1 yamaguch cv_init(&sc->sc_adminq_cv, xnamebuf); 856 1.1 yamaguch 857 1.1 yamaguch callout_init(&sc->sc_tick, CALLOUT_MPSAFE); 858 1.1 yamaguch callout_setfunc(&sc->sc_tick, iavf_tick, sc); 859 1.1 yamaguch 860 1.1 yamaguch iavf_work_set(&sc->sc_reset_task, iavf_reset_start, sc); 861 1.1 yamaguch iavf_work_set(&sc->sc_arq_refill, iavf_arq_refill, sc); 862 1.1 yamaguch iavf_work_set(&sc->sc_wdto_task, iavf_watchdog_timeout, sc); 863 1.1 yamaguch iavf_work_set(&sc->sc_req_queues_task, iavf_post_request_queues, sc); 864 1.1 yamaguch snprintf(xnamebuf, sizeof(xnamebuf), "%s_wq_cfg", device_xname(self)); 865 1.1 yamaguch sc->sc_workq = iavf_workq_create(xnamebuf, IAVF_WORKQUEUE_PRI, 866 1.1 yamaguch IPL_NET, WQ_MPSAFE); 867 1.1 yamaguch if (sc->sc_workq == NULL) 868 1.1 yamaguch goto destroy_cv; 869 1.1 yamaguch 870 1.1 yamaguch snprintf(xnamebuf, sizeof(xnamebuf), "%s_wq_txrx", device_xname(self)); 871 1.1 yamaguch error = workqueue_create(&sc->sc_workq_txrx, xnamebuf, 872 1.1 yamaguch iavf_handle_queue_wk, sc, IAVF_WORKQUEUE_PRI, IPL_NET, 873 1.1 yamaguch WQ_PERCPU|WQ_MPSAFE); 874 1.1 yamaguch if (error != 0) { 875 1.1 yamaguch sc->sc_workq_txrx = NULL; 876 1.1 yamaguch goto teardown_wqs; 877 1.1 yamaguch } 878 1.1 yamaguch 879 1.14 riastrad if_initialize(ifp); 880 1.1 yamaguch 881 1.1 yamaguch strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ); 882 1.1 yamaguch 883 1.1 yamaguch ifp->if_softc = sc; 884 1.1 yamaguch ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 885 1.1 yamaguch ifp->if_extflags = IFEF_MPSAFE; 886 1.1 yamaguch ifp->if_ioctl = iavf_ioctl; 887 1.1 yamaguch ifp->if_start = iavf_start; 888 1.1 yamaguch ifp->if_transmit = iavf_transmit; 889 1.1 yamaguch ifp->if_watchdog = NULL; 890 1.1 yamaguch ifp->if_init = iavf_init; 891 1.1 yamaguch ifp->if_stop = iavf_stop; 892 1.1 yamaguch 893 1.1 yamaguch IFQ_SET_MAXLEN(&ifp->if_snd, sc->sc_tx_ring_ndescs); 894 1.1 yamaguch IFQ_SET_READY(&ifp->if_snd); 895 1.1 yamaguch sc->sc_ipq = if_percpuq_create(ifp); 896 1.1 yamaguch 897 1.1 yamaguch ifp->if_capabilities |= IAVF_IFCAP_RXCSUM; 898 1.1 yamaguch ifp->if_capabilities |= IAVF_IFCAP_TXCSUM; 899 1.1 yamaguch 900 1.1 yamaguch ether_set_vlan_cb(&sc->sc_ec, iavf_vlan_cb); 901 1.1 yamaguch sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_HWTAGGING; 902 1.1 yamaguch sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_HWFILTER; 903 1.1 yamaguch sc->sc_ec.ec_capenable = sc->sc_ec.ec_capabilities; 904 1.1 yamaguch 905 1.1 yamaguch ether_set_ifflags_cb(&sc->sc_ec, iavf_ifflags_cb); 906 1.1 yamaguch 907 1.1 yamaguch sc->sc_ec.ec_ifmedia = &sc->sc_media; 908 1.1 yamaguch ifmedia_init_with_lock(&sc->sc_media, IFM_IMASK, iavf_media_change, 909 1.1 yamaguch iavf_media_status, &sc->sc_cfg_lock); 910 1.1 yamaguch 911 1.1 yamaguch ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL); 912 1.1 yamaguch ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO); 913 1.1 yamaguch 914 1.1 yamaguch if_deferred_start_init(ifp, NULL); 915 1.1 yamaguch ether_ifattach(ifp, sc->sc_enaddr); 916 1.1 yamaguch 917 1.1 yamaguch sc->sc_txrx_workqueue = true; 918 1.1 yamaguch sc->sc_tx_process_limit = IAVF_TX_PROCESS_LIMIT; 919 1.1 yamaguch sc->sc_rx_process_limit = IAVF_RX_PROCESS_LIMIT; 920 1.1 yamaguch sc->sc_tx_intr_process_limit = IAVF_TX_INTR_PROCESS_LIMIT; 921 1.1 yamaguch sc->sc_rx_intr_process_limit = IAVF_RX_INTR_PROCESS_LIMIT; 922 1.1 yamaguch 923 1.1 yamaguch if_register(ifp); 924 1.1 yamaguch if_link_state_change(ifp, sc->sc_link_state); 925 1.1 yamaguch iavf_intr_enable(sc); 926 1.1 yamaguch if (sc->sc_nqps_vsi < sc->sc_nqps_req) 927 1.1 yamaguch iavf_work_add(sc->sc_workq, &sc->sc_req_queues_task); 928 1.1 yamaguch sc->sc_attached = true; 929 1.1 yamaguch return; 930 1.1 yamaguch 931 1.1 yamaguch teardown_wqs: 932 1.1 yamaguch config_finalize_register(self, iavf_finalize_teardown); 933 1.1 yamaguch destroy_cv: 934 1.1 yamaguch cv_destroy(&sc->sc_adminq_cv); 935 1.1 yamaguch callout_destroy(&sc->sc_tick); 936 1.1 yamaguch iavf_teardown_stats(sc); 937 1.1 yamaguch teardown_sysctls: 938 1.1 yamaguch iavf_teardown_sysctls(sc); 939 1.1 yamaguch teardown_intrs: 940 1.1 yamaguch iavf_teardown_interrupts(sc); 941 1.1 yamaguch free_queue_pairs: 942 1.1 yamaguch iavf_queue_pairs_free(sc); 943 1.1 yamaguch shutdown: 944 1.1 yamaguch if (aqb != NULL) 945 1.1 yamaguch iavf_aqb_put_locked(&sc->sc_atq_idle, aqb); 946 1.1 yamaguch iavf_cleanup_admin_queue(sc); 947 1.1 yamaguch iavf_aqb_clean(&sc->sc_atq_idle, sc->sc_dmat); 948 1.1 yamaguch iavf_aqb_clean(&sc->sc_arq_idle, sc->sc_dmat); 949 1.1 yamaguch free_arq: 950 1.1 yamaguch iavf_dmamem_free(sc->sc_dmat, &sc->sc_arq); 951 1.1 yamaguch free_atq: 952 1.1 yamaguch iavf_dmamem_free(sc->sc_dmat, &sc->sc_atq); 953 1.1 yamaguch free_mutex: 954 1.1 yamaguch mutex_destroy(&sc->sc_cfg_lock); 955 1.1 yamaguch mutex_destroy(&sc->sc_adminq_lock); 956 1.1 yamaguch unmap: 957 1.1 yamaguch bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems); 958 1.1 yamaguch sc->sc_mems = 0; 959 1.1 yamaguch sc->sc_attached = false; 960 1.1 yamaguch } 961 1.1 yamaguch 962 1.1 yamaguch static int 963 1.1 yamaguch iavf_detach(device_t self, int flags) 964 1.1 yamaguch { 965 1.1 yamaguch struct iavf_softc *sc = device_private(self); 966 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 967 1.1 yamaguch 968 1.1 yamaguch if (!sc->sc_attached) 969 1.1 yamaguch return 0; 970 1.1 yamaguch 971 1.1 yamaguch iavf_stop(ifp, 1); 972 1.1 yamaguch 973 1.1 yamaguch /* 974 1.1 yamaguch * set a dummy function to halt callout safely 975 1.1 yamaguch * even if a workqueue entry calls callout_schedule() 976 1.1 yamaguch */ 977 1.1 yamaguch callout_setfunc(&sc->sc_tick, iavf_tick_halt, sc); 978 1.1 yamaguch iavf_work_wait(sc->sc_workq, &sc->sc_reset_task); 979 1.1 yamaguch iavf_work_wait(sc->sc_workq, &sc->sc_wdto_task); 980 1.1 yamaguch 981 1.1 yamaguch callout_halt(&sc->sc_tick, NULL); 982 1.1 yamaguch callout_destroy(&sc->sc_tick); 983 1.1 yamaguch 984 1.6 yamaguch /* detach the I/F before stop adminq due to callbacks */ 985 1.6 yamaguch ether_ifdetach(ifp); 986 1.6 yamaguch if_detach(ifp); 987 1.6 yamaguch ifmedia_fini(&sc->sc_media); 988 1.6 yamaguch if_percpuq_destroy(sc->sc_ipq); 989 1.6 yamaguch 990 1.6 yamaguch iavf_intr_disable(sc); 991 1.6 yamaguch iavf_intr_barrier(); 992 1.6 yamaguch iavf_work_wait(sc->sc_workq, &sc->sc_arq_refill); 993 1.6 yamaguch 994 1.6 yamaguch mutex_enter(&sc->sc_adminq_lock); 995 1.1 yamaguch iavf_cleanup_admin_queue(sc); 996 1.6 yamaguch mutex_exit(&sc->sc_adminq_lock); 997 1.1 yamaguch iavf_aqb_clean(&sc->sc_atq_idle, sc->sc_dmat); 998 1.1 yamaguch iavf_aqb_clean(&sc->sc_arq_idle, sc->sc_dmat); 999 1.1 yamaguch iavf_dmamem_free(sc->sc_dmat, &sc->sc_arq); 1000 1.1 yamaguch iavf_dmamem_free(sc->sc_dmat, &sc->sc_atq); 1001 1.1 yamaguch cv_destroy(&sc->sc_adminq_cv); 1002 1.1 yamaguch 1003 1.6 yamaguch iavf_workq_destroy(sc->sc_workq); 1004 1.6 yamaguch sc->sc_workq = NULL; 1005 1.6 yamaguch 1006 1.1 yamaguch iavf_queue_pairs_free(sc); 1007 1.1 yamaguch iavf_teardown_interrupts(sc); 1008 1.1 yamaguch iavf_teardown_sysctls(sc); 1009 1.1 yamaguch iavf_teardown_stats(sc); 1010 1.1 yamaguch bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems); 1011 1.1 yamaguch 1012 1.1 yamaguch mutex_destroy(&sc->sc_adminq_lock); 1013 1.1 yamaguch mutex_destroy(&sc->sc_cfg_lock); 1014 1.1 yamaguch 1015 1.1 yamaguch return 0; 1016 1.1 yamaguch } 1017 1.1 yamaguch 1018 1.1 yamaguch static int 1019 1.1 yamaguch iavf_finalize_teardown(device_t self) 1020 1.1 yamaguch { 1021 1.1 yamaguch struct iavf_softc *sc = device_private(self); 1022 1.1 yamaguch 1023 1.1 yamaguch if (sc->sc_workq != NULL) { 1024 1.1 yamaguch iavf_workq_destroy(sc->sc_workq); 1025 1.1 yamaguch sc->sc_workq = NULL; 1026 1.1 yamaguch } 1027 1.1 yamaguch 1028 1.1 yamaguch if (sc->sc_workq_txrx != NULL) { 1029 1.1 yamaguch workqueue_destroy(sc->sc_workq_txrx); 1030 1.1 yamaguch sc->sc_workq_txrx = NULL; 1031 1.1 yamaguch } 1032 1.1 yamaguch 1033 1.1 yamaguch return 0; 1034 1.1 yamaguch } 1035 1.1 yamaguch 1036 1.1 yamaguch static int 1037 1.1 yamaguch iavf_init(struct ifnet *ifp) 1038 1.1 yamaguch { 1039 1.1 yamaguch struct iavf_softc *sc; 1040 1.1 yamaguch int rv; 1041 1.1 yamaguch 1042 1.1 yamaguch sc = ifp->if_softc; 1043 1.1 yamaguch mutex_enter(&sc->sc_cfg_lock); 1044 1.1 yamaguch rv = iavf_init_locked(sc); 1045 1.1 yamaguch mutex_exit(&sc->sc_cfg_lock); 1046 1.1 yamaguch 1047 1.1 yamaguch return rv; 1048 1.1 yamaguch } 1049 1.1 yamaguch 1050 1.1 yamaguch static int 1051 1.1 yamaguch iavf_init_locked(struct iavf_softc *sc) 1052 1.1 yamaguch { 1053 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 1054 1.1 yamaguch unsigned int i; 1055 1.1 yamaguch int error; 1056 1.1 yamaguch 1057 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_cfg_lock)); 1058 1.1 yamaguch 1059 1.1 yamaguch if (ISSET(ifp->if_flags, IFF_RUNNING)) 1060 1.1 yamaguch iavf_stop_locked(sc); 1061 1.1 yamaguch 1062 1.1 yamaguch if (sc->sc_resetting) 1063 1.1 yamaguch return ENXIO; 1064 1.1 yamaguch 1065 1.1 yamaguch error = iavf_reinit(sc); 1066 1.1 yamaguch if (error) { 1067 1.1 yamaguch iavf_stop_locked(sc); 1068 1.1 yamaguch return error; 1069 1.1 yamaguch } 1070 1.1 yamaguch 1071 1.1 yamaguch SET(ifp->if_flags, IFF_RUNNING); 1072 1.1 yamaguch CLR(ifp->if_flags, IFF_OACTIVE); 1073 1.1 yamaguch 1074 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 1075 1.1 yamaguch iavf_wr(sc, I40E_VFINT_ITRN1(IAVF_ITR_RX, i), sc->sc_rx_itr); 1076 1.1 yamaguch iavf_wr(sc, I40E_VFINT_ITRN1(IAVF_ITR_TX, i), sc->sc_tx_itr); 1077 1.1 yamaguch } 1078 1.1 yamaguch iavf_wr(sc, I40E_VFINT_ITR01(IAVF_ITR_RX), sc->sc_rx_itr); 1079 1.1 yamaguch iavf_wr(sc, I40E_VFINT_ITR01(IAVF_ITR_TX), sc->sc_tx_itr); 1080 1.1 yamaguch iavf_wr(sc, I40E_VFINT_ITR01(IAVF_ITR_MISC), 0); 1081 1.1 yamaguch 1082 1.1 yamaguch error = iavf_iff_locked(sc); 1083 1.1 yamaguch if (error) { 1084 1.1 yamaguch iavf_stop_locked(sc); 1085 1.1 yamaguch return error; 1086 1.1 yamaguch }; 1087 1.1 yamaguch 1088 1.1 yamaguch /* ETHERCAP_VLAN_HWFILTER can not be disabled */ 1089 1.1 yamaguch SET(sc->sc_ec.ec_capenable, ETHERCAP_VLAN_HWFILTER); 1090 1.1 yamaguch 1091 1.1 yamaguch callout_schedule(&sc->sc_tick, IAVF_TICK_INTERVAL); 1092 1.1 yamaguch return 0; 1093 1.1 yamaguch } 1094 1.1 yamaguch 1095 1.1 yamaguch static int 1096 1.1 yamaguch iavf_reinit(struct iavf_softc *sc) 1097 1.1 yamaguch { 1098 1.1 yamaguch struct iavf_rx_ring *rxr; 1099 1.1 yamaguch struct iavf_tx_ring *txr; 1100 1.1 yamaguch unsigned int i; 1101 1.1 yamaguch uint32_t reg; 1102 1.1 yamaguch 1103 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_cfg_lock)); 1104 1.1 yamaguch 1105 1.1 yamaguch sc->sc_reset_up = true; 1106 1.1 yamaguch sc->sc_nqueue_pairs = MIN(sc->sc_nqps_alloc, sc->sc_nintrs - 1); 1107 1.1 yamaguch 1108 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 1109 1.1 yamaguch rxr = sc->sc_qps[i].qp_rxr; 1110 1.1 yamaguch txr = sc->sc_qps[i].qp_txr; 1111 1.1 yamaguch 1112 1.1 yamaguch iavf_rxfill(sc, rxr); 1113 1.1 yamaguch txr->txr_watchdog = IAVF_WATCHDOG_STOP; 1114 1.1 yamaguch } 1115 1.1 yamaguch 1116 1.1 yamaguch if (iavf_config_vsi_queues(sc) != 0) 1117 1.1 yamaguch return EIO; 1118 1.1 yamaguch 1119 1.1 yamaguch if (iavf_config_hena(sc) != 0) 1120 1.1 yamaguch return EIO; 1121 1.1 yamaguch 1122 1.1 yamaguch iavf_config_rss_key(sc); 1123 1.1 yamaguch iavf_config_rss_lut(sc); 1124 1.1 yamaguch 1125 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 1126 1.1 yamaguch iavf_queue_intr_enable(sc, i); 1127 1.1 yamaguch } 1128 1.1 yamaguch /* unmask */ 1129 1.1 yamaguch reg = iavf_rd(sc, I40E_VFINT_DYN_CTL01); 1130 1.1 yamaguch reg |= (IAVF_NOITR << I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT); 1131 1.1 yamaguch iavf_wr(sc, I40E_VFINT_DYN_CTL01, reg); 1132 1.1 yamaguch 1133 1.1 yamaguch if (iavf_queue_select(sc, IAVF_VC_OP_ENABLE_QUEUES) != 0) 1134 1.1 yamaguch return EIO; 1135 1.1 yamaguch 1136 1.1 yamaguch return 0; 1137 1.1 yamaguch } 1138 1.1 yamaguch 1139 1.1 yamaguch static void 1140 1.1 yamaguch iavf_stop(struct ifnet *ifp, int disable) 1141 1.1 yamaguch { 1142 1.1 yamaguch struct iavf_softc *sc; 1143 1.1 yamaguch 1144 1.1 yamaguch sc = ifp->if_softc; 1145 1.1 yamaguch mutex_enter(&sc->sc_cfg_lock); 1146 1.1 yamaguch iavf_stop_locked(sc); 1147 1.1 yamaguch mutex_exit(&sc->sc_cfg_lock); 1148 1.1 yamaguch } 1149 1.1 yamaguch 1150 1.1 yamaguch static void 1151 1.1 yamaguch iavf_stop_locked(struct iavf_softc *sc) 1152 1.1 yamaguch { 1153 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 1154 1.1 yamaguch struct iavf_rx_ring *rxr; 1155 1.1 yamaguch struct iavf_tx_ring *txr; 1156 1.1 yamaguch uint32_t reg; 1157 1.1 yamaguch unsigned int i; 1158 1.1 yamaguch 1159 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_cfg_lock)); 1160 1.1 yamaguch 1161 1.1 yamaguch CLR(ifp->if_flags, IFF_RUNNING); 1162 1.1 yamaguch sc->sc_reset_up = false; 1163 1.1 yamaguch callout_stop(&sc->sc_tick); 1164 1.1 yamaguch 1165 1.1 yamaguch if (!sc->sc_resetting) { 1166 1.1 yamaguch /* disable queues*/ 1167 1.1 yamaguch if (iavf_queue_select(sc, IAVF_VC_OP_DISABLE_QUEUES) != 0) { 1168 1.1 yamaguch goto die; 1169 1.1 yamaguch } 1170 1.1 yamaguch } 1171 1.1 yamaguch 1172 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 1173 1.1 yamaguch iavf_queue_intr_disable(sc, i); 1174 1.1 yamaguch } 1175 1.1 yamaguch 1176 1.1 yamaguch /* mask interrupts */ 1177 1.1 yamaguch reg = iavf_rd(sc, I40E_VFINT_DYN_CTL01); 1178 1.1 yamaguch reg |= I40E_VFINT_DYN_CTL0_INTENA_MSK_MASK | 1179 1.1 yamaguch (IAVF_NOITR << I40E_VFINT_DYN_CTL0_ITR_INDX_SHIFT); 1180 1.1 yamaguch iavf_wr(sc, I40E_VFINT_DYN_CTL01, reg); 1181 1.1 yamaguch 1182 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 1183 1.1 yamaguch rxr = sc->sc_qps[i].qp_rxr; 1184 1.1 yamaguch txr = sc->sc_qps[i].qp_txr; 1185 1.1 yamaguch 1186 1.1 yamaguch mutex_enter(&rxr->rxr_lock); 1187 1.1 yamaguch iavf_rxr_clean(sc, rxr); 1188 1.1 yamaguch mutex_exit(&rxr->rxr_lock); 1189 1.1 yamaguch 1190 1.1 yamaguch mutex_enter(&txr->txr_lock); 1191 1.1 yamaguch iavf_txr_clean(sc, txr); 1192 1.1 yamaguch mutex_exit(&txr->txr_lock); 1193 1.1 yamaguch 1194 1.1 yamaguch workqueue_wait(sc->sc_workq_txrx, 1195 1.1 yamaguch &sc->sc_qps[i].qp_work); 1196 1.1 yamaguch } 1197 1.1 yamaguch 1198 1.1 yamaguch return; 1199 1.1 yamaguch die: 1200 1.1 yamaguch if (!sc->sc_dead) { 1201 1.1 yamaguch sc->sc_dead = true; 1202 1.1 yamaguch log(LOG_INFO, "%s: Request VF reset\n", ifp->if_xname); 1203 1.1 yamaguch 1204 1.1 yamaguch iavf_work_set(&sc->sc_reset_task, iavf_reset_request, sc); 1205 1.1 yamaguch iavf_work_add(sc->sc_workq, &sc->sc_reset_task); 1206 1.1 yamaguch } 1207 1.1 yamaguch log(LOG_CRIT, "%s: failed to shut down rings\n", ifp->if_xname); 1208 1.1 yamaguch } 1209 1.1 yamaguch 1210 1.1 yamaguch static int 1211 1.1 yamaguch iavf_watchdog(struct iavf_tx_ring *txr) 1212 1.1 yamaguch { 1213 1.1 yamaguch struct iavf_softc *sc; 1214 1.1 yamaguch 1215 1.1 yamaguch sc = txr->txr_sc; 1216 1.1 yamaguch 1217 1.1 yamaguch mutex_enter(&txr->txr_lock); 1218 1.1 yamaguch 1219 1.1 yamaguch if (txr->txr_watchdog == IAVF_WATCHDOG_STOP 1220 1.1 yamaguch || --txr->txr_watchdog > 0) { 1221 1.1 yamaguch mutex_exit(&txr->txr_lock); 1222 1.1 yamaguch return 0; 1223 1.1 yamaguch } 1224 1.1 yamaguch 1225 1.1 yamaguch txr->txr_watchdog = IAVF_WATCHDOG_STOP; 1226 1.1 yamaguch txr->txr_watchdogto.ev_count++; 1227 1.1 yamaguch mutex_exit(&txr->txr_lock); 1228 1.1 yamaguch 1229 1.1 yamaguch device_printf(sc->sc_dev, "watchdog timeout on queue %d\n", 1230 1.1 yamaguch txr->txr_qid); 1231 1.1 yamaguch return 1; 1232 1.1 yamaguch } 1233 1.1 yamaguch 1234 1.1 yamaguch static void 1235 1.1 yamaguch iavf_watchdog_timeout(void *xsc) 1236 1.1 yamaguch { 1237 1.1 yamaguch struct iavf_softc *sc; 1238 1.1 yamaguch struct ifnet *ifp; 1239 1.1 yamaguch 1240 1.1 yamaguch sc = xsc; 1241 1.1 yamaguch ifp = &sc->sc_ec.ec_if; 1242 1.1 yamaguch 1243 1.1 yamaguch mutex_enter(&sc->sc_cfg_lock); 1244 1.1 yamaguch if (ISSET(ifp->if_flags, IFF_RUNNING)) 1245 1.1 yamaguch iavf_init_locked(sc); 1246 1.1 yamaguch mutex_exit(&sc->sc_cfg_lock); 1247 1.1 yamaguch } 1248 1.1 yamaguch 1249 1.1 yamaguch static int 1250 1.1 yamaguch iavf_media_change(struct ifnet *ifp) 1251 1.1 yamaguch { 1252 1.1 yamaguch struct iavf_softc *sc; 1253 1.1 yamaguch struct ifmedia *ifm; 1254 1.1 yamaguch 1255 1.1 yamaguch sc = ifp->if_softc; 1256 1.1 yamaguch ifm = &sc->sc_media; 1257 1.1 yamaguch 1258 1.1 yamaguch if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) 1259 1.1 yamaguch return EINVAL; 1260 1.1 yamaguch 1261 1.1 yamaguch switch (IFM_SUBTYPE(ifm->ifm_media)) { 1262 1.1 yamaguch case IFM_AUTO: 1263 1.1 yamaguch break; 1264 1.1 yamaguch default: 1265 1.1 yamaguch return EINVAL; 1266 1.1 yamaguch } 1267 1.1 yamaguch 1268 1.1 yamaguch return 0; 1269 1.1 yamaguch } 1270 1.1 yamaguch 1271 1.1 yamaguch static void 1272 1.1 yamaguch iavf_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) 1273 1.1 yamaguch { 1274 1.1 yamaguch struct iavf_softc *sc = ifp->if_softc; 1275 1.1 yamaguch 1276 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_cfg_lock)); 1277 1.1 yamaguch 1278 1.1 yamaguch ifmr->ifm_status = sc->sc_media_status; 1279 1.1 yamaguch ifmr->ifm_active = sc->sc_media_active; 1280 1.1 yamaguch } 1281 1.1 yamaguch 1282 1.1 yamaguch static int 1283 1.1 yamaguch iavf_ifflags_cb(struct ethercom *ec) 1284 1.1 yamaguch { 1285 1.1 yamaguch struct ifnet *ifp = &ec->ec_if; 1286 1.1 yamaguch struct iavf_softc *sc = ifp->if_softc; 1287 1.1 yamaguch 1288 1.1 yamaguch /* vlan hwfilter can not be disabled */ 1289 1.1 yamaguch SET(ec->ec_capenable, ETHERCAP_VLAN_HWFILTER); 1290 1.1 yamaguch 1291 1.1 yamaguch return iavf_iff(sc); 1292 1.1 yamaguch } 1293 1.1 yamaguch 1294 1.1 yamaguch static int 1295 1.1 yamaguch iavf_vlan_cb(struct ethercom *ec, uint16_t vid, bool set) 1296 1.1 yamaguch { 1297 1.1 yamaguch struct ifnet *ifp = &ec->ec_if; 1298 1.1 yamaguch struct iavf_softc *sc = ifp->if_softc; 1299 1.1 yamaguch int rv; 1300 1.1 yamaguch 1301 1.1 yamaguch mutex_enter(&sc->sc_cfg_lock); 1302 1.1 yamaguch 1303 1.1 yamaguch if (sc->sc_resetting) { 1304 1.1 yamaguch mutex_exit(&sc->sc_cfg_lock); 1305 1.1 yamaguch 1306 1.1 yamaguch /* all vlan id was already removed */ 1307 1.1 yamaguch if (!set) 1308 1.1 yamaguch return 0; 1309 1.1 yamaguch 1310 1.1 yamaguch return ENXIO; 1311 1.1 yamaguch } 1312 1.1 yamaguch 1313 1.1 yamaguch /* ETHERCAP_VLAN_HWFILTER can not be disabled */ 1314 1.1 yamaguch SET(sc->sc_ec.ec_capenable, ETHERCAP_VLAN_HWFILTER); 1315 1.1 yamaguch 1316 1.1 yamaguch if (set) { 1317 1.1 yamaguch rv = iavf_config_vlan_id(sc, vid, IAVF_VC_OP_ADD_VLAN); 1318 1.1 yamaguch if (!ISSET(sc->sc_ec.ec_capenable, ETHERCAP_VLAN_HWTAGGING)) { 1319 1.1 yamaguch iavf_config_vlan_stripping(sc, 1320 1.1 yamaguch sc->sc_ec.ec_capenable); 1321 1.1 yamaguch } 1322 1.1 yamaguch } else { 1323 1.1 yamaguch rv = iavf_config_vlan_id(sc, vid, IAVF_VC_OP_DEL_VLAN); 1324 1.1 yamaguch } 1325 1.1 yamaguch 1326 1.1 yamaguch mutex_exit(&sc->sc_cfg_lock); 1327 1.1 yamaguch 1328 1.1 yamaguch if (rv != 0) 1329 1.1 yamaguch return EIO; 1330 1.1 yamaguch 1331 1.1 yamaguch return 0; 1332 1.1 yamaguch } 1333 1.1 yamaguch 1334 1.1 yamaguch static int 1335 1.1 yamaguch iavf_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1336 1.1 yamaguch { 1337 1.1 yamaguch struct ifreq *ifr = (struct ifreq *)data; 1338 1.1 yamaguch struct iavf_softc *sc = (struct iavf_softc *)ifp->if_softc; 1339 1.1 yamaguch const struct sockaddr *sa; 1340 1.1 yamaguch uint8_t addrhi[ETHER_ADDR_LEN], addrlo[ETHER_ADDR_LEN]; 1341 1.1 yamaguch int s, error = 0; 1342 1.1 yamaguch unsigned int nmtu; 1343 1.1 yamaguch 1344 1.1 yamaguch switch (cmd) { 1345 1.1 yamaguch case SIOCSIFMTU: 1346 1.1 yamaguch nmtu = ifr->ifr_mtu; 1347 1.1 yamaguch 1348 1.1 yamaguch if (nmtu < IAVF_MIN_MTU || nmtu > IAVF_MAX_MTU) { 1349 1.1 yamaguch error = EINVAL; 1350 1.1 yamaguch break; 1351 1.1 yamaguch } 1352 1.1 yamaguch if (ifp->if_mtu != nmtu) { 1353 1.1 yamaguch s = splnet(); 1354 1.1 yamaguch error = ether_ioctl(ifp, cmd, data); 1355 1.1 yamaguch splx(s); 1356 1.1 yamaguch if (error == ENETRESET) 1357 1.1 yamaguch error = iavf_init(ifp); 1358 1.1 yamaguch } 1359 1.1 yamaguch break; 1360 1.1 yamaguch case SIOCADDMULTI: 1361 1.1 yamaguch sa = ifreq_getaddr(SIOCADDMULTI, ifr); 1362 1.1 yamaguch if (ether_addmulti(sa, &sc->sc_ec) == ENETRESET) { 1363 1.1 yamaguch error = ether_multiaddr(sa, addrlo, addrhi); 1364 1.1 yamaguch if (error != 0) 1365 1.1 yamaguch return error; 1366 1.1 yamaguch 1367 1.1 yamaguch error = iavf_add_multi(sc, addrlo, addrhi); 1368 1.1 yamaguch if (error != 0 && error != ENETRESET) { 1369 1.1 yamaguch ether_delmulti(sa, &sc->sc_ec); 1370 1.1 yamaguch error = EIO; 1371 1.1 yamaguch } 1372 1.1 yamaguch } 1373 1.1 yamaguch break; 1374 1.1 yamaguch 1375 1.1 yamaguch case SIOCDELMULTI: 1376 1.1 yamaguch sa = ifreq_getaddr(SIOCDELMULTI, ifr); 1377 1.1 yamaguch if (ether_delmulti(sa, &sc->sc_ec) == ENETRESET) { 1378 1.1 yamaguch error = ether_multiaddr(sa, addrlo, addrhi); 1379 1.1 yamaguch if (error != 0) 1380 1.1 yamaguch return error; 1381 1.1 yamaguch 1382 1.1 yamaguch error = iavf_del_multi(sc, addrlo, addrhi); 1383 1.1 yamaguch } 1384 1.1 yamaguch break; 1385 1.1 yamaguch 1386 1.1 yamaguch default: 1387 1.1 yamaguch s = splnet(); 1388 1.1 yamaguch error = ether_ioctl(ifp, cmd, data); 1389 1.1 yamaguch splx(s); 1390 1.1 yamaguch } 1391 1.1 yamaguch 1392 1.1 yamaguch if (error == ENETRESET) 1393 1.1 yamaguch error = iavf_iff(sc); 1394 1.1 yamaguch 1395 1.1 yamaguch return error; 1396 1.1 yamaguch } 1397 1.1 yamaguch 1398 1.1 yamaguch static int 1399 1.1 yamaguch iavf_iff(struct iavf_softc *sc) 1400 1.1 yamaguch { 1401 1.1 yamaguch int error; 1402 1.1 yamaguch 1403 1.1 yamaguch mutex_enter(&sc->sc_cfg_lock); 1404 1.1 yamaguch error = iavf_iff_locked(sc); 1405 1.1 yamaguch mutex_exit(&sc->sc_cfg_lock); 1406 1.1 yamaguch 1407 1.1 yamaguch return error; 1408 1.1 yamaguch } 1409 1.1 yamaguch 1410 1.1 yamaguch static int 1411 1.1 yamaguch iavf_iff_locked(struct iavf_softc *sc) 1412 1.1 yamaguch { 1413 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 1414 1.1 yamaguch int unicast, multicast; 1415 1.1 yamaguch const uint8_t *enaddr; 1416 1.1 yamaguch 1417 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_cfg_lock)); 1418 1.1 yamaguch 1419 1.1 yamaguch if (!ISSET(ifp->if_flags, IFF_RUNNING)) 1420 1.1 yamaguch return 0; 1421 1.1 yamaguch 1422 1.1 yamaguch unicast = 0; 1423 1.1 yamaguch multicast = 0; 1424 1.1 yamaguch if (ISSET(ifp->if_flags, IFF_PROMISC)) { 1425 1.1 yamaguch unicast = 1; 1426 1.1 yamaguch multicast = 1; 1427 1.1 yamaguch } else if (ISSET(ifp->if_flags, IFF_ALLMULTI)) { 1428 1.1 yamaguch multicast = 1; 1429 1.1 yamaguch } 1430 1.1 yamaguch 1431 1.1 yamaguch iavf_config_promisc_mode(sc, unicast, multicast); 1432 1.1 yamaguch 1433 1.1 yamaguch iavf_config_vlan_stripping(sc, sc->sc_ec.ec_capenable); 1434 1.1 yamaguch 1435 1.1 yamaguch enaddr = CLLADDR(ifp->if_sadl); 1436 1.1 yamaguch if (memcmp(enaddr, sc->sc_enaddr_added, ETHER_ADDR_LEN) != 0) { 1437 1.1 yamaguch if (!iavf_is_etheranyaddr(sc->sc_enaddr_added)) { 1438 1.1 yamaguch iavf_eth_addr(sc, sc->sc_enaddr_added, 1439 1.1 yamaguch IAVF_VC_OP_DEL_ETH_ADDR); 1440 1.1 yamaguch } 1441 1.1 yamaguch memcpy(sc->sc_enaddr_added, enaddr, ETHER_ADDR_LEN); 1442 1.1 yamaguch iavf_eth_addr(sc, enaddr, IAVF_VC_OP_ADD_ETH_ADDR); 1443 1.1 yamaguch } 1444 1.1 yamaguch 1445 1.1 yamaguch return 0; 1446 1.1 yamaguch } 1447 1.1 yamaguch 1448 1.1 yamaguch static const struct iavf_product * 1449 1.1 yamaguch iavf_lookup(const struct pci_attach_args *pa) 1450 1.1 yamaguch { 1451 1.1 yamaguch const struct iavf_product *iavfp; 1452 1.1 yamaguch 1453 1.1 yamaguch for (iavfp = iavf_products; iavfp->vendor_id != 0; iavfp++) { 1454 1.1 yamaguch if (PCI_VENDOR(pa->pa_id) == iavfp->vendor_id && 1455 1.1 yamaguch PCI_PRODUCT(pa->pa_id) == iavfp->product_id) 1456 1.1 yamaguch return iavfp; 1457 1.1 yamaguch } 1458 1.1 yamaguch 1459 1.1 yamaguch return NULL; 1460 1.1 yamaguch } 1461 1.1 yamaguch 1462 1.1 yamaguch static enum i40e_mac_type 1463 1.1 yamaguch iavf_mactype(pci_product_id_t id) 1464 1.1 yamaguch { 1465 1.1 yamaguch 1466 1.1 yamaguch switch (id) { 1467 1.1 yamaguch case PCI_PRODUCT_INTEL_XL710_VF: 1468 1.1 yamaguch case PCI_PRODUCT_INTEL_XL710_VF_HV: 1469 1.1 yamaguch return I40E_MAC_VF; 1470 1.1 yamaguch case PCI_PRODUCT_INTEL_X722_VF: 1471 1.1 yamaguch return I40E_MAC_X722_VF; 1472 1.1 yamaguch } 1473 1.1 yamaguch 1474 1.1 yamaguch return I40E_MAC_GENERIC; 1475 1.1 yamaguch } 1476 1.1 yamaguch 1477 1.1 yamaguch static const struct iavf_link_speed * 1478 1.1 yamaguch iavf_find_link_speed(struct iavf_softc *sc, uint32_t link_speed) 1479 1.1 yamaguch { 1480 1.1 yamaguch size_t i; 1481 1.1 yamaguch 1482 1.1 yamaguch for (i = 0; i < __arraycount(iavf_link_speeds); i++) { 1483 1.1 yamaguch if (link_speed & (1 << i)) 1484 1.1 yamaguch return (&iavf_link_speeds[i]); 1485 1.1 yamaguch } 1486 1.1 yamaguch 1487 1.1 yamaguch return NULL; 1488 1.1 yamaguch } 1489 1.1 yamaguch 1490 1.1 yamaguch static void 1491 1.1 yamaguch iavf_pci_csr_setup(pci_chipset_tag_t pc, pcitag_t tag) 1492 1.1 yamaguch { 1493 1.1 yamaguch pcireg_t csr; 1494 1.1 yamaguch 1495 1.1 yamaguch csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 1496 1.1 yamaguch csr |= (PCI_COMMAND_MASTER_ENABLE | 1497 1.1 yamaguch PCI_COMMAND_MEM_ENABLE); 1498 1.1 yamaguch pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr); 1499 1.1 yamaguch } 1500 1.1 yamaguch 1501 1.1 yamaguch static int 1502 1.1 yamaguch iavf_wait_active(struct iavf_softc *sc) 1503 1.1 yamaguch { 1504 1.1 yamaguch int tries; 1505 1.1 yamaguch uint32_t reg; 1506 1.1 yamaguch 1507 1.1 yamaguch for (tries = 0; tries < 100; tries++) { 1508 1.1 yamaguch reg = iavf_rd(sc, I40E_VFGEN_RSTAT) & 1509 1.1 yamaguch I40E_VFGEN_RSTAT_VFR_STATE_MASK; 1510 1.1 yamaguch if (reg == IAVF_VFR_VFACTIVE || 1511 1.1 yamaguch reg == IAVF_VFR_COMPLETED) 1512 1.1 yamaguch return 0; 1513 1.1 yamaguch 1514 1.1 yamaguch delaymsec(10); 1515 1.1 yamaguch } 1516 1.1 yamaguch 1517 1.1 yamaguch return -1; 1518 1.1 yamaguch } 1519 1.1 yamaguch 1520 1.1 yamaguch static bool 1521 1.1 yamaguch iavf_is_etheranyaddr(const uint8_t *enaddr) 1522 1.1 yamaguch { 1523 1.1 yamaguch static const uint8_t etheranyaddr[ETHER_ADDR_LEN] = { 1524 1.1 yamaguch 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1525 1.1 yamaguch }; 1526 1.1 yamaguch 1527 1.1 yamaguch if (memcmp(enaddr, etheranyaddr, ETHER_ADDR_LEN) != 0) 1528 1.1 yamaguch return false; 1529 1.1 yamaguch 1530 1.1 yamaguch return true; 1531 1.1 yamaguch } 1532 1.1 yamaguch 1533 1.1 yamaguch static void 1534 1.1 yamaguch iavf_prepare_fakeaddr(struct iavf_softc *sc) 1535 1.1 yamaguch { 1536 1.1 yamaguch uint64_t rndval; 1537 1.1 yamaguch 1538 1.1 yamaguch if (!iavf_is_etheranyaddr(sc->sc_enaddr_fake)) 1539 1.1 yamaguch return; 1540 1.1 yamaguch 1541 1.1 yamaguch rndval = cprng_strong64(); 1542 1.1 yamaguch 1543 1.1 yamaguch memcpy(sc->sc_enaddr_fake, &rndval, sizeof(sc->sc_enaddr_fake)); 1544 1.1 yamaguch sc->sc_enaddr_fake[0] &= 0xFE; 1545 1.1 yamaguch sc->sc_enaddr_fake[0] |= 0x02; 1546 1.1 yamaguch } 1547 1.1 yamaguch 1548 1.1 yamaguch static int 1549 1.1 yamaguch iavf_replace_lla(struct ifnet *ifp, const uint8_t *prev, const uint8_t *next) 1550 1.1 yamaguch { 1551 1.1 yamaguch union { 1552 1.1 yamaguch struct sockaddr sa; 1553 1.1 yamaguch struct sockaddr_dl sdl; 1554 1.1 yamaguch struct sockaddr_storage ss; 1555 1.1 yamaguch } u; 1556 1.1 yamaguch struct psref psref_prev, psref_next; 1557 1.1 yamaguch struct ifaddr *ifa_prev, *ifa_next; 1558 1.1 yamaguch const struct sockaddr_dl *nsdl; 1559 1.1 yamaguch int s, error; 1560 1.1 yamaguch 1561 1.1 yamaguch KASSERT(IFNET_LOCKED(ifp)); 1562 1.1 yamaguch 1563 1.1 yamaguch error = 0; 1564 1.1 yamaguch ifa_prev = ifa_next = NULL; 1565 1.1 yamaguch 1566 1.1 yamaguch if (memcmp(prev, next, ETHER_ADDR_LEN) == 0) { 1567 1.1 yamaguch goto done; 1568 1.1 yamaguch } 1569 1.1 yamaguch 1570 1.1 yamaguch if (sockaddr_dl_init(&u.sdl, sizeof(u.ss), ifp->if_index, 1571 1.1 yamaguch ifp->if_type, ifp->if_xname, strlen(ifp->if_xname), 1572 1.1 yamaguch prev, ETHER_ADDR_LEN) == NULL) { 1573 1.1 yamaguch error = EINVAL; 1574 1.1 yamaguch goto done; 1575 1.1 yamaguch } 1576 1.1 yamaguch 1577 1.1 yamaguch s = pserialize_read_enter(); 1578 1.1 yamaguch IFADDR_READER_FOREACH(ifa_prev, ifp) { 1579 1.1 yamaguch if (sockaddr_cmp(&u.sa, ifa_prev->ifa_addr) == 0) { 1580 1.1 yamaguch ifa_acquire(ifa_prev, &psref_prev); 1581 1.1 yamaguch break; 1582 1.1 yamaguch } 1583 1.1 yamaguch } 1584 1.1 yamaguch pserialize_read_exit(s); 1585 1.1 yamaguch 1586 1.1 yamaguch if (sockaddr_dl_init(&u.sdl, sizeof(u.ss), ifp->if_index, 1587 1.1 yamaguch ifp->if_type, ifp->if_xname, strlen(ifp->if_xname), 1588 1.1 yamaguch next, ETHER_ADDR_LEN) == NULL) { 1589 1.1 yamaguch error = EINVAL; 1590 1.1 yamaguch goto done; 1591 1.1 yamaguch } 1592 1.1 yamaguch 1593 1.1 yamaguch s = pserialize_read_enter(); 1594 1.1 yamaguch IFADDR_READER_FOREACH(ifa_next, ifp) { 1595 1.1 yamaguch if (sockaddr_cmp(&u.sa, ifa_next->ifa_addr) == 0) { 1596 1.1 yamaguch ifa_acquire(ifa_next, &psref_next); 1597 1.1 yamaguch break; 1598 1.1 yamaguch } 1599 1.1 yamaguch } 1600 1.1 yamaguch pserialize_read_exit(s); 1601 1.1 yamaguch 1602 1.1 yamaguch if (ifa_next == NULL) { 1603 1.1 yamaguch nsdl = &u.sdl; 1604 1.1 yamaguch ifa_next = if_dl_create(ifp, &nsdl); 1605 1.1 yamaguch if (ifa_next == NULL) { 1606 1.1 yamaguch error = ENOMEM; 1607 1.1 yamaguch goto done; 1608 1.1 yamaguch } 1609 1.1 yamaguch 1610 1.1 yamaguch s = pserialize_read_enter(); 1611 1.1 yamaguch ifa_acquire(ifa_next, &psref_next); 1612 1.1 yamaguch pserialize_read_exit(s); 1613 1.1 yamaguch 1614 1.1 yamaguch sockaddr_copy(ifa_next->ifa_addr, 1615 1.1 yamaguch ifa_next->ifa_addr->sa_len, &u.sa); 1616 1.1 yamaguch ifa_insert(ifp, ifa_next); 1617 1.1 yamaguch } else { 1618 1.1 yamaguch nsdl = NULL; 1619 1.1 yamaguch } 1620 1.1 yamaguch 1621 1.1 yamaguch if (ifa_prev != NULL && ifa_prev == ifp->if_dl) { 1622 1.1 yamaguch if_activate_sadl(ifp, ifa_next, nsdl); 1623 1.1 yamaguch } 1624 1.1 yamaguch 1625 1.1 yamaguch ifa_release(ifa_next, &psref_next); 1626 1.1 yamaguch ifa_next = NULL; 1627 1.1 yamaguch 1628 1.1 yamaguch if (ifa_prev != NULL && ifa_prev != ifp->if_hwdl) { 1629 1.1 yamaguch ifaref(ifa_prev); 1630 1.1 yamaguch ifa_release(ifa_prev, &psref_prev); 1631 1.1 yamaguch ifa_remove(ifp, ifa_prev); 1632 1.1 yamaguch KASSERTMSG(ifa_prev->ifa_refcnt == 1, "ifa_refcnt=%d", 1633 1.1 yamaguch ifa_prev->ifa_refcnt); 1634 1.1 yamaguch ifafree(ifa_prev); 1635 1.1 yamaguch ifa_prev = NULL; 1636 1.1 yamaguch } 1637 1.1 yamaguch 1638 1.1 yamaguch if (ISSET(ifp->if_flags, IFF_RUNNING)) 1639 1.1 yamaguch error = ENETRESET; 1640 1.1 yamaguch 1641 1.1 yamaguch done: 1642 1.1 yamaguch if (ifa_prev != NULL) 1643 1.1 yamaguch ifa_release(ifa_prev, &psref_prev); 1644 1.1 yamaguch if (ifa_next != NULL) 1645 1.1 yamaguch ifa_release(ifa_next, &psref_next); 1646 1.1 yamaguch 1647 1.1 yamaguch return error; 1648 1.1 yamaguch } 1649 1.1 yamaguch static int 1650 1.1 yamaguch iavf_add_multi(struct iavf_softc *sc, uint8_t *addrlo, uint8_t *addrhi) 1651 1.1 yamaguch { 1652 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 1653 1.1 yamaguch int rv; 1654 1.1 yamaguch 1655 1.1 yamaguch if (ISSET(ifp->if_flags, IFF_ALLMULTI)) 1656 1.1 yamaguch return 0; 1657 1.1 yamaguch 1658 1.1 yamaguch if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0) { 1659 1.1 yamaguch iavf_del_all_multi(sc); 1660 1.1 yamaguch SET(ifp->if_flags, IFF_ALLMULTI); 1661 1.1 yamaguch return ENETRESET; 1662 1.1 yamaguch } 1663 1.1 yamaguch 1664 1.1 yamaguch rv = iavf_eth_addr(sc, addrlo, IAVF_VC_OP_ADD_ETH_ADDR); 1665 1.1 yamaguch 1666 1.1 yamaguch if (rv == ENOSPC) { 1667 1.1 yamaguch iavf_del_all_multi(sc); 1668 1.1 yamaguch SET(ifp->if_flags, IFF_ALLMULTI); 1669 1.1 yamaguch return ENETRESET; 1670 1.1 yamaguch } 1671 1.1 yamaguch 1672 1.1 yamaguch return rv; 1673 1.1 yamaguch } 1674 1.1 yamaguch 1675 1.1 yamaguch static int 1676 1.1 yamaguch iavf_del_multi(struct iavf_softc *sc, uint8_t *addrlo, uint8_t *addrhi) 1677 1.1 yamaguch { 1678 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 1679 1.1 yamaguch struct ethercom *ec = &sc->sc_ec; 1680 1.1 yamaguch struct ether_multi *enm, *enm_last; 1681 1.1 yamaguch struct ether_multistep step; 1682 1.1 yamaguch int error, rv = 0; 1683 1.1 yamaguch 1684 1.1 yamaguch if (!ISSET(ifp->if_flags, IFF_ALLMULTI)) { 1685 1.1 yamaguch if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0) 1686 1.1 yamaguch return 0; 1687 1.1 yamaguch 1688 1.1 yamaguch iavf_eth_addr(sc, addrlo, IAVF_VC_OP_DEL_ETH_ADDR); 1689 1.1 yamaguch return 0; 1690 1.1 yamaguch } 1691 1.1 yamaguch 1692 1.1 yamaguch ETHER_LOCK(ec); 1693 1.1 yamaguch for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL; 1694 1.1 yamaguch ETHER_NEXT_MULTI(step, enm)) { 1695 1.1 yamaguch if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 1696 1.1 yamaguch ETHER_ADDR_LEN) != 0) { 1697 1.1 yamaguch goto out; 1698 1.1 yamaguch } 1699 1.1 yamaguch } 1700 1.1 yamaguch 1701 1.1 yamaguch for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL; 1702 1.1 yamaguch ETHER_NEXT_MULTI(step, enm)) { 1703 1.1 yamaguch error = iavf_eth_addr(sc, enm->enm_addrlo, 1704 1.1 yamaguch IAVF_VC_OP_ADD_ETH_ADDR); 1705 1.1 yamaguch if (error != 0) 1706 1.1 yamaguch break; 1707 1.1 yamaguch } 1708 1.1 yamaguch 1709 1.1 yamaguch if (enm != NULL) { 1710 1.1 yamaguch enm_last = enm; 1711 1.1 yamaguch for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL; 1712 1.1 yamaguch ETHER_NEXT_MULTI(step, enm)) { 1713 1.1 yamaguch if (enm == enm_last) 1714 1.1 yamaguch break; 1715 1.1 yamaguch 1716 1.1 yamaguch iavf_eth_addr(sc, enm->enm_addrlo, 1717 1.1 yamaguch IAVF_VC_OP_DEL_ETH_ADDR); 1718 1.1 yamaguch } 1719 1.1 yamaguch } else { 1720 1.1 yamaguch CLR(ifp->if_flags, IFF_ALLMULTI); 1721 1.1 yamaguch rv = ENETRESET; 1722 1.1 yamaguch } 1723 1.1 yamaguch 1724 1.1 yamaguch out: 1725 1.1 yamaguch ETHER_UNLOCK(ec); 1726 1.1 yamaguch return rv; 1727 1.1 yamaguch } 1728 1.1 yamaguch 1729 1.1 yamaguch static void 1730 1.1 yamaguch iavf_del_all_multi(struct iavf_softc *sc) 1731 1.1 yamaguch { 1732 1.1 yamaguch struct ethercom *ec = &sc->sc_ec; 1733 1.1 yamaguch struct ether_multi *enm; 1734 1.1 yamaguch struct ether_multistep step; 1735 1.1 yamaguch 1736 1.1 yamaguch ETHER_LOCK(ec); 1737 1.1 yamaguch for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL; 1738 1.1 yamaguch ETHER_NEXT_MULTI(step, enm)) { 1739 1.1 yamaguch iavf_eth_addr(sc, enm->enm_addrlo, 1740 1.1 yamaguch IAVF_VC_OP_DEL_ETH_ADDR); 1741 1.1 yamaguch } 1742 1.1 yamaguch ETHER_UNLOCK(ec); 1743 1.1 yamaguch } 1744 1.1 yamaguch 1745 1.1 yamaguch static int 1746 1.1 yamaguch iavf_setup_interrupts(struct iavf_softc *sc) 1747 1.1 yamaguch { 1748 1.1 yamaguch struct pci_attach_args *pa; 1749 1.1 yamaguch kcpuset_t *affinity = NULL; 1750 1.1 yamaguch char intrbuf[PCI_INTRSTR_LEN], xnamebuf[32]; 1751 1.1 yamaguch char const *intrstr; 1752 1.1 yamaguch int counts[PCI_INTR_TYPE_SIZE]; 1753 1.1 yamaguch int error, affinity_to; 1754 1.1 yamaguch unsigned int vector, qid, num; 1755 1.1 yamaguch 1756 1.1 yamaguch /* queue pairs + misc interrupt */ 1757 1.1 yamaguch num = sc->sc_nqps_alloc + 1; 1758 1.1 yamaguch 1759 1.1 yamaguch num = MIN(num, iavf_calc_msix_count(sc)); 1760 1.1 yamaguch if (num <= 0) { 1761 1.1 yamaguch return -1; 1762 1.1 yamaguch } 1763 1.1 yamaguch 1764 1.1 yamaguch KASSERT(sc->sc_nqps_alloc > 0); 1765 1.1 yamaguch num = MIN(num, sc->sc_nqps_alloc + 1); 1766 1.1 yamaguch 1767 1.1 yamaguch pa = &sc->sc_pa; 1768 1.1 yamaguch memset(counts, 0, sizeof(counts)); 1769 1.1 yamaguch counts[PCI_INTR_TYPE_MSIX] = num; 1770 1.1 yamaguch 1771 1.1 yamaguch error = pci_intr_alloc(pa, &sc->sc_ihp, counts, PCI_INTR_TYPE_MSIX); 1772 1.1 yamaguch if (error != 0) { 1773 1.1 yamaguch IAVF_LOG(sc, LOG_WARNING, "couldn't allocate interrupts\n"); 1774 1.1 yamaguch return -1; 1775 1.1 yamaguch } 1776 1.1 yamaguch 1777 1.1 yamaguch KASSERT(pci_intr_type(pa->pa_pc, sc->sc_ihp[0]) == PCI_INTR_TYPE_MSIX); 1778 1.1 yamaguch 1779 1.1 yamaguch if (counts[PCI_INTR_TYPE_MSIX] < 1) { 1780 1.1 yamaguch IAVF_LOG(sc, LOG_ERR, "couldn't allocate interrupts\n"); 1781 1.1 yamaguch } else if (counts[PCI_INTR_TYPE_MSIX] != (int)num) { 1782 1.1 yamaguch IAVF_LOG(sc, LOG_DEBUG, 1783 1.17 andvar "request %u interrupts, but allocate %d interrupts\n", 1784 1.1 yamaguch num, counts[PCI_INTR_TYPE_MSIX]); 1785 1.1 yamaguch num = counts[PCI_INTR_TYPE_MSIX]; 1786 1.1 yamaguch } 1787 1.1 yamaguch 1788 1.12 jakllsch sc->sc_ihs = kmem_zalloc(sizeof(sc->sc_ihs[0]) * num, KM_NOSLEEP); 1789 1.1 yamaguch if (sc->sc_ihs == NULL) { 1790 1.1 yamaguch IAVF_LOG(sc, LOG_ERR, 1791 1.1 yamaguch "couldn't allocate memory for interrupts\n"); 1792 1.1 yamaguch goto fail; 1793 1.1 yamaguch } 1794 1.1 yamaguch 1795 1.1 yamaguch /* vector #0 is Misc interrupt */ 1796 1.1 yamaguch vector = 0; 1797 1.1 yamaguch pci_intr_setattr(pa->pa_pc, &sc->sc_ihp[vector], PCI_INTR_MPSAFE, true); 1798 1.1 yamaguch intrstr = pci_intr_string(pa->pa_pc, sc->sc_ihp[vector], 1799 1.1 yamaguch intrbuf, sizeof(intrbuf)); 1800 1.1 yamaguch snprintf(xnamebuf, sizeof(xnamebuf), "%s-Misc", 1801 1.1 yamaguch device_xname(sc->sc_dev)); 1802 1.1 yamaguch 1803 1.1 yamaguch sc->sc_ihs[vector] = pci_intr_establish_xname(pa->pa_pc, 1804 1.1 yamaguch sc->sc_ihp[vector], IPL_NET, iavf_intr, sc, xnamebuf); 1805 1.1 yamaguch if (sc->sc_ihs[vector] == NULL) { 1806 1.1 yamaguch IAVF_LOG(sc, LOG_WARNING, 1807 1.1 yamaguch "unable to establish interrupt at %s", intrstr); 1808 1.1 yamaguch goto fail; 1809 1.1 yamaguch } 1810 1.1 yamaguch 1811 1.1 yamaguch kcpuset_create(&affinity, false); 1812 1.8 yamaguch affinity_to = 0; 1813 1.1 yamaguch qid = 0; 1814 1.1 yamaguch for (vector = 1; vector < num; vector++) { 1815 1.1 yamaguch pci_intr_setattr(pa->pa_pc, &sc->sc_ihp[vector], 1816 1.1 yamaguch PCI_INTR_MPSAFE, true); 1817 1.1 yamaguch intrstr = pci_intr_string(pa->pa_pc, sc->sc_ihp[vector], 1818 1.1 yamaguch intrbuf, sizeof(intrbuf)); 1819 1.1 yamaguch snprintf(xnamebuf, sizeof(xnamebuf), "%s-TXRX%u", 1820 1.1 yamaguch device_xname(sc->sc_dev), qid); 1821 1.1 yamaguch 1822 1.1 yamaguch sc->sc_ihs[vector] = pci_intr_establish_xname(pa->pa_pc, 1823 1.1 yamaguch sc->sc_ihp[vector], IPL_NET, iavf_queue_intr, 1824 1.1 yamaguch (void *)&sc->sc_qps[qid], xnamebuf); 1825 1.1 yamaguch if (sc->sc_ihs[vector] == NULL) { 1826 1.1 yamaguch IAVF_LOG(sc, LOG_WARNING, 1827 1.1 yamaguch "unable to establish interrupt at %s\n", intrstr); 1828 1.1 yamaguch goto fail; 1829 1.1 yamaguch } 1830 1.1 yamaguch 1831 1.1 yamaguch kcpuset_zero(affinity); 1832 1.1 yamaguch kcpuset_set(affinity, affinity_to); 1833 1.1 yamaguch error = interrupt_distribute(sc->sc_ihs[vector], 1834 1.1 yamaguch affinity, NULL); 1835 1.1 yamaguch 1836 1.1 yamaguch if (error == 0) { 1837 1.1 yamaguch IAVF_LOG(sc, LOG_INFO, 1838 1.1 yamaguch "for TXRX%d interrupt at %s, affinity to %d\n", 1839 1.1 yamaguch qid, intrstr, affinity_to); 1840 1.1 yamaguch } else { 1841 1.1 yamaguch IAVF_LOG(sc, LOG_INFO, 1842 1.1 yamaguch "for TXRX%d interrupt at %s\n", 1843 1.1 yamaguch qid, intrstr); 1844 1.1 yamaguch } 1845 1.1 yamaguch 1846 1.1 yamaguch qid++; 1847 1.1 yamaguch affinity_to = (affinity_to + 1) % ncpu; 1848 1.1 yamaguch } 1849 1.1 yamaguch 1850 1.8 yamaguch vector = 0; 1851 1.8 yamaguch kcpuset_zero(affinity); 1852 1.8 yamaguch kcpuset_set(affinity, affinity_to); 1853 1.8 yamaguch intrstr = pci_intr_string(pa->pa_pc, sc->sc_ihp[vector], 1854 1.8 yamaguch intrbuf, sizeof(intrbuf)); 1855 1.8 yamaguch error = interrupt_distribute(sc->sc_ihs[vector], affinity, NULL); 1856 1.8 yamaguch if (error == 0) { 1857 1.8 yamaguch IAVF_LOG(sc, LOG_INFO, 1858 1.8 yamaguch "for Misc interrupt at %s, affinity to %d\n", 1859 1.8 yamaguch intrstr, affinity_to); 1860 1.8 yamaguch } else { 1861 1.8 yamaguch IAVF_LOG(sc, LOG_INFO, 1862 1.8 yamaguch "for MISC interrupt at %s\n", intrstr); 1863 1.8 yamaguch } 1864 1.8 yamaguch 1865 1.1 yamaguch kcpuset_destroy(affinity); 1866 1.1 yamaguch 1867 1.1 yamaguch sc->sc_nintrs = num; 1868 1.1 yamaguch return 0; 1869 1.1 yamaguch 1870 1.1 yamaguch fail: 1871 1.1 yamaguch if (affinity != NULL) 1872 1.1 yamaguch kcpuset_destroy(affinity); 1873 1.20 joe 1874 1.20 joe if (sc->sc_ihs != NULL) { 1875 1.20 joe for (vector = 0; vector < num; vector++) { 1876 1.20 joe if (sc->sc_ihs[vector] == NULL) 1877 1.20 joe continue; 1878 1.20 joe pci_intr_disestablish(pa->pa_pc, sc->sc_ihs[vector]); 1879 1.20 joe } 1880 1.20 joe kmem_free(sc->sc_ihs, sizeof(sc->sc_ihs[0]) * num); 1881 1.1 yamaguch } 1882 1.1 yamaguch pci_intr_release(pa->pa_pc, sc->sc_ihp, num); 1883 1.1 yamaguch 1884 1.1 yamaguch return -1; 1885 1.1 yamaguch } 1886 1.1 yamaguch 1887 1.1 yamaguch static void 1888 1.1 yamaguch iavf_teardown_interrupts(struct iavf_softc *sc) 1889 1.1 yamaguch { 1890 1.1 yamaguch struct pci_attach_args *pa; 1891 1.1 yamaguch unsigned int i; 1892 1.1 yamaguch 1893 1.1 yamaguch if (sc->sc_ihs == NULL) 1894 1.1 yamaguch return; 1895 1.1 yamaguch 1896 1.1 yamaguch pa = &sc->sc_pa; 1897 1.1 yamaguch 1898 1.1 yamaguch for (i = 0; i < sc->sc_nintrs; i++) { 1899 1.1 yamaguch pci_intr_disestablish(pa->pa_pc, sc->sc_ihs[i]); 1900 1.1 yamaguch } 1901 1.1 yamaguch 1902 1.1 yamaguch kmem_free(sc->sc_ihs, sizeof(sc->sc_ihs[0]) * sc->sc_nintrs); 1903 1.1 yamaguch sc->sc_ihs = NULL; 1904 1.1 yamaguch 1905 1.1 yamaguch pci_intr_release(pa->pa_pc, sc->sc_ihp, sc->sc_nintrs); 1906 1.1 yamaguch sc->sc_nintrs = 0; 1907 1.1 yamaguch } 1908 1.1 yamaguch 1909 1.1 yamaguch static int 1910 1.1 yamaguch iavf_setup_sysctls(struct iavf_softc *sc) 1911 1.1 yamaguch { 1912 1.1 yamaguch const char *devname; 1913 1.1 yamaguch struct sysctllog **log; 1914 1.1 yamaguch const struct sysctlnode *rnode, *rxnode, *txnode; 1915 1.1 yamaguch int error; 1916 1.1 yamaguch 1917 1.1 yamaguch log = &sc->sc_sysctllog; 1918 1.1 yamaguch devname = device_xname(sc->sc_dev); 1919 1.1 yamaguch 1920 1.1 yamaguch error = sysctl_createv(log, 0, NULL, &rnode, 1921 1.1 yamaguch 0, CTLTYPE_NODE, devname, 1922 1.1 yamaguch SYSCTL_DESCR("iavf information and settings"), 1923 1.1 yamaguch NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 1924 1.1 yamaguch if (error) 1925 1.1 yamaguch goto out; 1926 1.1 yamaguch 1927 1.1 yamaguch error = sysctl_createv(log, 0, &rnode, NULL, 1928 1.1 yamaguch CTLFLAG_READWRITE, CTLTYPE_BOOL, "txrx_workqueue", 1929 1.1 yamaguch SYSCTL_DESCR("Use workqueue for packet processing"), 1930 1.1 yamaguch NULL, 0, &sc->sc_txrx_workqueue, 0, CTL_CREATE, CTL_EOL); 1931 1.1 yamaguch if (error) 1932 1.1 yamaguch goto out; 1933 1.1 yamaguch 1934 1.1 yamaguch error = sysctl_createv(log, 0, &rnode, NULL, 1935 1.1 yamaguch CTLFLAG_READWRITE, CTLTYPE_INT, "debug_level", 1936 1.1 yamaguch SYSCTL_DESCR("Debug level"), 1937 1.1 yamaguch NULL, 0, &sc->sc_debuglevel, 0, CTL_CREATE, CTL_EOL); 1938 1.1 yamaguch if (error) 1939 1.1 yamaguch goto out; 1940 1.1 yamaguch 1941 1.1 yamaguch error = sysctl_createv(log, 0, &rnode, &rxnode, 1942 1.1 yamaguch 0, CTLTYPE_NODE, "rx", 1943 1.1 yamaguch SYSCTL_DESCR("iavf information and settings for Rx"), 1944 1.1 yamaguch NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 1945 1.1 yamaguch if (error) 1946 1.1 yamaguch goto out; 1947 1.1 yamaguch 1948 1.1 yamaguch error = sysctl_createv(log, 0, &rxnode, NULL, 1949 1.1 yamaguch CTLFLAG_READWRITE, CTLTYPE_INT, "itr", 1950 1.1 yamaguch SYSCTL_DESCR("Interrupt Throttling"), 1951 1.1 yamaguch iavf_sysctl_itr_handler, 0, 1952 1.1 yamaguch (void *)sc, 0, CTL_CREATE, CTL_EOL); 1953 1.1 yamaguch if (error) 1954 1.1 yamaguch goto out; 1955 1.1 yamaguch 1956 1.1 yamaguch error = sysctl_createv(log, 0, &rxnode, NULL, 1957 1.1 yamaguch CTLFLAG_READONLY, CTLTYPE_INT, "descriptor_num", 1958 1.1 yamaguch SYSCTL_DESCR("descriptor size"), 1959 1.1 yamaguch NULL, 0, &sc->sc_rx_ring_ndescs, 0, CTL_CREATE, CTL_EOL); 1960 1.1 yamaguch if (error) 1961 1.1 yamaguch goto out; 1962 1.1 yamaguch 1963 1.1 yamaguch error = sysctl_createv(log, 0, &rxnode, NULL, 1964 1.1 yamaguch CTLFLAG_READWRITE, CTLTYPE_INT, "intr_process_limit", 1965 1.1 yamaguch SYSCTL_DESCR("max number of Rx packets" 1966 1.1 yamaguch " to process for interrupt processing"), 1967 1.1 yamaguch NULL, 0, &sc->sc_rx_intr_process_limit, 0, CTL_CREATE, CTL_EOL); 1968 1.1 yamaguch if (error) 1969 1.1 yamaguch goto out; 1970 1.1 yamaguch 1971 1.1 yamaguch error = sysctl_createv(log, 0, &rxnode, NULL, 1972 1.1 yamaguch CTLFLAG_READWRITE, CTLTYPE_INT, "process_limit", 1973 1.1 yamaguch SYSCTL_DESCR("max number of Rx packets" 1974 1.1 yamaguch " to process for deferred processing"), 1975 1.1 yamaguch NULL, 0, &sc->sc_rx_process_limit, 0, CTL_CREATE, CTL_EOL); 1976 1.1 yamaguch if (error) 1977 1.1 yamaguch goto out; 1978 1.1 yamaguch 1979 1.1 yamaguch error = sysctl_createv(log, 0, &rnode, &txnode, 1980 1.1 yamaguch 0, CTLTYPE_NODE, "tx", 1981 1.1 yamaguch SYSCTL_DESCR("iavf information and settings for Tx"), 1982 1.1 yamaguch NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 1983 1.1 yamaguch if (error) 1984 1.1 yamaguch goto out; 1985 1.1 yamaguch 1986 1.1 yamaguch error = sysctl_createv(log, 0, &txnode, NULL, 1987 1.1 yamaguch CTLFLAG_READWRITE, CTLTYPE_INT, "itr", 1988 1.1 yamaguch SYSCTL_DESCR("Interrupt Throttling"), 1989 1.1 yamaguch iavf_sysctl_itr_handler, 0, 1990 1.1 yamaguch (void *)sc, 0, CTL_CREATE, CTL_EOL); 1991 1.1 yamaguch if (error) 1992 1.1 yamaguch goto out; 1993 1.1 yamaguch 1994 1.1 yamaguch error = sysctl_createv(log, 0, &txnode, NULL, 1995 1.1 yamaguch CTLFLAG_READONLY, CTLTYPE_INT, "descriptor_num", 1996 1.1 yamaguch SYSCTL_DESCR("the number of Tx descriptors"), 1997 1.1 yamaguch NULL, 0, &sc->sc_tx_ring_ndescs, 0, CTL_CREATE, CTL_EOL); 1998 1.1 yamaguch if (error) 1999 1.1 yamaguch goto out; 2000 1.1 yamaguch 2001 1.1 yamaguch error = sysctl_createv(log, 0, &txnode, NULL, 2002 1.1 yamaguch CTLFLAG_READWRITE, CTLTYPE_INT, "intr_process_limit", 2003 1.1 yamaguch SYSCTL_DESCR("max number of Tx packets" 2004 1.1 yamaguch " to process for interrupt processing"), 2005 1.1 yamaguch NULL, 0, &sc->sc_tx_intr_process_limit, 0, CTL_CREATE, CTL_EOL); 2006 1.1 yamaguch if (error) 2007 1.1 yamaguch goto out; 2008 1.1 yamaguch 2009 1.1 yamaguch error = sysctl_createv(log, 0, &txnode, NULL, 2010 1.1 yamaguch CTLFLAG_READWRITE, CTLTYPE_INT, "process_limit", 2011 1.1 yamaguch SYSCTL_DESCR("max number of Tx packets" 2012 1.1 yamaguch " to process for deferred processing"), 2013 1.1 yamaguch NULL, 0, &sc->sc_tx_process_limit, 0, CTL_CREATE, CTL_EOL); 2014 1.1 yamaguch if (error) 2015 1.1 yamaguch goto out; 2016 1.1 yamaguch out: 2017 1.1 yamaguch return error; 2018 1.1 yamaguch } 2019 1.1 yamaguch 2020 1.1 yamaguch static void 2021 1.1 yamaguch iavf_teardown_sysctls(struct iavf_softc *sc) 2022 1.1 yamaguch { 2023 1.1 yamaguch 2024 1.1 yamaguch sysctl_teardown(&sc->sc_sysctllog); 2025 1.1 yamaguch } 2026 1.1 yamaguch 2027 1.1 yamaguch static int 2028 1.1 yamaguch iavf_setup_stats(struct iavf_softc *sc) 2029 1.1 yamaguch { 2030 1.1 yamaguch struct iavf_stat_counters *isc; 2031 1.1 yamaguch const char *dn; 2032 1.1 yamaguch 2033 1.1 yamaguch dn = device_xname(sc->sc_dev); 2034 1.1 yamaguch isc = &sc->sc_stat_counters; 2035 1.1 yamaguch 2036 1.1 yamaguch iavf_evcnt_attach(&isc->isc_rx_bytes, dn, "Rx bytes"); 2037 1.1 yamaguch iavf_evcnt_attach(&isc->isc_rx_unicast, dn, "Rx unicast"); 2038 1.1 yamaguch iavf_evcnt_attach(&isc->isc_rx_multicast, dn, "Rx multicast"); 2039 1.1 yamaguch iavf_evcnt_attach(&isc->isc_rx_broadcast, dn, "Rx broadcast"); 2040 1.1 yamaguch iavf_evcnt_attach(&isc->isc_rx_discards, dn, "Rx discards"); 2041 1.1 yamaguch iavf_evcnt_attach(&isc->isc_rx_unknown_protocol, 2042 1.1 yamaguch dn, "Rx unknown protocol"); 2043 1.1 yamaguch 2044 1.1 yamaguch iavf_evcnt_attach(&isc->isc_tx_bytes, dn, "Tx bytes"); 2045 1.1 yamaguch iavf_evcnt_attach(&isc->isc_tx_unicast, dn, "Tx unicast"); 2046 1.1 yamaguch iavf_evcnt_attach(&isc->isc_tx_multicast, dn, "Tx multicast"); 2047 1.1 yamaguch iavf_evcnt_attach(&isc->isc_tx_broadcast, dn, "Tx broadcast"); 2048 1.1 yamaguch iavf_evcnt_attach(&isc->isc_tx_discards, dn, "Tx discards"); 2049 1.1 yamaguch iavf_evcnt_attach(&isc->isc_tx_errors, dn, "Tx errors"); 2050 1.1 yamaguch 2051 1.1 yamaguch return 0; 2052 1.1 yamaguch } 2053 1.1 yamaguch 2054 1.1 yamaguch static void 2055 1.1 yamaguch iavf_teardown_stats(struct iavf_softc *sc) 2056 1.1 yamaguch { 2057 1.1 yamaguch struct iavf_stat_counters *isc; 2058 1.1 yamaguch 2059 1.1 yamaguch isc = &sc->sc_stat_counters; 2060 1.1 yamaguch 2061 1.1 yamaguch evcnt_detach(&isc->isc_rx_bytes); 2062 1.1 yamaguch evcnt_detach(&isc->isc_rx_unicast); 2063 1.1 yamaguch evcnt_detach(&isc->isc_rx_multicast); 2064 1.1 yamaguch evcnt_detach(&isc->isc_rx_broadcast); 2065 1.1 yamaguch evcnt_detach(&isc->isc_rx_discards); 2066 1.1 yamaguch evcnt_detach(&isc->isc_rx_unknown_protocol); 2067 1.1 yamaguch 2068 1.1 yamaguch evcnt_detach(&isc->isc_tx_bytes); 2069 1.1 yamaguch evcnt_detach(&isc->isc_tx_unicast); 2070 1.1 yamaguch evcnt_detach(&isc->isc_tx_multicast); 2071 1.1 yamaguch evcnt_detach(&isc->isc_tx_broadcast); 2072 1.1 yamaguch evcnt_detach(&isc->isc_tx_discards); 2073 1.1 yamaguch evcnt_detach(&isc->isc_tx_errors); 2074 1.1 yamaguch 2075 1.1 yamaguch } 2076 1.1 yamaguch 2077 1.1 yamaguch static int 2078 1.1 yamaguch iavf_init_admin_queue(struct iavf_softc *sc) 2079 1.1 yamaguch { 2080 1.1 yamaguch uint32_t reg; 2081 1.1 yamaguch 2082 1.1 yamaguch sc->sc_atq_cons = 0; 2083 1.1 yamaguch sc->sc_atq_prod = 0; 2084 1.1 yamaguch 2085 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 2086 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), 2087 1.1 yamaguch BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 2088 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq), 2089 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_arq), 2090 1.1 yamaguch BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 2091 1.1 yamaguch 2092 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->atq_head, 0); 2093 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->arq_head, 0); 2094 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->atq_tail, 0); 2095 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->arq_tail, 0); 2096 1.1 yamaguch 2097 1.1 yamaguch iavf_barrier(sc, 0, sc->sc_mems, BUS_SPACE_BARRIER_WRITE); 2098 1.1 yamaguch 2099 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->atq_bal, 2100 1.1 yamaguch ixl_dmamem_lo(&sc->sc_atq)); 2101 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->atq_bah, 2102 1.1 yamaguch ixl_dmamem_hi(&sc->sc_atq)); 2103 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->atq_len, 2104 1.1 yamaguch sc->sc_aq_regs->atq_len_enable | IAVF_AQ_NUM); 2105 1.1 yamaguch 2106 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->arq_bal, 2107 1.1 yamaguch ixl_dmamem_lo(&sc->sc_arq)); 2108 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->arq_bah, 2109 1.1 yamaguch ixl_dmamem_hi(&sc->sc_arq)); 2110 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->arq_len, 2111 1.1 yamaguch sc->sc_aq_regs->arq_len_enable | IAVF_AQ_NUM); 2112 1.1 yamaguch 2113 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->arq_tail, sc->sc_arq_prod); 2114 1.1 yamaguch 2115 1.1 yamaguch reg = iavf_rd(sc, sc->sc_aq_regs->atq_bal); 2116 1.1 yamaguch if (reg != ixl_dmamem_lo(&sc->sc_atq)) 2117 1.1 yamaguch goto fail; 2118 1.1 yamaguch 2119 1.1 yamaguch reg = iavf_rd(sc, sc->sc_aq_regs->arq_bal); 2120 1.1 yamaguch if (reg != ixl_dmamem_lo(&sc->sc_arq)) 2121 1.1 yamaguch goto fail; 2122 1.1 yamaguch 2123 1.1 yamaguch sc->sc_dead = false; 2124 1.1 yamaguch return 0; 2125 1.1 yamaguch 2126 1.1 yamaguch fail: 2127 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->atq_len, 0); 2128 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->arq_len, 0); 2129 1.1 yamaguch return -1; 2130 1.1 yamaguch } 2131 1.1 yamaguch 2132 1.1 yamaguch static void 2133 1.1 yamaguch iavf_cleanup_admin_queue(struct iavf_softc *sc) 2134 1.1 yamaguch { 2135 1.1 yamaguch struct ixl_aq_buf *aqb; 2136 1.1 yamaguch 2137 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->atq_head, 0); 2138 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->arq_head, 0); 2139 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->atq_tail, 0); 2140 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->arq_tail, 0); 2141 1.1 yamaguch 2142 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->atq_bal, 0); 2143 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->atq_bah, 0); 2144 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->atq_len, 0); 2145 1.1 yamaguch 2146 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->arq_bal, 0); 2147 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->arq_bah, 0); 2148 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->arq_len, 0); 2149 1.1 yamaguch iavf_flush(sc); 2150 1.1 yamaguch 2151 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq), 2152 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_arq), 2153 1.1 yamaguch BUS_DMASYNC_POSTREAD); 2154 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 2155 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), 2156 1.1 yamaguch BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 2157 1.1 yamaguch 2158 1.1 yamaguch sc->sc_atq_cons = 0; 2159 1.1 yamaguch sc->sc_atq_prod = 0; 2160 1.1 yamaguch sc->sc_arq_cons = 0; 2161 1.1 yamaguch sc->sc_arq_prod = 0; 2162 1.1 yamaguch 2163 1.1 yamaguch memset(IXL_DMA_KVA(&sc->sc_arq), 0, IXL_DMA_LEN(&sc->sc_arq)); 2164 1.1 yamaguch memset(IXL_DMA_KVA(&sc->sc_atq), 0, IXL_DMA_LEN(&sc->sc_atq)); 2165 1.1 yamaguch 2166 1.1 yamaguch while ((aqb = iavf_aqb_get_locked(&sc->sc_arq_live)) != NULL) { 2167 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0, aqb->aqb_size, 2168 1.1 yamaguch BUS_DMASYNC_POSTREAD); 2169 1.1 yamaguch iavf_aqb_put_locked(&sc->sc_arq_idle, aqb); 2170 1.1 yamaguch } 2171 1.1 yamaguch 2172 1.1 yamaguch while ((aqb = iavf_aqb_get_locked(&sc->sc_atq_live)) != NULL) { 2173 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0, aqb->aqb_size, 2174 1.1 yamaguch BUS_DMASYNC_POSTREAD); 2175 1.1 yamaguch iavf_aqb_put_locked(&sc->sc_atq_idle, aqb); 2176 1.1 yamaguch } 2177 1.1 yamaguch } 2178 1.1 yamaguch 2179 1.1 yamaguch static unsigned int 2180 1.1 yamaguch iavf_calc_msix_count(struct iavf_softc *sc) 2181 1.1 yamaguch { 2182 1.1 yamaguch struct pci_attach_args *pa; 2183 1.1 yamaguch int count; 2184 1.1 yamaguch 2185 1.1 yamaguch pa = &sc->sc_pa; 2186 1.1 yamaguch count = pci_msix_count(pa->pa_pc, pa->pa_tag); 2187 1.1 yamaguch if (count < 0) { 2188 1.1 yamaguch IAVF_LOG(sc, LOG_DEBUG,"MSIX config error\n"); 2189 1.1 yamaguch count = 0; 2190 1.1 yamaguch } 2191 1.1 yamaguch 2192 1.1 yamaguch return MIN(sc->sc_max_vectors, (unsigned int)count); 2193 1.1 yamaguch } 2194 1.1 yamaguch 2195 1.1 yamaguch static unsigned int 2196 1.1 yamaguch iavf_calc_queue_pair_size(struct iavf_softc *sc) 2197 1.1 yamaguch { 2198 1.1 yamaguch unsigned int nqp, nvec; 2199 1.1 yamaguch 2200 1.1 yamaguch nvec = iavf_calc_msix_count(sc); 2201 1.1 yamaguch if (sc->sc_max_vectors > 1) { 2202 1.1 yamaguch /* decrease the number of misc interrupt */ 2203 1.1 yamaguch nvec -= 1; 2204 1.1 yamaguch } 2205 1.1 yamaguch 2206 1.1 yamaguch nqp = ncpu; 2207 1.1 yamaguch nqp = MIN(nqp, sc->sc_nqps_vsi); 2208 1.1 yamaguch nqp = MIN(nqp, nvec); 2209 1.1 yamaguch nqp = MIN(nqp, (unsigned int)iavf_params.max_qps); 2210 1.1 yamaguch 2211 1.1 yamaguch return nqp; 2212 1.1 yamaguch } 2213 1.1 yamaguch 2214 1.1 yamaguch static struct iavf_tx_ring * 2215 1.1 yamaguch iavf_txr_alloc(struct iavf_softc *sc, unsigned int qid) 2216 1.1 yamaguch { 2217 1.1 yamaguch struct iavf_tx_ring *txr; 2218 1.1 yamaguch struct iavf_tx_map *maps; 2219 1.1 yamaguch unsigned int i; 2220 1.1 yamaguch int error; 2221 1.1 yamaguch 2222 1.1 yamaguch txr = kmem_zalloc(sizeof(*txr), KM_NOSLEEP); 2223 1.1 yamaguch if (txr == NULL) 2224 1.1 yamaguch return NULL; 2225 1.1 yamaguch 2226 1.1 yamaguch maps = kmem_zalloc(sizeof(maps[0]) * sc->sc_tx_ring_ndescs, 2227 1.1 yamaguch KM_NOSLEEP); 2228 1.1 yamaguch if (maps == NULL) 2229 1.1 yamaguch goto free_txr; 2230 1.1 yamaguch 2231 1.1 yamaguch if (iavf_dmamem_alloc(sc->sc_dmat, &txr->txr_mem, 2232 1.1 yamaguch sizeof(struct ixl_tx_desc) * sc->sc_tx_ring_ndescs, 2233 1.1 yamaguch IAVF_TX_QUEUE_ALIGN) != 0) { 2234 1.1 yamaguch goto free_maps; 2235 1.1 yamaguch } 2236 1.1 yamaguch 2237 1.1 yamaguch for (i = 0; i < sc->sc_tx_ring_ndescs; i++) { 2238 1.1 yamaguch error = bus_dmamap_create(sc->sc_dmat, IAVF_TX_PKT_MAXSIZE, 2239 1.1 yamaguch IAVF_TX_PKT_DESCS, IAVF_TX_PKT_MAXSIZE, 0, 2240 1.1 yamaguch BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &maps[i].txm_map); 2241 1.1 yamaguch if (error) 2242 1.1 yamaguch goto destroy_maps; 2243 1.1 yamaguch } 2244 1.1 yamaguch 2245 1.1 yamaguch txr->txr_intrq = pcq_create(sc->sc_tx_ring_ndescs, KM_NOSLEEP); 2246 1.1 yamaguch if (txr->txr_intrq == NULL) 2247 1.1 yamaguch goto destroy_maps; 2248 1.1 yamaguch 2249 1.1 yamaguch txr->txr_si = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE, 2250 1.1 yamaguch iavf_deferred_transmit, txr); 2251 1.1 yamaguch if (txr->txr_si == NULL) 2252 1.1 yamaguch goto destroy_pcq; 2253 1.1 yamaguch 2254 1.1 yamaguch snprintf(txr->txr_name, sizeof(txr->txr_name), "%s-tx%d", 2255 1.1 yamaguch device_xname(sc->sc_dev), qid); 2256 1.1 yamaguch 2257 1.1 yamaguch iavf_evcnt_attach(&txr->txr_defragged, 2258 1.1 yamaguch txr->txr_name, "m_defrag successed"); 2259 1.1 yamaguch iavf_evcnt_attach(&txr->txr_defrag_failed, 2260 1.1 yamaguch txr->txr_name, "m_defrag failed"); 2261 1.1 yamaguch iavf_evcnt_attach(&txr->txr_pcqdrop, 2262 1.1 yamaguch txr->txr_name, "Dropped in pcq"); 2263 1.1 yamaguch iavf_evcnt_attach(&txr->txr_transmitdef, 2264 1.1 yamaguch txr->txr_name, "Deferred transmit"); 2265 1.1 yamaguch iavf_evcnt_attach(&txr->txr_watchdogto, 2266 1.1 yamaguch txr->txr_name, "Watchdog timedout on queue"); 2267 1.1 yamaguch iavf_evcnt_attach(&txr->txr_defer, 2268 1.1 yamaguch txr->txr_name, "Handled queue in softint/workqueue"); 2269 1.1 yamaguch 2270 1.1 yamaguch evcnt_attach_dynamic(&txr->txr_intr, EVCNT_TYPE_INTR, NULL, 2271 1.1 yamaguch txr->txr_name, "Interrupt on queue"); 2272 1.1 yamaguch 2273 1.1 yamaguch txr->txr_qid = qid; 2274 1.1 yamaguch txr->txr_sc = sc; 2275 1.1 yamaguch txr->txr_maps = maps; 2276 1.1 yamaguch txr->txr_prod = txr->txr_cons = 0; 2277 1.1 yamaguch txr->txr_tail = I40E_QTX_TAIL1(qid); 2278 1.1 yamaguch mutex_init(&txr->txr_lock, MUTEX_DEFAULT, IPL_NET); 2279 1.1 yamaguch 2280 1.1 yamaguch return txr; 2281 1.1 yamaguch destroy_pcq: 2282 1.1 yamaguch pcq_destroy(txr->txr_intrq); 2283 1.1 yamaguch destroy_maps: 2284 1.1 yamaguch for (i = 0; i < sc->sc_tx_ring_ndescs; i++) { 2285 1.1 yamaguch if (maps[i].txm_map == NULL) 2286 1.1 yamaguch continue; 2287 1.1 yamaguch bus_dmamap_destroy(sc->sc_dmat, maps[i].txm_map); 2288 1.1 yamaguch } 2289 1.1 yamaguch 2290 1.1 yamaguch iavf_dmamem_free(sc->sc_dmat, &txr->txr_mem); 2291 1.1 yamaguch free_maps: 2292 1.1 yamaguch kmem_free(maps, sizeof(maps[0]) * sc->sc_tx_ring_ndescs); 2293 1.1 yamaguch free_txr: 2294 1.1 yamaguch kmem_free(txr, sizeof(*txr)); 2295 1.1 yamaguch return NULL; 2296 1.1 yamaguch } 2297 1.1 yamaguch 2298 1.1 yamaguch static void 2299 1.1 yamaguch iavf_txr_free(struct iavf_softc *sc, struct iavf_tx_ring *txr) 2300 1.1 yamaguch { 2301 1.1 yamaguch struct iavf_tx_map *maps; 2302 1.1 yamaguch unsigned int i; 2303 1.1 yamaguch 2304 1.1 yamaguch maps = txr->txr_maps; 2305 1.1 yamaguch if (maps != NULL) { 2306 1.1 yamaguch for (i = 0; i < sc->sc_tx_ring_ndescs; i++) { 2307 1.1 yamaguch if (maps[i].txm_map == NULL) 2308 1.1 yamaguch continue; 2309 1.1 yamaguch bus_dmamap_destroy(sc->sc_dmat, maps[i].txm_map); 2310 1.1 yamaguch } 2311 1.1 yamaguch kmem_free(txr->txr_maps, 2312 1.1 yamaguch sizeof(maps[0]) * sc->sc_tx_ring_ndescs); 2313 1.1 yamaguch txr->txr_maps = NULL; 2314 1.1 yamaguch } 2315 1.1 yamaguch 2316 1.1 yamaguch evcnt_detach(&txr->txr_defragged); 2317 1.1 yamaguch evcnt_detach(&txr->txr_defrag_failed); 2318 1.1 yamaguch evcnt_detach(&txr->txr_pcqdrop); 2319 1.1 yamaguch evcnt_detach(&txr->txr_transmitdef); 2320 1.1 yamaguch evcnt_detach(&txr->txr_watchdogto); 2321 1.1 yamaguch evcnt_detach(&txr->txr_defer); 2322 1.1 yamaguch evcnt_detach(&txr->txr_intr); 2323 1.1 yamaguch 2324 1.1 yamaguch iavf_dmamem_free(sc->sc_dmat, &txr->txr_mem); 2325 1.1 yamaguch softint_disestablish(txr->txr_si); 2326 1.1 yamaguch pcq_destroy(txr->txr_intrq); 2327 1.1 yamaguch mutex_destroy(&txr->txr_lock); 2328 1.1 yamaguch kmem_free(txr, sizeof(*txr)); 2329 1.1 yamaguch } 2330 1.1 yamaguch 2331 1.1 yamaguch static struct iavf_rx_ring * 2332 1.1 yamaguch iavf_rxr_alloc(struct iavf_softc *sc, unsigned int qid) 2333 1.1 yamaguch { 2334 1.1 yamaguch struct iavf_rx_ring *rxr; 2335 1.1 yamaguch struct iavf_rx_map *maps; 2336 1.1 yamaguch unsigned int i; 2337 1.1 yamaguch int error; 2338 1.1 yamaguch 2339 1.1 yamaguch rxr = kmem_zalloc(sizeof(*rxr), KM_NOSLEEP); 2340 1.1 yamaguch if (rxr == NULL) 2341 1.1 yamaguch return NULL; 2342 1.1 yamaguch 2343 1.1 yamaguch maps = kmem_zalloc(sizeof(maps[0]) * sc->sc_rx_ring_ndescs, 2344 1.1 yamaguch KM_NOSLEEP); 2345 1.1 yamaguch if (maps == NULL) 2346 1.1 yamaguch goto free_rxr; 2347 1.1 yamaguch 2348 1.1 yamaguch if (iavf_dmamem_alloc(sc->sc_dmat, &rxr->rxr_mem, 2349 1.1 yamaguch sizeof(struct ixl_rx_rd_desc_32) * sc->sc_rx_ring_ndescs, 2350 1.1 yamaguch IAVF_RX_QUEUE_ALIGN) != 0) 2351 1.1 yamaguch goto free_maps; 2352 1.1 yamaguch 2353 1.1 yamaguch for (i = 0; i < sc->sc_rx_ring_ndescs; i++) { 2354 1.1 yamaguch error = bus_dmamap_create(sc->sc_dmat, IAVF_MCLBYTES, 2355 1.1 yamaguch 1, IAVF_MCLBYTES, 0, 2356 1.1 yamaguch BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &maps[i].rxm_map); 2357 1.1 yamaguch if (error) 2358 1.1 yamaguch goto destroy_maps; 2359 1.1 yamaguch } 2360 1.1 yamaguch 2361 1.1 yamaguch snprintf(rxr->rxr_name, sizeof(rxr->rxr_name), "%s-rx%d", 2362 1.1 yamaguch device_xname(sc->sc_dev), qid); 2363 1.1 yamaguch 2364 1.1 yamaguch iavf_evcnt_attach(&rxr->rxr_mgethdr_failed, 2365 1.1 yamaguch rxr->rxr_name, "MGETHDR failed"); 2366 1.1 yamaguch iavf_evcnt_attach(&rxr->rxr_mgetcl_failed, 2367 1.1 yamaguch rxr->rxr_name, "MCLGET failed"); 2368 1.1 yamaguch iavf_evcnt_attach(&rxr->rxr_mbuf_load_failed, 2369 1.1 yamaguch rxr->rxr_name, "bus_dmamap_load_mbuf failed"); 2370 1.1 yamaguch iavf_evcnt_attach(&rxr->rxr_defer, 2371 1.1 yamaguch rxr->rxr_name, "Handled queue in softint/workqueue"); 2372 1.1 yamaguch 2373 1.1 yamaguch evcnt_attach_dynamic(&rxr->rxr_intr, EVCNT_TYPE_INTR, NULL, 2374 1.1 yamaguch rxr->rxr_name, "Interrupt on queue"); 2375 1.1 yamaguch 2376 1.1 yamaguch rxr->rxr_qid = qid; 2377 1.1 yamaguch rxr->rxr_sc = sc; 2378 1.1 yamaguch rxr->rxr_cons = rxr->rxr_prod = 0; 2379 1.1 yamaguch rxr->rxr_m_head = NULL; 2380 1.1 yamaguch rxr->rxr_m_tail = &rxr->rxr_m_head; 2381 1.1 yamaguch rxr->rxr_maps = maps; 2382 1.1 yamaguch rxr->rxr_tail = I40E_QRX_TAIL1(qid); 2383 1.1 yamaguch mutex_init(&rxr->rxr_lock, MUTEX_DEFAULT, IPL_NET); 2384 1.1 yamaguch 2385 1.1 yamaguch return rxr; 2386 1.1 yamaguch 2387 1.1 yamaguch destroy_maps: 2388 1.1 yamaguch for (i = 0; i < sc->sc_rx_ring_ndescs; i++) { 2389 1.1 yamaguch if (maps[i].rxm_map == NULL) 2390 1.1 yamaguch continue; 2391 1.1 yamaguch bus_dmamap_destroy(sc->sc_dmat, maps[i].rxm_map); 2392 1.1 yamaguch } 2393 1.1 yamaguch iavf_dmamem_free(sc->sc_dmat, &rxr->rxr_mem); 2394 1.1 yamaguch free_maps: 2395 1.1 yamaguch kmem_free(maps, sizeof(maps[0]) * sc->sc_rx_ring_ndescs); 2396 1.1 yamaguch free_rxr: 2397 1.1 yamaguch kmem_free(rxr, sizeof(*rxr)); 2398 1.1 yamaguch 2399 1.1 yamaguch return NULL; 2400 1.1 yamaguch } 2401 1.1 yamaguch 2402 1.1 yamaguch static void 2403 1.1 yamaguch iavf_rxr_free(struct iavf_softc *sc, struct iavf_rx_ring *rxr) 2404 1.1 yamaguch { 2405 1.1 yamaguch struct iavf_rx_map *maps; 2406 1.1 yamaguch unsigned int i; 2407 1.1 yamaguch 2408 1.1 yamaguch maps = rxr->rxr_maps; 2409 1.1 yamaguch if (maps != NULL) { 2410 1.1 yamaguch for (i = 0; i < sc->sc_rx_ring_ndescs; i++) { 2411 1.1 yamaguch if (maps[i].rxm_map == NULL) 2412 1.1 yamaguch continue; 2413 1.1 yamaguch bus_dmamap_destroy(sc->sc_dmat, maps[i].rxm_map); 2414 1.1 yamaguch } 2415 1.1 yamaguch kmem_free(maps, sizeof(maps[0]) * sc->sc_rx_ring_ndescs); 2416 1.1 yamaguch rxr->rxr_maps = NULL; 2417 1.1 yamaguch } 2418 1.1 yamaguch 2419 1.1 yamaguch evcnt_detach(&rxr->rxr_mgethdr_failed); 2420 1.1 yamaguch evcnt_detach(&rxr->rxr_mgetcl_failed); 2421 1.1 yamaguch evcnt_detach(&rxr->rxr_mbuf_load_failed); 2422 1.1 yamaguch evcnt_detach(&rxr->rxr_defer); 2423 1.1 yamaguch evcnt_detach(&rxr->rxr_intr); 2424 1.1 yamaguch 2425 1.1 yamaguch iavf_dmamem_free(sc->sc_dmat, &rxr->rxr_mem); 2426 1.1 yamaguch mutex_destroy(&rxr->rxr_lock); 2427 1.1 yamaguch kmem_free(rxr, sizeof(*rxr)); 2428 1.1 yamaguch } 2429 1.1 yamaguch 2430 1.1 yamaguch static int 2431 1.1 yamaguch iavf_queue_pairs_alloc(struct iavf_softc *sc) 2432 1.1 yamaguch { 2433 1.1 yamaguch struct iavf_queue_pair *qp; 2434 1.1 yamaguch unsigned int i, num; 2435 1.1 yamaguch 2436 1.1 yamaguch num = iavf_calc_queue_pair_size(sc); 2437 1.1 yamaguch if (num <= 0) { 2438 1.1 yamaguch return -1; 2439 1.1 yamaguch } 2440 1.1 yamaguch 2441 1.1 yamaguch sc->sc_qps = kmem_zalloc(sizeof(sc->sc_qps[0]) * num, KM_NOSLEEP); 2442 1.1 yamaguch if (sc->sc_qps == NULL) { 2443 1.1 yamaguch return -1; 2444 1.1 yamaguch } 2445 1.1 yamaguch 2446 1.1 yamaguch for (i = 0; i < num; i++) { 2447 1.1 yamaguch qp = &sc->sc_qps[i]; 2448 1.1 yamaguch 2449 1.1 yamaguch qp->qp_rxr = iavf_rxr_alloc(sc, i); 2450 1.1 yamaguch qp->qp_txr = iavf_txr_alloc(sc, i); 2451 1.1 yamaguch 2452 1.1 yamaguch if (qp->qp_rxr == NULL || qp->qp_txr == NULL) 2453 1.1 yamaguch goto free; 2454 1.1 yamaguch 2455 1.1 yamaguch qp->qp_si = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE, 2456 1.1 yamaguch iavf_handle_queue, qp); 2457 1.1 yamaguch if (qp->qp_si == NULL) 2458 1.1 yamaguch goto free; 2459 1.1 yamaguch } 2460 1.1 yamaguch 2461 1.1 yamaguch sc->sc_nqps_alloc = num; 2462 1.1 yamaguch return 0; 2463 1.1 yamaguch free: 2464 1.1 yamaguch for (i = 0; i < num; i++) { 2465 1.1 yamaguch qp = &sc->sc_qps[i]; 2466 1.1 yamaguch 2467 1.1 yamaguch if (qp->qp_si != NULL) 2468 1.1 yamaguch softint_disestablish(qp->qp_si); 2469 1.1 yamaguch if (qp->qp_rxr != NULL) 2470 1.1 yamaguch iavf_rxr_free(sc, qp->qp_rxr); 2471 1.1 yamaguch if (qp->qp_txr != NULL) 2472 1.1 yamaguch iavf_txr_free(sc, qp->qp_txr); 2473 1.1 yamaguch } 2474 1.1 yamaguch 2475 1.1 yamaguch kmem_free(sc->sc_qps, sizeof(sc->sc_qps[0]) * num); 2476 1.1 yamaguch sc->sc_qps = NULL; 2477 1.1 yamaguch 2478 1.1 yamaguch return -1; 2479 1.1 yamaguch } 2480 1.1 yamaguch 2481 1.1 yamaguch static void 2482 1.1 yamaguch iavf_queue_pairs_free(struct iavf_softc *sc) 2483 1.1 yamaguch { 2484 1.1 yamaguch struct iavf_queue_pair *qp; 2485 1.1 yamaguch unsigned int i; 2486 1.1 yamaguch size_t sz; 2487 1.1 yamaguch 2488 1.1 yamaguch if (sc->sc_qps == NULL) 2489 1.1 yamaguch return; 2490 1.1 yamaguch 2491 1.1 yamaguch for (i = 0; i < sc->sc_nqps_alloc; i++) { 2492 1.1 yamaguch qp = &sc->sc_qps[i]; 2493 1.1 yamaguch 2494 1.1 yamaguch if (qp->qp_si != NULL) 2495 1.1 yamaguch softint_disestablish(qp->qp_si); 2496 1.1 yamaguch if (qp->qp_rxr != NULL) 2497 1.1 yamaguch iavf_rxr_free(sc, qp->qp_rxr); 2498 1.1 yamaguch if (qp->qp_txr != NULL) 2499 1.1 yamaguch iavf_txr_free(sc, qp->qp_txr); 2500 1.1 yamaguch } 2501 1.1 yamaguch 2502 1.1 yamaguch sz = sizeof(sc->sc_qps[0]) * sc->sc_nqps_alloc; 2503 1.1 yamaguch kmem_free(sc->sc_qps, sz); 2504 1.1 yamaguch sc->sc_qps = NULL; 2505 1.1 yamaguch sc->sc_nqps_alloc = 0; 2506 1.1 yamaguch } 2507 1.1 yamaguch 2508 1.1 yamaguch static int 2509 1.1 yamaguch iavf_rxfill(struct iavf_softc *sc, struct iavf_rx_ring *rxr) 2510 1.1 yamaguch { 2511 1.1 yamaguch struct ixl_rx_rd_desc_32 *ring, *rxd; 2512 1.1 yamaguch struct iavf_rx_map *rxm; 2513 1.1 yamaguch bus_dmamap_t map; 2514 1.1 yamaguch struct mbuf *m; 2515 1.1 yamaguch unsigned int slots, prod, mask; 2516 1.1 yamaguch int error, post; 2517 1.1 yamaguch 2518 1.1 yamaguch slots = ixl_rxr_unrefreshed(rxr->rxr_prod, rxr->rxr_cons, 2519 1.1 yamaguch sc->sc_rx_ring_ndescs); 2520 1.1 yamaguch 2521 1.1 yamaguch if (slots == 0) 2522 1.1 yamaguch return 0; 2523 1.1 yamaguch 2524 1.19 joe post = 0; 2525 1.1 yamaguch error = 0; 2526 1.1 yamaguch prod = rxr->rxr_prod; 2527 1.1 yamaguch 2528 1.1 yamaguch ring = IXL_DMA_KVA(&rxr->rxr_mem); 2529 1.1 yamaguch mask = sc->sc_rx_ring_ndescs - 1; 2530 1.1 yamaguch 2531 1.1 yamaguch do { 2532 1.1 yamaguch rxm = &rxr->rxr_maps[prod]; 2533 1.1 yamaguch 2534 1.1 yamaguch MGETHDR(m, M_DONTWAIT, MT_DATA); 2535 1.1 yamaguch if (m == NULL) { 2536 1.1 yamaguch rxr->rxr_mgethdr_failed.ev_count++; 2537 1.1 yamaguch error = -1; 2538 1.1 yamaguch break; 2539 1.1 yamaguch } 2540 1.1 yamaguch 2541 1.1 yamaguch MCLGET(m, M_DONTWAIT); 2542 1.1 yamaguch if (!ISSET(m->m_flags, M_EXT)) { 2543 1.1 yamaguch rxr->rxr_mgetcl_failed.ev_count++; 2544 1.1 yamaguch error = -1; 2545 1.1 yamaguch m_freem(m); 2546 1.1 yamaguch break; 2547 1.1 yamaguch } 2548 1.1 yamaguch 2549 1.1 yamaguch m->m_len = m->m_pkthdr.len = MCLBYTES; 2550 1.1 yamaguch m_adj(m, ETHER_ALIGN); 2551 1.1 yamaguch 2552 1.1 yamaguch map = rxm->rxm_map; 2553 1.1 yamaguch 2554 1.1 yamaguch if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, 2555 1.1 yamaguch BUS_DMA_READ|BUS_DMA_NOWAIT) != 0) { 2556 1.1 yamaguch rxr->rxr_mbuf_load_failed.ev_count++; 2557 1.1 yamaguch error = -1; 2558 1.1 yamaguch m_freem(m); 2559 1.1 yamaguch break; 2560 1.1 yamaguch } 2561 1.1 yamaguch 2562 1.1 yamaguch rxm->rxm_m = m; 2563 1.1 yamaguch 2564 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 2565 1.1 yamaguch BUS_DMASYNC_PREREAD); 2566 1.1 yamaguch 2567 1.1 yamaguch rxd = &ring[prod]; 2568 1.1 yamaguch rxd->paddr = htole64(map->dm_segs[0].ds_addr); 2569 1.1 yamaguch rxd->haddr = htole64(0); 2570 1.1 yamaguch 2571 1.1 yamaguch prod++; 2572 1.1 yamaguch prod &= mask; 2573 1.1 yamaguch post = 1; 2574 1.1 yamaguch } while (--slots); 2575 1.1 yamaguch 2576 1.1 yamaguch if (post) { 2577 1.1 yamaguch rxr->rxr_prod = prod; 2578 1.1 yamaguch iavf_wr(sc, rxr->rxr_tail, prod); 2579 1.1 yamaguch } 2580 1.1 yamaguch 2581 1.1 yamaguch return error; 2582 1.1 yamaguch } 2583 1.1 yamaguch 2584 1.1 yamaguch static inline void 2585 1.1 yamaguch iavf_rx_csum(struct mbuf *m, uint64_t qword) 2586 1.1 yamaguch { 2587 1.1 yamaguch int flags_mask; 2588 1.1 yamaguch 2589 1.1 yamaguch if (!ISSET(qword, IXL_RX_DESC_L3L4P)) { 2590 1.1 yamaguch /* No L3 or L4 checksum was calculated */ 2591 1.1 yamaguch return; 2592 1.1 yamaguch } 2593 1.1 yamaguch 2594 1.1 yamaguch switch (__SHIFTOUT(qword, IXL_RX_DESC_PTYPE_MASK)) { 2595 1.1 yamaguch case IXL_RX_DESC_PTYPE_IPV4FRAG: 2596 1.1 yamaguch case IXL_RX_DESC_PTYPE_IPV4: 2597 1.1 yamaguch case IXL_RX_DESC_PTYPE_SCTPV4: 2598 1.1 yamaguch case IXL_RX_DESC_PTYPE_ICMPV4: 2599 1.1 yamaguch flags_mask = M_CSUM_IPv4 | M_CSUM_IPv4_BAD; 2600 1.1 yamaguch break; 2601 1.1 yamaguch case IXL_RX_DESC_PTYPE_TCPV4: 2602 1.1 yamaguch flags_mask = M_CSUM_IPv4 | M_CSUM_IPv4_BAD; 2603 1.1 yamaguch flags_mask |= M_CSUM_TCPv4 | M_CSUM_TCP_UDP_BAD; 2604 1.1 yamaguch break; 2605 1.1 yamaguch case IXL_RX_DESC_PTYPE_UDPV4: 2606 1.1 yamaguch flags_mask = M_CSUM_IPv4 | M_CSUM_IPv4_BAD; 2607 1.1 yamaguch flags_mask |= M_CSUM_UDPv4 | M_CSUM_TCP_UDP_BAD; 2608 1.1 yamaguch break; 2609 1.1 yamaguch case IXL_RX_DESC_PTYPE_TCPV6: 2610 1.1 yamaguch flags_mask = M_CSUM_TCPv6 | M_CSUM_TCP_UDP_BAD; 2611 1.1 yamaguch break; 2612 1.1 yamaguch case IXL_RX_DESC_PTYPE_UDPV6: 2613 1.1 yamaguch flags_mask = M_CSUM_UDPv6 | M_CSUM_TCP_UDP_BAD; 2614 1.1 yamaguch break; 2615 1.1 yamaguch default: 2616 1.1 yamaguch flags_mask = 0; 2617 1.1 yamaguch } 2618 1.1 yamaguch 2619 1.1 yamaguch m->m_pkthdr.csum_flags |= (flags_mask & (M_CSUM_IPv4 | 2620 1.1 yamaguch M_CSUM_TCPv4 | M_CSUM_TCPv6 | M_CSUM_UDPv4 | M_CSUM_UDPv6)); 2621 1.1 yamaguch 2622 1.1 yamaguch if (ISSET(qword, IXL_RX_DESC_IPE)) { 2623 1.1 yamaguch m->m_pkthdr.csum_flags |= (flags_mask & M_CSUM_IPv4_BAD); 2624 1.1 yamaguch } 2625 1.1 yamaguch 2626 1.1 yamaguch if (ISSET(qword, IXL_RX_DESC_L4E)) { 2627 1.1 yamaguch m->m_pkthdr.csum_flags |= (flags_mask & M_CSUM_TCP_UDP_BAD); 2628 1.1 yamaguch } 2629 1.1 yamaguch } 2630 1.1 yamaguch 2631 1.1 yamaguch static int 2632 1.1 yamaguch iavf_rxeof(struct iavf_softc *sc, struct iavf_rx_ring *rxr, u_int rxlimit, 2633 1.1 yamaguch struct evcnt *ecnt) 2634 1.1 yamaguch { 2635 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 2636 1.1 yamaguch struct ixl_rx_wb_desc_32 *ring, *rxd; 2637 1.1 yamaguch struct iavf_rx_map *rxm; 2638 1.1 yamaguch bus_dmamap_t map; 2639 1.1 yamaguch unsigned int cons, prod; 2640 1.1 yamaguch struct mbuf *m; 2641 1.1 yamaguch uint64_t word, word0; 2642 1.1 yamaguch unsigned int len; 2643 1.1 yamaguch unsigned int mask; 2644 1.1 yamaguch int done = 0, more = 0; 2645 1.1 yamaguch 2646 1.1 yamaguch KASSERT(mutex_owned(&rxr->rxr_lock)); 2647 1.1 yamaguch 2648 1.1 yamaguch if (!ISSET(ifp->if_flags, IFF_RUNNING)) 2649 1.1 yamaguch return 0; 2650 1.1 yamaguch 2651 1.1 yamaguch prod = rxr->rxr_prod; 2652 1.1 yamaguch cons = rxr->rxr_cons; 2653 1.1 yamaguch 2654 1.1 yamaguch if (cons == prod) 2655 1.1 yamaguch return 0; 2656 1.1 yamaguch 2657 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&rxr->rxr_mem), 2658 1.1 yamaguch 0, IXL_DMA_LEN(&rxr->rxr_mem), 2659 1.1 yamaguch BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 2660 1.1 yamaguch 2661 1.1 yamaguch ring = IXL_DMA_KVA(&rxr->rxr_mem); 2662 1.1 yamaguch mask = sc->sc_rx_ring_ndescs - 1; 2663 1.1 yamaguch 2664 1.1 yamaguch net_stat_ref_t nsr = IF_STAT_GETREF(ifp); 2665 1.1 yamaguch 2666 1.1 yamaguch do { 2667 1.1 yamaguch if (rxlimit-- <= 0) { 2668 1.1 yamaguch more = 1; 2669 1.1 yamaguch break; 2670 1.1 yamaguch } 2671 1.1 yamaguch 2672 1.1 yamaguch rxd = &ring[cons]; 2673 1.1 yamaguch 2674 1.1 yamaguch word = le64toh(rxd->qword1); 2675 1.1 yamaguch 2676 1.1 yamaguch if (!ISSET(word, IXL_RX_DESC_DD)) 2677 1.1 yamaguch break; 2678 1.1 yamaguch 2679 1.1 yamaguch rxm = &rxr->rxr_maps[cons]; 2680 1.1 yamaguch 2681 1.1 yamaguch map = rxm->rxm_map; 2682 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 2683 1.1 yamaguch BUS_DMASYNC_POSTREAD); 2684 1.1 yamaguch bus_dmamap_unload(sc->sc_dmat, map); 2685 1.1 yamaguch 2686 1.1 yamaguch m = rxm->rxm_m; 2687 1.1 yamaguch rxm->rxm_m = NULL; 2688 1.1 yamaguch 2689 1.1 yamaguch KASSERT(m != NULL); 2690 1.1 yamaguch 2691 1.1 yamaguch len = (word & IXL_RX_DESC_PLEN_MASK) >> IXL_RX_DESC_PLEN_SHIFT; 2692 1.1 yamaguch m->m_len = len; 2693 1.1 yamaguch m->m_pkthdr.len = 0; 2694 1.1 yamaguch 2695 1.1 yamaguch m->m_next = NULL; 2696 1.1 yamaguch *rxr->rxr_m_tail = m; 2697 1.1 yamaguch rxr->rxr_m_tail = &m->m_next; 2698 1.1 yamaguch 2699 1.1 yamaguch m = rxr->rxr_m_head; 2700 1.1 yamaguch m->m_pkthdr.len += len; 2701 1.1 yamaguch 2702 1.1 yamaguch if (ISSET(word, IXL_RX_DESC_EOP)) { 2703 1.1 yamaguch word0 = le64toh(rxd->qword0); 2704 1.1 yamaguch 2705 1.1 yamaguch if (ISSET(word, IXL_RX_DESC_L2TAG1P)) { 2706 1.16 yamaguch uint16_t vtag; 2707 1.16 yamaguch vtag = __SHIFTOUT(word0, IXL_RX_DESC_L2TAG1_MASK); 2708 1.16 yamaguch vlan_set_tag(m, le16toh(vtag)); 2709 1.1 yamaguch } 2710 1.1 yamaguch 2711 1.1 yamaguch if ((ifp->if_capenable & IAVF_IFCAP_RXCSUM) != 0) 2712 1.1 yamaguch iavf_rx_csum(m, word); 2713 1.1 yamaguch 2714 1.1 yamaguch if (!ISSET(word, 2715 1.1 yamaguch IXL_RX_DESC_RXE | IXL_RX_DESC_OVERSIZE)) { 2716 1.1 yamaguch m_set_rcvif(m, ifp); 2717 1.18 riastrad if_statinc_ref(ifp, nsr, if_ipackets); 2718 1.18 riastrad if_statadd_ref(ifp, nsr, if_ibytes, 2719 1.1 yamaguch m->m_pkthdr.len); 2720 1.1 yamaguch if_percpuq_enqueue(sc->sc_ipq, m); 2721 1.1 yamaguch } else { 2722 1.18 riastrad if_statinc_ref(ifp, nsr, if_ierrors); 2723 1.1 yamaguch m_freem(m); 2724 1.1 yamaguch } 2725 1.1 yamaguch 2726 1.1 yamaguch rxr->rxr_m_head = NULL; 2727 1.1 yamaguch rxr->rxr_m_tail = &rxr->rxr_m_head; 2728 1.1 yamaguch } 2729 1.1 yamaguch 2730 1.1 yamaguch cons++; 2731 1.1 yamaguch cons &= mask; 2732 1.1 yamaguch 2733 1.1 yamaguch done = 1; 2734 1.1 yamaguch } while (cons != prod); 2735 1.1 yamaguch 2736 1.1 yamaguch if (done) { 2737 1.1 yamaguch ecnt->ev_count++; 2738 1.1 yamaguch rxr->rxr_cons = cons; 2739 1.1 yamaguch if (iavf_rxfill(sc, rxr) == -1) 2740 1.18 riastrad if_statinc_ref(ifp, nsr, if_iqdrops); 2741 1.1 yamaguch } 2742 1.1 yamaguch 2743 1.1 yamaguch IF_STAT_PUTREF(ifp); 2744 1.1 yamaguch 2745 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&rxr->rxr_mem), 2746 1.1 yamaguch 0, IXL_DMA_LEN(&rxr->rxr_mem), 2747 1.1 yamaguch BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 2748 1.1 yamaguch 2749 1.1 yamaguch return more; 2750 1.1 yamaguch } 2751 1.1 yamaguch 2752 1.1 yamaguch static void 2753 1.1 yamaguch iavf_rxr_clean(struct iavf_softc *sc, struct iavf_rx_ring *rxr) 2754 1.1 yamaguch { 2755 1.1 yamaguch struct iavf_rx_map *maps, *rxm; 2756 1.1 yamaguch bus_dmamap_t map; 2757 1.1 yamaguch unsigned int i; 2758 1.1 yamaguch 2759 1.1 yamaguch KASSERT(mutex_owned(&rxr->rxr_lock)); 2760 1.1 yamaguch 2761 1.1 yamaguch maps = rxr->rxr_maps; 2762 1.1 yamaguch for (i = 0; i < sc->sc_rx_ring_ndescs; i++) { 2763 1.1 yamaguch rxm = &maps[i]; 2764 1.1 yamaguch 2765 1.1 yamaguch if (rxm->rxm_m == NULL) 2766 1.1 yamaguch continue; 2767 1.1 yamaguch 2768 1.1 yamaguch map = rxm->rxm_map; 2769 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 2770 1.1 yamaguch BUS_DMASYNC_POSTWRITE); 2771 1.1 yamaguch bus_dmamap_unload(sc->sc_dmat, map); 2772 1.1 yamaguch 2773 1.1 yamaguch m_freem(rxm->rxm_m); 2774 1.1 yamaguch rxm->rxm_m = NULL; 2775 1.1 yamaguch } 2776 1.1 yamaguch 2777 1.1 yamaguch m_freem(rxr->rxr_m_head); 2778 1.1 yamaguch rxr->rxr_m_head = NULL; 2779 1.1 yamaguch rxr->rxr_m_tail = &rxr->rxr_m_head; 2780 1.1 yamaguch 2781 1.1 yamaguch memset(IXL_DMA_KVA(&rxr->rxr_mem), 0, IXL_DMA_LEN(&rxr->rxr_mem)); 2782 1.1 yamaguch rxr->rxr_prod = rxr->rxr_cons = 0; 2783 1.1 yamaguch } 2784 1.1 yamaguch 2785 1.1 yamaguch static int 2786 1.1 yamaguch iavf_txeof(struct iavf_softc *sc, struct iavf_tx_ring *txr, u_int txlimit, 2787 1.1 yamaguch struct evcnt *ecnt) 2788 1.1 yamaguch { 2789 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 2790 1.1 yamaguch struct ixl_tx_desc *ring, *txd; 2791 1.1 yamaguch struct iavf_tx_map *txm; 2792 1.1 yamaguch struct mbuf *m; 2793 1.1 yamaguch bus_dmamap_t map; 2794 1.1 yamaguch unsigned int cons, prod, last; 2795 1.1 yamaguch unsigned int mask; 2796 1.1 yamaguch uint64_t dtype; 2797 1.1 yamaguch int done = 0, more = 0; 2798 1.1 yamaguch 2799 1.1 yamaguch KASSERT(mutex_owned(&txr->txr_lock)); 2800 1.1 yamaguch 2801 1.1 yamaguch prod = txr->txr_prod; 2802 1.1 yamaguch cons = txr->txr_cons; 2803 1.1 yamaguch 2804 1.1 yamaguch if (cons == prod) 2805 1.1 yamaguch return 0; 2806 1.1 yamaguch 2807 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem), 2808 1.1 yamaguch 0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_POSTREAD); 2809 1.1 yamaguch 2810 1.1 yamaguch ring = IXL_DMA_KVA(&txr->txr_mem); 2811 1.1 yamaguch mask = sc->sc_tx_ring_ndescs - 1; 2812 1.1 yamaguch 2813 1.1 yamaguch net_stat_ref_t nsr = IF_STAT_GETREF(ifp); 2814 1.1 yamaguch 2815 1.1 yamaguch do { 2816 1.1 yamaguch if (txlimit-- <= 0) { 2817 1.1 yamaguch more = 1; 2818 1.1 yamaguch break; 2819 1.1 yamaguch } 2820 1.1 yamaguch 2821 1.1 yamaguch txm = &txr->txr_maps[cons]; 2822 1.1 yamaguch last = txm->txm_eop; 2823 1.1 yamaguch txd = &ring[last]; 2824 1.1 yamaguch 2825 1.1 yamaguch dtype = txd->cmd & htole64(IXL_TX_DESC_DTYPE_MASK); 2826 1.1 yamaguch if (dtype != htole64(IXL_TX_DESC_DTYPE_DONE)) 2827 1.1 yamaguch break; 2828 1.1 yamaguch 2829 1.1 yamaguch map = txm->txm_map; 2830 1.1 yamaguch 2831 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 2832 1.1 yamaguch BUS_DMASYNC_POSTWRITE); 2833 1.1 yamaguch bus_dmamap_unload(sc->sc_dmat, map); 2834 1.1 yamaguch 2835 1.1 yamaguch m = txm->txm_m; 2836 1.1 yamaguch if (m != NULL) { 2837 1.18 riastrad if_statinc_ref(ifp, nsr, if_opackets); 2838 1.18 riastrad if_statadd_ref(ifp, nsr, if_obytes, m->m_pkthdr.len); 2839 1.1 yamaguch if (ISSET(m->m_flags, M_MCAST)) 2840 1.18 riastrad if_statinc_ref(ifp, nsr, if_omcasts); 2841 1.1 yamaguch m_freem(m); 2842 1.1 yamaguch } 2843 1.1 yamaguch 2844 1.1 yamaguch txm->txm_m = NULL; 2845 1.1 yamaguch txm->txm_eop = -1; 2846 1.1 yamaguch 2847 1.1 yamaguch cons = last + 1; 2848 1.1 yamaguch cons &= mask; 2849 1.1 yamaguch done = 1; 2850 1.1 yamaguch } while (cons != prod); 2851 1.1 yamaguch 2852 1.1 yamaguch IF_STAT_PUTREF(ifp); 2853 1.1 yamaguch 2854 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem), 2855 1.1 yamaguch 0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_PREREAD); 2856 1.1 yamaguch 2857 1.1 yamaguch txr->txr_cons = cons; 2858 1.1 yamaguch 2859 1.1 yamaguch if (done) { 2860 1.1 yamaguch ecnt->ev_count++; 2861 1.1 yamaguch softint_schedule(txr->txr_si); 2862 1.1 yamaguch if (txr->txr_qid == 0) { 2863 1.1 yamaguch CLR(ifp->if_flags, IFF_OACTIVE); 2864 1.1 yamaguch if_schedule_deferred_start(ifp); 2865 1.1 yamaguch } 2866 1.1 yamaguch } 2867 1.1 yamaguch 2868 1.1 yamaguch if (txr->txr_cons == txr->txr_prod) { 2869 1.1 yamaguch txr->txr_watchdog = IAVF_WATCHDOG_STOP; 2870 1.1 yamaguch } 2871 1.1 yamaguch 2872 1.1 yamaguch return more; 2873 1.1 yamaguch } 2874 1.1 yamaguch 2875 1.1 yamaguch static inline int 2876 1.1 yamaguch iavf_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf **m0, 2877 1.1 yamaguch struct iavf_tx_ring *txr) 2878 1.1 yamaguch { 2879 1.1 yamaguch struct mbuf *m; 2880 1.1 yamaguch int error; 2881 1.1 yamaguch 2882 1.1 yamaguch KASSERT(mutex_owned(&txr->txr_lock)); 2883 1.1 yamaguch 2884 1.1 yamaguch m = *m0; 2885 1.1 yamaguch 2886 1.1 yamaguch error = bus_dmamap_load_mbuf(dmat, map, m, 2887 1.1 yamaguch BUS_DMA_STREAMING|BUS_DMA_WRITE|BUS_DMA_NOWAIT); 2888 1.1 yamaguch if (error != EFBIG) 2889 1.1 yamaguch return error; 2890 1.1 yamaguch 2891 1.1 yamaguch m = m_defrag(m, M_DONTWAIT); 2892 1.1 yamaguch if (m != NULL) { 2893 1.1 yamaguch *m0 = m; 2894 1.1 yamaguch txr->txr_defragged.ev_count++; 2895 1.1 yamaguch error = bus_dmamap_load_mbuf(dmat, map, m, 2896 1.1 yamaguch BUS_DMA_STREAMING|BUS_DMA_WRITE|BUS_DMA_NOWAIT); 2897 1.1 yamaguch } else { 2898 1.1 yamaguch txr->txr_defrag_failed.ev_count++; 2899 1.1 yamaguch error = ENOBUFS; 2900 1.1 yamaguch } 2901 1.1 yamaguch 2902 1.1 yamaguch return error; 2903 1.1 yamaguch } 2904 1.1 yamaguch 2905 1.1 yamaguch static inline int 2906 1.1 yamaguch iavf_tx_setup_offloads(struct mbuf *m, uint64_t *cmd_txd) 2907 1.1 yamaguch { 2908 1.1 yamaguch struct ether_header *eh; 2909 1.1 yamaguch size_t len; 2910 1.1 yamaguch uint64_t cmd; 2911 1.1 yamaguch 2912 1.1 yamaguch cmd = 0; 2913 1.1 yamaguch 2914 1.1 yamaguch eh = mtod(m, struct ether_header *); 2915 1.1 yamaguch switch (htons(eh->ether_type)) { 2916 1.1 yamaguch case ETHERTYPE_IP: 2917 1.1 yamaguch case ETHERTYPE_IPV6: 2918 1.1 yamaguch len = ETHER_HDR_LEN; 2919 1.1 yamaguch break; 2920 1.1 yamaguch case ETHERTYPE_VLAN: 2921 1.1 yamaguch len = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; 2922 1.1 yamaguch break; 2923 1.1 yamaguch default: 2924 1.1 yamaguch len = 0; 2925 1.1 yamaguch } 2926 1.1 yamaguch cmd |= ((len >> 1) << IXL_TX_DESC_MACLEN_SHIFT); 2927 1.1 yamaguch 2928 1.1 yamaguch if (m->m_pkthdr.csum_flags & 2929 1.1 yamaguch (M_CSUM_TSOv4 | M_CSUM_TCPv4 | M_CSUM_UDPv4)) { 2930 1.1 yamaguch cmd |= IXL_TX_DESC_CMD_IIPT_IPV4; 2931 1.1 yamaguch } 2932 1.1 yamaguch if (m->m_pkthdr.csum_flags & M_CSUM_IPv4) { 2933 1.1 yamaguch cmd |= IXL_TX_DESC_CMD_IIPT_IPV4_CSUM; 2934 1.1 yamaguch } 2935 1.1 yamaguch 2936 1.1 yamaguch if (m->m_pkthdr.csum_flags & 2937 1.1 yamaguch (M_CSUM_TSOv6 | M_CSUM_TCPv6 | M_CSUM_UDPv6)) { 2938 1.1 yamaguch cmd |= IXL_TX_DESC_CMD_IIPT_IPV6; 2939 1.1 yamaguch } 2940 1.1 yamaguch 2941 1.1 yamaguch switch (cmd & IXL_TX_DESC_CMD_IIPT_MASK) { 2942 1.1 yamaguch case IXL_TX_DESC_CMD_IIPT_IPV4: 2943 1.1 yamaguch case IXL_TX_DESC_CMD_IIPT_IPV4_CSUM: 2944 1.1 yamaguch len = M_CSUM_DATA_IPv4_IPHL(m->m_pkthdr.csum_data); 2945 1.1 yamaguch break; 2946 1.1 yamaguch case IXL_TX_DESC_CMD_IIPT_IPV6: 2947 1.1 yamaguch len = M_CSUM_DATA_IPv6_IPHL(m->m_pkthdr.csum_data); 2948 1.1 yamaguch break; 2949 1.1 yamaguch default: 2950 1.1 yamaguch len = 0; 2951 1.1 yamaguch } 2952 1.1 yamaguch cmd |= ((len >> 2) << IXL_TX_DESC_IPLEN_SHIFT); 2953 1.1 yamaguch 2954 1.1 yamaguch if (m->m_pkthdr.csum_flags & 2955 1.1 yamaguch (M_CSUM_TSOv4 | M_CSUM_TSOv6 | M_CSUM_TCPv4 | M_CSUM_TCPv6)) { 2956 1.1 yamaguch len = sizeof(struct tcphdr); 2957 1.1 yamaguch cmd |= IXL_TX_DESC_CMD_L4T_EOFT_TCP; 2958 1.1 yamaguch } else if (m->m_pkthdr.csum_flags & (M_CSUM_UDPv4 | M_CSUM_UDPv6)) { 2959 1.1 yamaguch len = sizeof(struct udphdr); 2960 1.1 yamaguch cmd |= IXL_TX_DESC_CMD_L4T_EOFT_UDP; 2961 1.1 yamaguch } else { 2962 1.1 yamaguch len = 0; 2963 1.1 yamaguch } 2964 1.1 yamaguch cmd |= ((len >> 2) << IXL_TX_DESC_L4LEN_SHIFT); 2965 1.1 yamaguch 2966 1.1 yamaguch *cmd_txd |= cmd; 2967 1.1 yamaguch return 0; 2968 1.1 yamaguch } 2969 1.1 yamaguch 2970 1.1 yamaguch static void 2971 1.1 yamaguch iavf_tx_common_locked(struct ifnet *ifp, struct iavf_tx_ring *txr, 2972 1.1 yamaguch bool is_transmit) 2973 1.1 yamaguch { 2974 1.1 yamaguch struct iavf_softc *sc; 2975 1.1 yamaguch struct ixl_tx_desc *ring, *txd; 2976 1.1 yamaguch struct iavf_tx_map *txm; 2977 1.1 yamaguch bus_dmamap_t map; 2978 1.1 yamaguch struct mbuf *m; 2979 1.1 yamaguch unsigned int prod, free, last, i; 2980 1.1 yamaguch unsigned int mask; 2981 1.1 yamaguch uint64_t cmd, cmd_txd; 2982 1.1 yamaguch int post = 0; 2983 1.1 yamaguch 2984 1.1 yamaguch KASSERT(mutex_owned(&txr->txr_lock)); 2985 1.1 yamaguch 2986 1.1 yamaguch sc = ifp->if_softc; 2987 1.1 yamaguch 2988 1.1 yamaguch if (!ISSET(ifp->if_flags, IFF_RUNNING) 2989 1.1 yamaguch || (!is_transmit && ISSET(ifp->if_flags, IFF_OACTIVE))) { 2990 1.1 yamaguch if (!is_transmit) 2991 1.1 yamaguch IFQ_PURGE(&ifp->if_snd); 2992 1.1 yamaguch return; 2993 1.1 yamaguch } 2994 1.1 yamaguch 2995 1.1 yamaguch prod = txr->txr_prod; 2996 1.1 yamaguch free = txr->txr_cons; 2997 1.1 yamaguch 2998 1.1 yamaguch if (free <= prod) 2999 1.1 yamaguch free += sc->sc_tx_ring_ndescs; 3000 1.1 yamaguch free -= prod; 3001 1.1 yamaguch 3002 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem), 3003 1.1 yamaguch 0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_POSTWRITE); 3004 1.1 yamaguch 3005 1.1 yamaguch ring = IXL_DMA_KVA(&txr->txr_mem); 3006 1.1 yamaguch mask = sc->sc_tx_ring_ndescs - 1; 3007 1.1 yamaguch last = prod; 3008 1.1 yamaguch cmd = 0; 3009 1.1 yamaguch txd = NULL; 3010 1.1 yamaguch 3011 1.1 yamaguch for (;;) { 3012 1.1 yamaguch if (free < IAVF_TX_PKT_DESCS) { 3013 1.1 yamaguch if (!is_transmit) 3014 1.1 yamaguch SET(ifp->if_flags, IFF_OACTIVE); 3015 1.1 yamaguch break; 3016 1.1 yamaguch } 3017 1.1 yamaguch 3018 1.1 yamaguch if (is_transmit) 3019 1.1 yamaguch m = pcq_get(txr->txr_intrq); 3020 1.1 yamaguch else 3021 1.1 yamaguch IFQ_DEQUEUE(&ifp->if_snd, m); 3022 1.1 yamaguch 3023 1.1 yamaguch if (m == NULL) 3024 1.1 yamaguch break; 3025 1.1 yamaguch 3026 1.1 yamaguch txm = &txr->txr_maps[prod]; 3027 1.1 yamaguch map = txm->txm_map; 3028 1.1 yamaguch 3029 1.1 yamaguch if (iavf_load_mbuf(sc->sc_dmat, map, &m, txr) != 0) { 3030 1.1 yamaguch if_statinc(ifp, if_oerrors); 3031 1.1 yamaguch m_freem(m); 3032 1.1 yamaguch continue; 3033 1.1 yamaguch } 3034 1.1 yamaguch 3035 1.1 yamaguch cmd_txd = 0; 3036 1.1 yamaguch if (m->m_pkthdr.csum_flags & IAVF_CSUM_ALL_OFFLOAD) { 3037 1.1 yamaguch iavf_tx_setup_offloads(m, &cmd_txd); 3038 1.1 yamaguch } 3039 1.1 yamaguch if (vlan_has_tag(m)) { 3040 1.16 yamaguch uint16_t vtag; 3041 1.16 yamaguch vtag = htole16(vlan_get_tag(m)); 3042 1.1 yamaguch cmd_txd |= IXL_TX_DESC_CMD_IL2TAG1 | 3043 1.16 yamaguch ((uint64_t)vtag << IXL_TX_DESC_L2TAG1_SHIFT); 3044 1.1 yamaguch } 3045 1.1 yamaguch 3046 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, map, 0, 3047 1.1 yamaguch map->dm_mapsize, BUS_DMASYNC_PREWRITE); 3048 1.1 yamaguch 3049 1.1 yamaguch for (i = 0; i < (unsigned int)map->dm_nsegs; i++) { 3050 1.1 yamaguch txd = &ring[prod]; 3051 1.1 yamaguch 3052 1.1 yamaguch cmd = (uint64_t)map->dm_segs[i].ds_len << 3053 1.1 yamaguch IXL_TX_DESC_BSIZE_SHIFT; 3054 1.1 yamaguch cmd |= IXL_TX_DESC_DTYPE_DATA|IXL_TX_DESC_CMD_ICRC| 3055 1.1 yamaguch cmd_txd; 3056 1.1 yamaguch 3057 1.1 yamaguch txd->addr = htole64(map->dm_segs[i].ds_addr); 3058 1.1 yamaguch txd->cmd = htole64(cmd); 3059 1.1 yamaguch 3060 1.1 yamaguch last = prod; 3061 1.1 yamaguch prod++; 3062 1.1 yamaguch prod &= mask; 3063 1.1 yamaguch } 3064 1.1 yamaguch 3065 1.1 yamaguch cmd |= IXL_TX_DESC_CMD_EOP|IXL_TX_DESC_CMD_RS; 3066 1.1 yamaguch txd->cmd = htole64(cmd); 3067 1.1 yamaguch txm->txm_m = m; 3068 1.1 yamaguch txm->txm_eop = last; 3069 1.1 yamaguch 3070 1.1 yamaguch bpf_mtap(ifp, m, BPF_D_OUT); 3071 1.1 yamaguch free -= i; 3072 1.1 yamaguch post = 1; 3073 1.1 yamaguch } 3074 1.1 yamaguch 3075 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem), 3076 1.1 yamaguch 0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_PREWRITE); 3077 1.1 yamaguch 3078 1.1 yamaguch if (post) { 3079 1.1 yamaguch txr->txr_prod = prod; 3080 1.1 yamaguch iavf_wr(sc, txr->txr_tail, prod); 3081 1.1 yamaguch txr->txr_watchdog = IAVF_WATCHDOG_TICKS; 3082 1.1 yamaguch } 3083 1.1 yamaguch } 3084 1.1 yamaguch 3085 1.1 yamaguch static inline int 3086 1.1 yamaguch iavf_handle_queue_common(struct iavf_softc *sc, struct iavf_queue_pair *qp, 3087 1.1 yamaguch u_int txlimit, struct evcnt *txevcnt, 3088 1.1 yamaguch u_int rxlimit, struct evcnt *rxevcnt) 3089 1.1 yamaguch { 3090 1.1 yamaguch struct iavf_tx_ring *txr; 3091 1.1 yamaguch struct iavf_rx_ring *rxr; 3092 1.1 yamaguch int txmore, rxmore; 3093 1.1 yamaguch int rv; 3094 1.1 yamaguch 3095 1.1 yamaguch txr = qp->qp_txr; 3096 1.1 yamaguch rxr = qp->qp_rxr; 3097 1.1 yamaguch 3098 1.1 yamaguch mutex_enter(&txr->txr_lock); 3099 1.1 yamaguch txmore = iavf_txeof(sc, txr, txlimit, txevcnt); 3100 1.1 yamaguch mutex_exit(&txr->txr_lock); 3101 1.1 yamaguch 3102 1.1 yamaguch mutex_enter(&rxr->rxr_lock); 3103 1.1 yamaguch rxmore = iavf_rxeof(sc, rxr, rxlimit, rxevcnt); 3104 1.1 yamaguch mutex_exit(&rxr->rxr_lock); 3105 1.1 yamaguch 3106 1.1 yamaguch rv = txmore | (rxmore << 1); 3107 1.1 yamaguch 3108 1.1 yamaguch return rv; 3109 1.1 yamaguch } 3110 1.1 yamaguch 3111 1.1 yamaguch static void 3112 1.1 yamaguch iavf_sched_handle_queue(struct iavf_softc *sc, struct iavf_queue_pair *qp) 3113 1.1 yamaguch { 3114 1.1 yamaguch 3115 1.1 yamaguch if (qp->qp_workqueue) 3116 1.1 yamaguch workqueue_enqueue(sc->sc_workq_txrx, &qp->qp_work, NULL); 3117 1.1 yamaguch else 3118 1.1 yamaguch softint_schedule(qp->qp_si); 3119 1.1 yamaguch } 3120 1.1 yamaguch 3121 1.1 yamaguch static void 3122 1.1 yamaguch iavf_start(struct ifnet *ifp) 3123 1.1 yamaguch { 3124 1.1 yamaguch struct iavf_softc *sc; 3125 1.1 yamaguch struct iavf_tx_ring *txr; 3126 1.1 yamaguch 3127 1.1 yamaguch sc = ifp->if_softc; 3128 1.1 yamaguch txr = sc->sc_qps[0].qp_txr; 3129 1.1 yamaguch 3130 1.1 yamaguch mutex_enter(&txr->txr_lock); 3131 1.1 yamaguch iavf_tx_common_locked(ifp, txr, false); 3132 1.1 yamaguch mutex_exit(&txr->txr_lock); 3133 1.1 yamaguch 3134 1.1 yamaguch } 3135 1.1 yamaguch 3136 1.1 yamaguch static inline unsigned int 3137 1.1 yamaguch iavf_select_txqueue(struct iavf_softc *sc, struct mbuf *m) 3138 1.1 yamaguch { 3139 1.1 yamaguch u_int cpuid; 3140 1.1 yamaguch 3141 1.1 yamaguch cpuid = cpu_index(curcpu()); 3142 1.1 yamaguch 3143 1.1 yamaguch return (unsigned int)(cpuid % sc->sc_nqueue_pairs); 3144 1.1 yamaguch } 3145 1.1 yamaguch 3146 1.1 yamaguch static int 3147 1.1 yamaguch iavf_transmit(struct ifnet *ifp, struct mbuf *m) 3148 1.1 yamaguch { 3149 1.1 yamaguch struct iavf_softc *sc; 3150 1.1 yamaguch struct iavf_tx_ring *txr; 3151 1.1 yamaguch unsigned int qid; 3152 1.1 yamaguch 3153 1.1 yamaguch sc = ifp->if_softc; 3154 1.1 yamaguch qid = iavf_select_txqueue(sc, m); 3155 1.1 yamaguch 3156 1.1 yamaguch txr = sc->sc_qps[qid].qp_txr; 3157 1.1 yamaguch 3158 1.1 yamaguch if (__predict_false(!pcq_put(txr->txr_intrq, m))) { 3159 1.1 yamaguch mutex_enter(&txr->txr_lock); 3160 1.1 yamaguch txr->txr_pcqdrop.ev_count++; 3161 1.1 yamaguch mutex_exit(&txr->txr_lock); 3162 1.1 yamaguch 3163 1.1 yamaguch m_freem(m); 3164 1.1 yamaguch return ENOBUFS; 3165 1.1 yamaguch } 3166 1.1 yamaguch 3167 1.1 yamaguch if (mutex_tryenter(&txr->txr_lock)) { 3168 1.1 yamaguch iavf_tx_common_locked(ifp, txr, true); 3169 1.1 yamaguch mutex_exit(&txr->txr_lock); 3170 1.1 yamaguch } else { 3171 1.1 yamaguch kpreempt_disable(); 3172 1.1 yamaguch softint_schedule(txr->txr_si); 3173 1.1 yamaguch kpreempt_enable(); 3174 1.1 yamaguch } 3175 1.1 yamaguch return 0; 3176 1.1 yamaguch } 3177 1.1 yamaguch 3178 1.1 yamaguch static void 3179 1.1 yamaguch iavf_deferred_transmit(void *xtxr) 3180 1.1 yamaguch { 3181 1.1 yamaguch struct iavf_tx_ring *txr; 3182 1.1 yamaguch struct iavf_softc *sc; 3183 1.1 yamaguch struct ifnet *ifp; 3184 1.1 yamaguch 3185 1.1 yamaguch txr = xtxr; 3186 1.1 yamaguch sc = txr->txr_sc; 3187 1.1 yamaguch ifp = &sc->sc_ec.ec_if; 3188 1.1 yamaguch 3189 1.1 yamaguch mutex_enter(&txr->txr_lock); 3190 1.1 yamaguch txr->txr_transmitdef.ev_count++; 3191 1.1 yamaguch if (pcq_peek(txr->txr_intrq) != NULL) 3192 1.1 yamaguch iavf_tx_common_locked(ifp, txr, true); 3193 1.1 yamaguch mutex_exit(&txr->txr_lock); 3194 1.1 yamaguch } 3195 1.1 yamaguch 3196 1.1 yamaguch static void 3197 1.1 yamaguch iavf_txr_clean(struct iavf_softc *sc, struct iavf_tx_ring *txr) 3198 1.1 yamaguch { 3199 1.1 yamaguch struct iavf_tx_map *maps, *txm; 3200 1.1 yamaguch bus_dmamap_t map; 3201 1.1 yamaguch unsigned int i; 3202 1.1 yamaguch 3203 1.1 yamaguch KASSERT(mutex_owned(&txr->txr_lock)); 3204 1.1 yamaguch 3205 1.1 yamaguch maps = txr->txr_maps; 3206 1.1 yamaguch for (i = 0; i < sc->sc_tx_ring_ndescs; i++) { 3207 1.1 yamaguch txm = &maps[i]; 3208 1.1 yamaguch 3209 1.1 yamaguch if (txm->txm_m == NULL) 3210 1.1 yamaguch continue; 3211 1.1 yamaguch 3212 1.1 yamaguch map = txm->txm_map; 3213 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 3214 1.1 yamaguch BUS_DMASYNC_POSTWRITE); 3215 1.1 yamaguch bus_dmamap_unload(sc->sc_dmat, map); 3216 1.1 yamaguch 3217 1.1 yamaguch m_freem(txm->txm_m); 3218 1.1 yamaguch txm->txm_m = NULL; 3219 1.1 yamaguch } 3220 1.1 yamaguch 3221 1.1 yamaguch memset(IXL_DMA_KVA(&txr->txr_mem), 0, IXL_DMA_LEN(&txr->txr_mem)); 3222 1.1 yamaguch txr->txr_prod = txr->txr_cons = 0; 3223 1.1 yamaguch } 3224 1.1 yamaguch 3225 1.1 yamaguch static int 3226 1.1 yamaguch iavf_intr(void *xsc) 3227 1.1 yamaguch { 3228 1.1 yamaguch struct iavf_softc *sc = xsc; 3229 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 3230 1.1 yamaguch struct iavf_rx_ring *rxr; 3231 1.1 yamaguch struct iavf_tx_ring *txr; 3232 1.1 yamaguch uint32_t icr; 3233 1.1 yamaguch unsigned int i; 3234 1.1 yamaguch 3235 1.1 yamaguch /* read I40E_VFINT_ICR_ENA1 to clear status */ 3236 1.1 yamaguch (void)iavf_rd(sc, I40E_VFINT_ICR0_ENA1); 3237 1.1 yamaguch 3238 1.1 yamaguch iavf_intr_enable(sc); 3239 1.1 yamaguch icr = iavf_rd(sc, I40E_VFINT_ICR01); 3240 1.1 yamaguch 3241 1.1 yamaguch if (icr == IAVF_REG_VFR) { 3242 1.1 yamaguch log(LOG_INFO, "%s: VF reset in progress\n", 3243 1.1 yamaguch ifp->if_xname); 3244 1.1 yamaguch iavf_work_set(&sc->sc_reset_task, iavf_reset_start, sc); 3245 1.1 yamaguch iavf_work_add(sc->sc_workq, &sc->sc_reset_task); 3246 1.1 yamaguch return 1; 3247 1.1 yamaguch } 3248 1.1 yamaguch 3249 1.1 yamaguch if (ISSET(icr, I40E_VFINT_ICR01_ADMINQ_MASK)) { 3250 1.1 yamaguch mutex_enter(&sc->sc_adminq_lock); 3251 1.1 yamaguch iavf_atq_done(sc); 3252 1.1 yamaguch iavf_arq(sc); 3253 1.1 yamaguch mutex_exit(&sc->sc_adminq_lock); 3254 1.1 yamaguch } 3255 1.1 yamaguch 3256 1.1 yamaguch if (ISSET(icr, I40E_VFINT_ICR01_QUEUE_0_MASK)) { 3257 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 3258 1.1 yamaguch rxr = sc->sc_qps[i].qp_rxr; 3259 1.1 yamaguch txr = sc->sc_qps[i].qp_txr; 3260 1.1 yamaguch 3261 1.1 yamaguch mutex_enter(&rxr->rxr_lock); 3262 1.1 yamaguch while (iavf_rxeof(sc, rxr, UINT_MAX, 3263 1.1 yamaguch &rxr->rxr_intr) != 0) { 3264 1.1 yamaguch /* do nothing */ 3265 1.1 yamaguch } 3266 1.1 yamaguch mutex_exit(&rxr->rxr_lock); 3267 1.1 yamaguch 3268 1.1 yamaguch mutex_enter(&txr->txr_lock); 3269 1.1 yamaguch while (iavf_txeof(sc, txr, UINT_MAX, 3270 1.1 yamaguch &txr->txr_intr) != 0) { 3271 1.1 yamaguch /* do nothing */ 3272 1.1 yamaguch } 3273 1.1 yamaguch mutex_exit(&txr->txr_lock); 3274 1.1 yamaguch } 3275 1.1 yamaguch } 3276 1.1 yamaguch 3277 1.1 yamaguch return 0; 3278 1.1 yamaguch } 3279 1.1 yamaguch 3280 1.1 yamaguch static int 3281 1.1 yamaguch iavf_queue_intr(void *xqp) 3282 1.1 yamaguch { 3283 1.1 yamaguch struct iavf_queue_pair *qp = xqp; 3284 1.1 yamaguch struct iavf_tx_ring *txr; 3285 1.1 yamaguch struct iavf_rx_ring *rxr; 3286 1.1 yamaguch struct iavf_softc *sc; 3287 1.1 yamaguch unsigned int qid; 3288 1.1 yamaguch u_int txlimit, rxlimit; 3289 1.1 yamaguch int more; 3290 1.1 yamaguch 3291 1.1 yamaguch txr = qp->qp_txr; 3292 1.1 yamaguch rxr = qp->qp_rxr; 3293 1.1 yamaguch sc = txr->txr_sc; 3294 1.1 yamaguch qid = txr->txr_qid; 3295 1.1 yamaguch 3296 1.1 yamaguch txlimit = sc->sc_tx_intr_process_limit; 3297 1.1 yamaguch rxlimit = sc->sc_rx_intr_process_limit; 3298 1.1 yamaguch qp->qp_workqueue = sc->sc_txrx_workqueue; 3299 1.1 yamaguch 3300 1.1 yamaguch more = iavf_handle_queue_common(sc, qp, 3301 1.1 yamaguch txlimit, &txr->txr_intr, rxlimit, &rxr->rxr_intr); 3302 1.1 yamaguch 3303 1.1 yamaguch if (more != 0) { 3304 1.1 yamaguch iavf_sched_handle_queue(sc, qp); 3305 1.1 yamaguch } else { 3306 1.1 yamaguch /* for ALTQ */ 3307 1.1 yamaguch if (txr->txr_qid == 0) 3308 1.1 yamaguch if_schedule_deferred_start(&sc->sc_ec.ec_if); 3309 1.1 yamaguch softint_schedule(txr->txr_si); 3310 1.1 yamaguch 3311 1.1 yamaguch iavf_queue_intr_enable(sc, qid); 3312 1.1 yamaguch } 3313 1.1 yamaguch 3314 1.1 yamaguch return 0; 3315 1.1 yamaguch } 3316 1.1 yamaguch 3317 1.1 yamaguch static void 3318 1.1 yamaguch iavf_handle_queue_wk(struct work *wk, void *xsc __unused) 3319 1.1 yamaguch { 3320 1.1 yamaguch struct iavf_queue_pair *qp; 3321 1.1 yamaguch 3322 1.1 yamaguch qp = container_of(wk, struct iavf_queue_pair, qp_work); 3323 1.1 yamaguch iavf_handle_queue(qp); 3324 1.1 yamaguch } 3325 1.1 yamaguch 3326 1.1 yamaguch static void 3327 1.1 yamaguch iavf_handle_queue(void *xqp) 3328 1.1 yamaguch { 3329 1.1 yamaguch struct iavf_queue_pair *qp = xqp; 3330 1.1 yamaguch struct iavf_tx_ring *txr; 3331 1.1 yamaguch struct iavf_rx_ring *rxr; 3332 1.1 yamaguch struct iavf_softc *sc; 3333 1.1 yamaguch unsigned int qid; 3334 1.1 yamaguch u_int txlimit, rxlimit; 3335 1.1 yamaguch int more; 3336 1.1 yamaguch 3337 1.1 yamaguch txr = qp->qp_txr; 3338 1.1 yamaguch rxr = qp->qp_rxr; 3339 1.1 yamaguch sc = txr->txr_sc; 3340 1.1 yamaguch qid = txr->txr_qid; 3341 1.1 yamaguch 3342 1.1 yamaguch txlimit = sc->sc_tx_process_limit; 3343 1.1 yamaguch rxlimit = sc->sc_rx_process_limit; 3344 1.1 yamaguch 3345 1.1 yamaguch more = iavf_handle_queue_common(sc, qp, 3346 1.1 yamaguch txlimit, &txr->txr_defer, rxlimit, &rxr->rxr_defer); 3347 1.1 yamaguch 3348 1.1 yamaguch if (more != 0) 3349 1.1 yamaguch iavf_sched_handle_queue(sc, qp); 3350 1.1 yamaguch else 3351 1.1 yamaguch iavf_queue_intr_enable(sc, qid); 3352 1.1 yamaguch } 3353 1.1 yamaguch 3354 1.1 yamaguch static void 3355 1.1 yamaguch iavf_tick(void *xsc) 3356 1.1 yamaguch { 3357 1.1 yamaguch struct iavf_softc *sc; 3358 1.1 yamaguch unsigned int i; 3359 1.1 yamaguch int timedout; 3360 1.1 yamaguch 3361 1.1 yamaguch sc = xsc; 3362 1.1 yamaguch timedout = 0; 3363 1.1 yamaguch 3364 1.1 yamaguch mutex_enter(&sc->sc_cfg_lock); 3365 1.1 yamaguch 3366 1.1 yamaguch if (sc->sc_resetting) { 3367 1.1 yamaguch iavf_work_add(sc->sc_workq, &sc->sc_reset_task); 3368 1.1 yamaguch mutex_exit(&sc->sc_cfg_lock); 3369 1.1 yamaguch return; 3370 1.1 yamaguch } 3371 1.1 yamaguch 3372 1.1 yamaguch iavf_get_stats(sc); 3373 1.1 yamaguch 3374 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 3375 1.1 yamaguch timedout |= iavf_watchdog(sc->sc_qps[i].qp_txr); 3376 1.1 yamaguch } 3377 1.1 yamaguch 3378 1.1 yamaguch if (timedout != 0) { 3379 1.1 yamaguch iavf_work_add(sc->sc_workq, &sc->sc_wdto_task); 3380 1.1 yamaguch } else { 3381 1.1 yamaguch callout_schedule(&sc->sc_tick, IAVF_TICK_INTERVAL); 3382 1.1 yamaguch } 3383 1.1 yamaguch 3384 1.1 yamaguch mutex_exit(&sc->sc_cfg_lock); 3385 1.1 yamaguch } 3386 1.1 yamaguch 3387 1.1 yamaguch static void 3388 1.1 yamaguch iavf_tick_halt(void *unused __unused) 3389 1.1 yamaguch { 3390 1.1 yamaguch 3391 1.1 yamaguch /* do nothing */ 3392 1.1 yamaguch } 3393 1.1 yamaguch 3394 1.1 yamaguch static void 3395 1.1 yamaguch iavf_reset_request(void *xsc) 3396 1.1 yamaguch { 3397 1.1 yamaguch struct iavf_softc *sc = xsc; 3398 1.1 yamaguch 3399 1.1 yamaguch iavf_reset_vf(sc); 3400 1.1 yamaguch iavf_reset_start(sc); 3401 1.1 yamaguch } 3402 1.1 yamaguch 3403 1.1 yamaguch static void 3404 1.1 yamaguch iavf_reset_start(void *xsc) 3405 1.1 yamaguch { 3406 1.1 yamaguch struct iavf_softc *sc = xsc; 3407 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 3408 1.1 yamaguch 3409 1.1 yamaguch mutex_enter(&sc->sc_cfg_lock); 3410 1.1 yamaguch 3411 1.1 yamaguch if (sc->sc_resetting) 3412 1.1 yamaguch goto do_reset; 3413 1.1 yamaguch 3414 1.1 yamaguch sc->sc_resetting = true; 3415 1.1 yamaguch if_link_state_change(ifp, LINK_STATE_DOWN); 3416 1.1 yamaguch 3417 1.1 yamaguch if (ISSET(ifp->if_flags, IFF_RUNNING)) { 3418 1.1 yamaguch iavf_stop_locked(sc); 3419 1.1 yamaguch sc->sc_reset_up = true; 3420 1.1 yamaguch } 3421 1.1 yamaguch 3422 1.1 yamaguch memcpy(sc->sc_enaddr_reset, sc->sc_enaddr, ETHER_ADDR_LEN); 3423 1.1 yamaguch 3424 1.1 yamaguch do_reset: 3425 1.1 yamaguch iavf_work_set(&sc->sc_reset_task, iavf_reset, sc); 3426 1.1 yamaguch 3427 1.1 yamaguch mutex_exit(&sc->sc_cfg_lock); 3428 1.1 yamaguch 3429 1.1 yamaguch iavf_reset((void *)sc); 3430 1.1 yamaguch } 3431 1.1 yamaguch 3432 1.1 yamaguch static void 3433 1.1 yamaguch iavf_reset(void *xsc) 3434 1.1 yamaguch { 3435 1.1 yamaguch struct iavf_softc *sc = xsc; 3436 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 3437 1.1 yamaguch struct ixl_aq_buf *aqb; 3438 1.1 yamaguch bool realloc_qps, realloc_intrs; 3439 1.1 yamaguch 3440 1.1 yamaguch mutex_enter(&sc->sc_cfg_lock); 3441 1.1 yamaguch 3442 1.1 yamaguch mutex_enter(&sc->sc_adminq_lock); 3443 1.1 yamaguch iavf_cleanup_admin_queue(sc); 3444 1.1 yamaguch mutex_exit(&sc->sc_adminq_lock); 3445 1.1 yamaguch 3446 1.1 yamaguch sc->sc_major_ver = UINT_MAX; 3447 1.1 yamaguch sc->sc_minor_ver = UINT_MAX; 3448 1.1 yamaguch sc->sc_got_vf_resources = 0; 3449 1.1 yamaguch sc->sc_got_irq_map = 0; 3450 1.1 yamaguch 3451 1.1 yamaguch aqb = iavf_aqb_get(sc, &sc->sc_atq_idle); 3452 1.1 yamaguch if (aqb == NULL) 3453 1.1 yamaguch goto failed; 3454 1.1 yamaguch 3455 1.1 yamaguch if (iavf_wait_active(sc) != 0) { 3456 1.1 yamaguch log(LOG_WARNING, "%s: VF reset timed out\n", 3457 1.1 yamaguch ifp->if_xname); 3458 1.1 yamaguch goto failed; 3459 1.1 yamaguch } 3460 1.1 yamaguch 3461 1.1 yamaguch if (!iavf_arq_fill(sc)) { 3462 1.1 yamaguch log(LOG_ERR, "%s: unable to fill arq descriptors\n", 3463 1.1 yamaguch ifp->if_xname); 3464 1.1 yamaguch goto failed; 3465 1.1 yamaguch } 3466 1.1 yamaguch 3467 1.1 yamaguch if (iavf_init_admin_queue(sc) != 0) { 3468 1.1 yamaguch log(LOG_ERR, "%s: unable to initialize admin queue\n", 3469 1.1 yamaguch ifp->if_xname); 3470 1.1 yamaguch goto failed; 3471 1.1 yamaguch } 3472 1.1 yamaguch 3473 1.1 yamaguch if (iavf_get_version(sc, aqb) != 0) { 3474 1.1 yamaguch log(LOG_ERR, "%s: unable to get VF interface version\n", 3475 1.1 yamaguch ifp->if_xname); 3476 1.1 yamaguch goto failed; 3477 1.1 yamaguch } 3478 1.1 yamaguch 3479 1.1 yamaguch if (iavf_get_vf_resources(sc, aqb) != 0) { 3480 1.1 yamaguch log(LOG_ERR, "%s: timed out waiting for VF resources\n", 3481 1.1 yamaguch ifp->if_xname); 3482 1.1 yamaguch goto failed; 3483 1.1 yamaguch } 3484 1.1 yamaguch 3485 1.1 yamaguch if (sc->sc_nqps_alloc < iavf_calc_queue_pair_size(sc)) { 3486 1.1 yamaguch realloc_qps = true; 3487 1.1 yamaguch } else { 3488 1.1 yamaguch realloc_qps = false; 3489 1.1 yamaguch } 3490 1.1 yamaguch 3491 1.1 yamaguch if (sc->sc_nintrs < iavf_calc_msix_count(sc)) { 3492 1.1 yamaguch realloc_intrs = true; 3493 1.1 yamaguch } else { 3494 1.1 yamaguch realloc_intrs = false; 3495 1.1 yamaguch } 3496 1.1 yamaguch 3497 1.1 yamaguch if (realloc_qps || realloc_intrs) 3498 1.1 yamaguch iavf_teardown_interrupts(sc); 3499 1.1 yamaguch 3500 1.1 yamaguch if (realloc_qps) { 3501 1.1 yamaguch iavf_queue_pairs_free(sc); 3502 1.1 yamaguch if (iavf_queue_pairs_alloc(sc) != 0) { 3503 1.1 yamaguch log(LOG_ERR, "%s: failed to allocate queue pairs\n", 3504 1.1 yamaguch ifp->if_xname); 3505 1.1 yamaguch goto failed; 3506 1.1 yamaguch } 3507 1.1 yamaguch } 3508 1.1 yamaguch 3509 1.1 yamaguch if (realloc_qps || realloc_intrs) { 3510 1.1 yamaguch if (iavf_setup_interrupts(sc) != 0) { 3511 1.1 yamaguch sc->sc_nintrs = 0; 3512 1.1 yamaguch log(LOG_ERR, "%s: failed to allocate interrupts\n", 3513 1.1 yamaguch ifp->if_xname); 3514 1.1 yamaguch goto failed; 3515 1.1 yamaguch } 3516 1.1 yamaguch log(LOG_INFO, "%s: reallocated queues\n", ifp->if_xname); 3517 1.1 yamaguch } 3518 1.1 yamaguch 3519 1.1 yamaguch if (iavf_config_irq_map(sc, aqb) != 0) { 3520 1.1 yamaguch log(LOG_ERR, "%s: timed out configuring IRQ map\n", 3521 1.1 yamaguch ifp->if_xname); 3522 1.1 yamaguch goto failed; 3523 1.1 yamaguch } 3524 1.1 yamaguch 3525 1.1 yamaguch mutex_enter(&sc->sc_adminq_lock); 3526 1.1 yamaguch iavf_aqb_put_locked(&sc->sc_atq_idle, aqb); 3527 1.1 yamaguch mutex_exit(&sc->sc_adminq_lock); 3528 1.1 yamaguch 3529 1.1 yamaguch iavf_reset_finish(sc); 3530 1.1 yamaguch 3531 1.1 yamaguch mutex_exit(&sc->sc_cfg_lock); 3532 1.1 yamaguch return; 3533 1.1 yamaguch 3534 1.1 yamaguch failed: 3535 1.1 yamaguch mutex_enter(&sc->sc_adminq_lock); 3536 1.1 yamaguch iavf_cleanup_admin_queue(sc); 3537 1.1 yamaguch if (aqb != NULL) { 3538 1.1 yamaguch iavf_aqb_put_locked(&sc->sc_atq_idle, aqb); 3539 1.1 yamaguch } 3540 1.1 yamaguch mutex_exit(&sc->sc_adminq_lock); 3541 1.1 yamaguch callout_schedule(&sc->sc_tick, IAVF_TICK_INTERVAL); 3542 1.1 yamaguch mutex_exit(&sc->sc_cfg_lock); 3543 1.1 yamaguch } 3544 1.1 yamaguch 3545 1.1 yamaguch static void 3546 1.1 yamaguch iavf_reset_finish(struct iavf_softc *sc) 3547 1.1 yamaguch { 3548 1.1 yamaguch struct ethercom *ec = &sc->sc_ec; 3549 1.1 yamaguch struct ether_multi *enm; 3550 1.1 yamaguch struct ether_multistep step; 3551 1.1 yamaguch struct ifnet *ifp = &ec->ec_if; 3552 1.1 yamaguch struct vlanid_list *vlanidp; 3553 1.5 yamaguch uint8_t enaddr_prev[ETHER_ADDR_LEN], enaddr_next[ETHER_ADDR_LEN]; 3554 1.1 yamaguch 3555 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_cfg_lock)); 3556 1.1 yamaguch 3557 1.1 yamaguch callout_stop(&sc->sc_tick); 3558 1.1 yamaguch 3559 1.1 yamaguch iavf_intr_enable(sc); 3560 1.1 yamaguch 3561 1.1 yamaguch if (!iavf_is_etheranyaddr(sc->sc_enaddr_added)) { 3562 1.1 yamaguch iavf_eth_addr(sc, sc->sc_enaddr_added, IAVF_VC_OP_ADD_ETH_ADDR); 3563 1.1 yamaguch } 3564 1.1 yamaguch 3565 1.1 yamaguch ETHER_LOCK(ec); 3566 1.1 yamaguch if (!ISSET(ifp->if_flags, IFF_ALLMULTI)) { 3567 1.1 yamaguch for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL; 3568 1.1 yamaguch ETHER_NEXT_MULTI(step, enm)) { 3569 1.1 yamaguch iavf_add_multi(sc, enm->enm_addrlo, enm->enm_addrhi); 3570 1.1 yamaguch } 3571 1.1 yamaguch } 3572 1.1 yamaguch 3573 1.1 yamaguch SIMPLEQ_FOREACH(vlanidp, &ec->ec_vids, vid_list) { 3574 1.1 yamaguch ETHER_UNLOCK(ec); 3575 1.1 yamaguch iavf_config_vlan_id(sc, vlanidp->vid, IAVF_VC_OP_ADD_VLAN); 3576 1.1 yamaguch ETHER_LOCK(ec); 3577 1.1 yamaguch } 3578 1.1 yamaguch ETHER_UNLOCK(ec); 3579 1.1 yamaguch 3580 1.1 yamaguch if (memcmp(sc->sc_enaddr, sc->sc_enaddr_reset, ETHER_ADDR_LEN) != 0) { 3581 1.5 yamaguch memcpy(enaddr_prev, sc->sc_enaddr_reset, sizeof(enaddr_prev)); 3582 1.5 yamaguch memcpy(enaddr_next, sc->sc_enaddr, sizeof(enaddr_next)); 3583 1.1 yamaguch log(LOG_INFO, "%s: Ethernet address changed to %s\n", 3584 1.5 yamaguch ifp->if_xname, ether_sprintf(enaddr_next)); 3585 1.5 yamaguch 3586 1.5 yamaguch mutex_exit(&sc->sc_cfg_lock); 3587 1.1 yamaguch IFNET_LOCK(ifp); 3588 1.1 yamaguch kpreempt_disable(); 3589 1.1 yamaguch /*XXX we need an API to change ethernet address. */ 3590 1.5 yamaguch iavf_replace_lla(ifp, enaddr_prev, enaddr_next); 3591 1.1 yamaguch kpreempt_enable(); 3592 1.1 yamaguch IFNET_UNLOCK(ifp); 3593 1.5 yamaguch mutex_enter(&sc->sc_cfg_lock); 3594 1.1 yamaguch } 3595 1.1 yamaguch 3596 1.1 yamaguch sc->sc_resetting = false; 3597 1.1 yamaguch 3598 1.1 yamaguch if (sc->sc_reset_up) { 3599 1.1 yamaguch iavf_init_locked(sc); 3600 1.1 yamaguch } 3601 1.1 yamaguch 3602 1.1 yamaguch if (sc->sc_link_state != LINK_STATE_DOWN) { 3603 1.1 yamaguch if_link_state_change(ifp, sc->sc_link_state); 3604 1.1 yamaguch } 3605 1.1 yamaguch 3606 1.1 yamaguch } 3607 1.1 yamaguch 3608 1.1 yamaguch static int 3609 1.1 yamaguch iavf_dmamem_alloc(bus_dma_tag_t dmat, struct ixl_dmamem *ixm, 3610 1.1 yamaguch bus_size_t size, bus_size_t align) 3611 1.1 yamaguch { 3612 1.1 yamaguch ixm->ixm_size = size; 3613 1.1 yamaguch 3614 1.1 yamaguch if (bus_dmamap_create(dmat, ixm->ixm_size, 1, 3615 1.1 yamaguch ixm->ixm_size, 0, 3616 1.1 yamaguch BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, 3617 1.1 yamaguch &ixm->ixm_map) != 0) 3618 1.1 yamaguch return 1; 3619 1.1 yamaguch if (bus_dmamem_alloc(dmat, ixm->ixm_size, 3620 1.1 yamaguch align, 0, &ixm->ixm_seg, 1, &ixm->ixm_nsegs, 3621 1.1 yamaguch BUS_DMA_WAITOK) != 0) 3622 1.1 yamaguch goto destroy; 3623 1.1 yamaguch if (bus_dmamem_map(dmat, &ixm->ixm_seg, ixm->ixm_nsegs, 3624 1.1 yamaguch ixm->ixm_size, &ixm->ixm_kva, BUS_DMA_WAITOK) != 0) 3625 1.1 yamaguch goto free; 3626 1.1 yamaguch if (bus_dmamap_load(dmat, ixm->ixm_map, ixm->ixm_kva, 3627 1.1 yamaguch ixm->ixm_size, NULL, BUS_DMA_WAITOK) != 0) 3628 1.1 yamaguch goto unmap; 3629 1.1 yamaguch 3630 1.1 yamaguch memset(ixm->ixm_kva, 0, ixm->ixm_size); 3631 1.1 yamaguch 3632 1.1 yamaguch return 0; 3633 1.1 yamaguch unmap: 3634 1.1 yamaguch bus_dmamem_unmap(dmat, ixm->ixm_kva, ixm->ixm_size); 3635 1.1 yamaguch free: 3636 1.1 yamaguch bus_dmamem_free(dmat, &ixm->ixm_seg, 1); 3637 1.1 yamaguch destroy: 3638 1.1 yamaguch bus_dmamap_destroy(dmat, ixm->ixm_map); 3639 1.1 yamaguch return 1; 3640 1.1 yamaguch } 3641 1.1 yamaguch 3642 1.1 yamaguch static void 3643 1.1 yamaguch iavf_dmamem_free(bus_dma_tag_t dmat, struct ixl_dmamem *ixm) 3644 1.1 yamaguch { 3645 1.1 yamaguch 3646 1.1 yamaguch bus_dmamap_unload(dmat, ixm->ixm_map); 3647 1.1 yamaguch bus_dmamem_unmap(dmat, ixm->ixm_kva, ixm->ixm_size); 3648 1.1 yamaguch bus_dmamem_free(dmat, &ixm->ixm_seg, 1); 3649 1.1 yamaguch bus_dmamap_destroy(dmat, ixm->ixm_map); 3650 1.1 yamaguch } 3651 1.1 yamaguch 3652 1.1 yamaguch static struct ixl_aq_buf * 3653 1.1 yamaguch iavf_aqb_alloc(bus_dma_tag_t dmat, size_t buflen) 3654 1.1 yamaguch { 3655 1.1 yamaguch struct ixl_aq_buf *aqb; 3656 1.1 yamaguch 3657 1.1 yamaguch aqb = kmem_alloc(sizeof(*aqb), KM_NOSLEEP); 3658 1.1 yamaguch if (aqb == NULL) 3659 1.1 yamaguch return NULL; 3660 1.1 yamaguch 3661 1.1 yamaguch aqb->aqb_size = buflen; 3662 1.1 yamaguch 3663 1.1 yamaguch if (bus_dmamap_create(dmat, aqb->aqb_size, 1, 3664 1.1 yamaguch aqb->aqb_size, 0, 3665 1.1 yamaguch BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &aqb->aqb_map) != 0) 3666 1.1 yamaguch goto free; 3667 1.1 yamaguch if (bus_dmamem_alloc(dmat, aqb->aqb_size, 3668 1.1 yamaguch IAVF_AQ_ALIGN, 0, &aqb->aqb_seg, 1, &aqb->aqb_nsegs, 3669 1.1 yamaguch BUS_DMA_WAITOK) != 0) 3670 1.1 yamaguch goto destroy; 3671 1.1 yamaguch if (bus_dmamem_map(dmat, &aqb->aqb_seg, aqb->aqb_nsegs, 3672 1.1 yamaguch aqb->aqb_size, &aqb->aqb_data, BUS_DMA_WAITOK) != 0) 3673 1.1 yamaguch goto dma_free; 3674 1.1 yamaguch if (bus_dmamap_load(dmat, aqb->aqb_map, aqb->aqb_data, 3675 1.1 yamaguch aqb->aqb_size, NULL, BUS_DMA_WAITOK) != 0) 3676 1.1 yamaguch goto unmap; 3677 1.1 yamaguch 3678 1.1 yamaguch return aqb; 3679 1.1 yamaguch unmap: 3680 1.1 yamaguch bus_dmamem_unmap(dmat, aqb->aqb_data, aqb->aqb_size); 3681 1.1 yamaguch dma_free: 3682 1.1 yamaguch bus_dmamem_free(dmat, &aqb->aqb_seg, 1); 3683 1.1 yamaguch destroy: 3684 1.1 yamaguch bus_dmamap_destroy(dmat, aqb->aqb_map); 3685 1.1 yamaguch free: 3686 1.1 yamaguch kmem_free(aqb, sizeof(*aqb)); 3687 1.1 yamaguch 3688 1.1 yamaguch return NULL; 3689 1.1 yamaguch } 3690 1.1 yamaguch 3691 1.1 yamaguch static void 3692 1.1 yamaguch iavf_aqb_free(bus_dma_tag_t dmat, struct ixl_aq_buf *aqb) 3693 1.1 yamaguch { 3694 1.1 yamaguch 3695 1.1 yamaguch bus_dmamap_unload(dmat, aqb->aqb_map); 3696 1.1 yamaguch bus_dmamem_unmap(dmat, aqb->aqb_data, aqb->aqb_size); 3697 1.1 yamaguch bus_dmamem_free(dmat, &aqb->aqb_seg, 1); 3698 1.1 yamaguch bus_dmamap_destroy(dmat, aqb->aqb_map); 3699 1.1 yamaguch kmem_free(aqb, sizeof(*aqb)); 3700 1.1 yamaguch } 3701 1.1 yamaguch 3702 1.1 yamaguch static struct ixl_aq_buf * 3703 1.1 yamaguch iavf_aqb_get_locked(struct ixl_aq_bufs *q) 3704 1.1 yamaguch { 3705 1.1 yamaguch struct ixl_aq_buf *aqb; 3706 1.1 yamaguch 3707 1.1 yamaguch aqb = SIMPLEQ_FIRST(q); 3708 1.1 yamaguch if (aqb != NULL) { 3709 1.1 yamaguch SIMPLEQ_REMOVE(q, aqb, ixl_aq_buf, aqb_entry); 3710 1.1 yamaguch } 3711 1.1 yamaguch 3712 1.1 yamaguch return aqb; 3713 1.1 yamaguch } 3714 1.1 yamaguch 3715 1.1 yamaguch static struct ixl_aq_buf * 3716 1.1 yamaguch iavf_aqb_get(struct iavf_softc *sc, struct ixl_aq_bufs *q) 3717 1.1 yamaguch { 3718 1.1 yamaguch struct ixl_aq_buf *aqb; 3719 1.1 yamaguch 3720 1.1 yamaguch if (q != NULL) { 3721 1.1 yamaguch mutex_enter(&sc->sc_adminq_lock); 3722 1.1 yamaguch aqb = iavf_aqb_get_locked(q); 3723 1.1 yamaguch mutex_exit(&sc->sc_adminq_lock); 3724 1.1 yamaguch } else { 3725 1.1 yamaguch aqb = NULL; 3726 1.1 yamaguch } 3727 1.1 yamaguch 3728 1.1 yamaguch if (aqb == NULL) { 3729 1.1 yamaguch aqb = iavf_aqb_alloc(sc->sc_dmat, IAVF_AQ_BUFLEN); 3730 1.1 yamaguch } 3731 1.1 yamaguch 3732 1.1 yamaguch return aqb; 3733 1.1 yamaguch } 3734 1.1 yamaguch 3735 1.1 yamaguch static void 3736 1.1 yamaguch iavf_aqb_put_locked(struct ixl_aq_bufs *q, struct ixl_aq_buf *aqb) 3737 1.1 yamaguch { 3738 1.1 yamaguch 3739 1.1 yamaguch SIMPLEQ_INSERT_TAIL(q, aqb, aqb_entry); 3740 1.1 yamaguch } 3741 1.1 yamaguch 3742 1.1 yamaguch static void 3743 1.1 yamaguch iavf_aqb_clean(struct ixl_aq_bufs *q, bus_dma_tag_t dmat) 3744 1.1 yamaguch { 3745 1.1 yamaguch struct ixl_aq_buf *aqb; 3746 1.1 yamaguch 3747 1.1 yamaguch while ((aqb = SIMPLEQ_FIRST(q)) != NULL) { 3748 1.1 yamaguch SIMPLEQ_REMOVE(q, aqb, ixl_aq_buf, aqb_entry); 3749 1.1 yamaguch iavf_aqb_free(dmat, aqb); 3750 1.1 yamaguch } 3751 1.1 yamaguch } 3752 1.1 yamaguch 3753 1.1 yamaguch static const char * 3754 1.1 yamaguch iavf_aq_vc_opcode_str(const struct ixl_aq_desc *iaq) 3755 1.1 yamaguch { 3756 1.1 yamaguch 3757 1.1 yamaguch switch (iavf_aq_vc_get_opcode(iaq)) { 3758 1.1 yamaguch case IAVF_VC_OP_VERSION: 3759 1.1 yamaguch return "GET_VERSION"; 3760 1.1 yamaguch case IAVF_VC_OP_RESET_VF: 3761 1.1 yamaguch return "RESET_VF"; 3762 1.1 yamaguch case IAVF_VC_OP_GET_VF_RESOURCES: 3763 1.1 yamaguch return "GET_VF_RESOURCES"; 3764 1.1 yamaguch case IAVF_VC_OP_CONFIG_TX_QUEUE: 3765 1.1 yamaguch return "CONFIG_TX_QUEUE"; 3766 1.1 yamaguch case IAVF_VC_OP_CONFIG_RX_QUEUE: 3767 1.1 yamaguch return "CONFIG_RX_QUEUE"; 3768 1.1 yamaguch case IAVF_VC_OP_CONFIG_VSI_QUEUES: 3769 1.1 yamaguch return "CONFIG_VSI_QUEUES"; 3770 1.1 yamaguch case IAVF_VC_OP_CONFIG_IRQ_MAP: 3771 1.1 yamaguch return "CONFIG_IRQ_MAP"; 3772 1.1 yamaguch case IAVF_VC_OP_ENABLE_QUEUES: 3773 1.1 yamaguch return "ENABLE_QUEUES"; 3774 1.1 yamaguch case IAVF_VC_OP_DISABLE_QUEUES: 3775 1.1 yamaguch return "DISABLE_QUEUES"; 3776 1.1 yamaguch case IAVF_VC_OP_ADD_ETH_ADDR: 3777 1.1 yamaguch return "ADD_ETH_ADDR"; 3778 1.1 yamaguch case IAVF_VC_OP_DEL_ETH_ADDR: 3779 1.1 yamaguch return "DEL_ETH_ADDR"; 3780 1.1 yamaguch case IAVF_VC_OP_CONFIG_PROMISC: 3781 1.1 yamaguch return "CONFIG_PROMISC"; 3782 1.1 yamaguch case IAVF_VC_OP_GET_STATS: 3783 1.1 yamaguch return "GET_STATS"; 3784 1.1 yamaguch case IAVF_VC_OP_EVENT: 3785 1.1 yamaguch return "EVENT"; 3786 1.1 yamaguch case IAVF_VC_OP_CONFIG_RSS_KEY: 3787 1.1 yamaguch return "CONFIG_RSS_KEY"; 3788 1.11 yamaguch case IAVF_VC_OP_CONFIG_RSS_LUT: 3789 1.11 yamaguch return "CONFIG_RSS_LUT"; 3790 1.1 yamaguch case IAVF_VC_OP_GET_RSS_HENA_CAPS: 3791 1.1 yamaguch return "GET_RS_HENA_CAPS"; 3792 1.1 yamaguch case IAVF_VC_OP_SET_RSS_HENA: 3793 1.1 yamaguch return "SET_RSS_HENA"; 3794 1.1 yamaguch case IAVF_VC_OP_ENABLE_VLAN_STRIP: 3795 1.1 yamaguch return "ENABLE_VLAN_STRIPPING"; 3796 1.1 yamaguch case IAVF_VC_OP_DISABLE_VLAN_STRIP: 3797 1.1 yamaguch return "DISABLE_VLAN_STRIPPING"; 3798 1.1 yamaguch case IAVF_VC_OP_REQUEST_QUEUES: 3799 1.1 yamaguch return "REQUEST_QUEUES"; 3800 1.1 yamaguch } 3801 1.1 yamaguch 3802 1.1 yamaguch return "unknown"; 3803 1.1 yamaguch } 3804 1.1 yamaguch 3805 1.1 yamaguch static void 3806 1.1 yamaguch iavf_aq_dump(const struct iavf_softc *sc, const struct ixl_aq_desc *iaq, 3807 1.1 yamaguch const char *msg) 3808 1.1 yamaguch { 3809 1.1 yamaguch char buf[512]; 3810 1.1 yamaguch size_t len; 3811 1.1 yamaguch 3812 1.1 yamaguch len = sizeof(buf); 3813 1.1 yamaguch buf[--len] = '\0'; 3814 1.1 yamaguch 3815 1.1 yamaguch device_printf(sc->sc_dev, "%s\n", msg); 3816 1.1 yamaguch snprintb(buf, len, IXL_AQ_FLAGS_FMT, le16toh(iaq->iaq_flags)); 3817 1.1 yamaguch device_printf(sc->sc_dev, "flags %s opcode %04x\n", 3818 1.1 yamaguch buf, le16toh(iaq->iaq_opcode)); 3819 1.1 yamaguch device_printf(sc->sc_dev, "datalen %u retval %u\n", 3820 1.1 yamaguch le16toh(iaq->iaq_datalen), le16toh(iaq->iaq_retval)); 3821 1.1 yamaguch device_printf(sc->sc_dev, "vc-opcode %u (%s)\n", 3822 1.1 yamaguch iavf_aq_vc_get_opcode(iaq), 3823 1.1 yamaguch iavf_aq_vc_opcode_str(iaq)); 3824 1.1 yamaguch device_printf(sc->sc_dev, "vc-retval %u\n", 3825 1.1 yamaguch iavf_aq_vc_get_retval(iaq)); 3826 1.1 yamaguch device_printf(sc->sc_dev, "cookie %016" PRIx64 "\n", iaq->iaq_cookie); 3827 1.1 yamaguch device_printf(sc->sc_dev, "%08x %08x %08x %08x\n", 3828 1.1 yamaguch le32toh(iaq->iaq_param[0]), le32toh(iaq->iaq_param[1]), 3829 1.1 yamaguch le32toh(iaq->iaq_param[2]), le32toh(iaq->iaq_param[3])); 3830 1.1 yamaguch } 3831 1.1 yamaguch 3832 1.1 yamaguch static int 3833 1.1 yamaguch iavf_arq_fill(struct iavf_softc *sc) 3834 1.1 yamaguch { 3835 1.1 yamaguch struct ixl_aq_buf *aqb; 3836 1.1 yamaguch struct ixl_aq_desc *arq, *iaq; 3837 1.1 yamaguch unsigned int prod = sc->sc_arq_prod; 3838 1.1 yamaguch unsigned int n; 3839 1.1 yamaguch int filled; 3840 1.1 yamaguch 3841 1.1 yamaguch n = ixl_rxr_unrefreshed(sc->sc_arq_prod, sc->sc_arq_cons, 3842 1.1 yamaguch IAVF_AQ_NUM); 3843 1.1 yamaguch 3844 1.1 yamaguch if (__predict_false(n <= 0)) 3845 1.1 yamaguch return 0; 3846 1.1 yamaguch 3847 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq), 3848 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_arq), 3849 1.1 yamaguch BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 3850 1.1 yamaguch 3851 1.1 yamaguch arq = IXL_DMA_KVA(&sc->sc_arq); 3852 1.1 yamaguch 3853 1.1 yamaguch do { 3854 1.1 yamaguch iaq = &arq[prod]; 3855 1.1 yamaguch 3856 1.1 yamaguch if (ixl_aq_has_dva(iaq)) { 3857 1.1 yamaguch /* already filled */ 3858 1.1 yamaguch break; 3859 1.1 yamaguch } 3860 1.1 yamaguch 3861 1.1 yamaguch aqb = iavf_aqb_get_locked(&sc->sc_arq_idle); 3862 1.1 yamaguch if (aqb == NULL) 3863 1.1 yamaguch break; 3864 1.1 yamaguch 3865 1.1 yamaguch memset(aqb->aqb_data, 0, aqb->aqb_size); 3866 1.1 yamaguch 3867 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0, 3868 1.1 yamaguch aqb->aqb_size, BUS_DMASYNC_PREREAD); 3869 1.1 yamaguch 3870 1.1 yamaguch iaq->iaq_flags = htole16(IXL_AQ_BUF | 3871 1.1 yamaguch (aqb->aqb_size > I40E_AQ_LARGE_BUF ? 3872 1.1 yamaguch IXL_AQ_LB : 0)); 3873 1.1 yamaguch iaq->iaq_opcode = 0; 3874 1.1 yamaguch iaq->iaq_datalen = htole16(aqb->aqb_size); 3875 1.1 yamaguch iaq->iaq_retval = 0; 3876 1.1 yamaguch iaq->iaq_cookie = 0; 3877 1.1 yamaguch iaq->iaq_param[0] = 0; 3878 1.1 yamaguch iaq->iaq_param[1] = 0; 3879 1.1 yamaguch ixl_aq_dva(iaq, IXL_AQB_DVA(aqb)); 3880 1.1 yamaguch iavf_aqb_put_locked(&sc->sc_arq_live, aqb); 3881 1.1 yamaguch 3882 1.1 yamaguch prod++; 3883 1.1 yamaguch prod &= IAVF_AQ_MASK; 3884 1.1 yamaguch filled = 1; 3885 1.1 yamaguch } while (--n); 3886 1.1 yamaguch 3887 1.1 yamaguch sc->sc_arq_prod = prod; 3888 1.1 yamaguch 3889 1.1 yamaguch if (filled) { 3890 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq), 3891 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_arq), 3892 1.1 yamaguch BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 3893 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->arq_tail, sc->sc_arq_prod); 3894 1.1 yamaguch } 3895 1.1 yamaguch 3896 1.1 yamaguch return filled; 3897 1.1 yamaguch } 3898 1.1 yamaguch 3899 1.1 yamaguch static int 3900 1.1 yamaguch iavf_arq_wait(struct iavf_softc *sc, uint32_t opcode) 3901 1.1 yamaguch { 3902 1.1 yamaguch int error; 3903 1.1 yamaguch 3904 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_adminq_lock)); 3905 1.1 yamaguch 3906 1.1 yamaguch while ((error = cv_timedwait(&sc->sc_adminq_cv, 3907 1.1 yamaguch &sc->sc_adminq_lock, mstohz(IAVF_EXEC_TIMEOUT))) == 0) { 3908 1.1 yamaguch if (opcode == sc->sc_arq_opcode) 3909 1.1 yamaguch break; 3910 1.1 yamaguch } 3911 1.1 yamaguch 3912 1.1 yamaguch if (error != 0 && 3913 1.1 yamaguch atomic_load_relaxed(&sc->sc_debuglevel) >= 2) 3914 1.1 yamaguch device_printf(sc->sc_dev, "cv_timedwait error=%d\n", error); 3915 1.1 yamaguch 3916 1.1 yamaguch return error; 3917 1.1 yamaguch } 3918 1.1 yamaguch 3919 1.1 yamaguch static void 3920 1.1 yamaguch iavf_arq_refill(void *xsc) 3921 1.1 yamaguch { 3922 1.1 yamaguch struct iavf_softc *sc = xsc; 3923 1.1 yamaguch struct ixl_aq_bufs aqbs; 3924 1.1 yamaguch struct ixl_aq_buf *aqb; 3925 1.1 yamaguch unsigned int n, i; 3926 1.1 yamaguch 3927 1.1 yamaguch mutex_enter(&sc->sc_adminq_lock); 3928 1.1 yamaguch iavf_arq_fill(sc); 3929 1.1 yamaguch n = ixl_rxr_unrefreshed(sc->sc_arq_prod, sc->sc_arq_cons, 3930 1.1 yamaguch IAVF_AQ_NUM); 3931 1.1 yamaguch mutex_exit(&sc->sc_adminq_lock); 3932 1.1 yamaguch 3933 1.1 yamaguch if (n == 0) 3934 1.1 yamaguch return; 3935 1.1 yamaguch 3936 1.1 yamaguch if (atomic_load_relaxed(&sc->sc_debuglevel) >= 1) 3937 1.1 yamaguch device_printf(sc->sc_dev, "Allocate %d bufs for arq\n", n); 3938 1.1 yamaguch 3939 1.1 yamaguch SIMPLEQ_INIT(&aqbs); 3940 1.1 yamaguch for (i = 0; i < n; i++) { 3941 1.1 yamaguch aqb = iavf_aqb_get(sc, NULL); 3942 1.1 yamaguch if (aqb == NULL) 3943 1.1 yamaguch continue; 3944 1.1 yamaguch SIMPLEQ_INSERT_TAIL(&aqbs, aqb, aqb_entry); 3945 1.1 yamaguch } 3946 1.1 yamaguch 3947 1.1 yamaguch mutex_enter(&sc->sc_adminq_lock); 3948 1.1 yamaguch while ((aqb = SIMPLEQ_FIRST(&aqbs)) != NULL) { 3949 1.1 yamaguch SIMPLEQ_REMOVE(&aqbs, aqb, ixl_aq_buf, aqb_entry); 3950 1.1 yamaguch iavf_aqb_put_locked(&sc->sc_arq_idle, aqb); 3951 1.1 yamaguch } 3952 1.1 yamaguch iavf_arq_fill(sc); 3953 1.1 yamaguch mutex_exit(&sc->sc_adminq_lock); 3954 1.1 yamaguch } 3955 1.1 yamaguch 3956 1.1 yamaguch static uint32_t 3957 1.1 yamaguch iavf_process_arq(struct iavf_softc *sc, struct ixl_aq_desc *iaq, 3958 1.1 yamaguch struct ixl_aq_buf *aqb) 3959 1.1 yamaguch { 3960 1.1 yamaguch uint32_t vc_retval, vc_opcode; 3961 1.1 yamaguch int dbg; 3962 1.1 yamaguch 3963 1.1 yamaguch dbg = atomic_load_relaxed(&sc->sc_debuglevel); 3964 1.1 yamaguch if (dbg >= 3) 3965 1.1 yamaguch iavf_aq_dump(sc, iaq, "arq proc"); 3966 1.1 yamaguch 3967 1.1 yamaguch if (dbg >= 2) { 3968 1.1 yamaguch vc_retval = iavf_aq_vc_get_retval(iaq); 3969 1.1 yamaguch if (vc_retval != IAVF_VC_RC_SUCCESS) { 3970 1.1 yamaguch device_printf(sc->sc_dev, "%s failed=%d(arq)\n", 3971 1.1 yamaguch iavf_aq_vc_opcode_str(iaq), vc_retval); 3972 1.1 yamaguch } 3973 1.1 yamaguch } 3974 1.1 yamaguch 3975 1.1 yamaguch vc_opcode = iavf_aq_vc_get_opcode(iaq); 3976 1.1 yamaguch switch (vc_opcode) { 3977 1.1 yamaguch case IAVF_VC_OP_VERSION: 3978 1.1 yamaguch iavf_process_version(sc, iaq, aqb); 3979 1.1 yamaguch break; 3980 1.1 yamaguch case IAVF_VC_OP_GET_VF_RESOURCES: 3981 1.1 yamaguch iavf_process_vf_resources(sc, iaq, aqb); 3982 1.1 yamaguch break; 3983 1.1 yamaguch case IAVF_VC_OP_CONFIG_IRQ_MAP: 3984 1.1 yamaguch iavf_process_irq_map(sc, iaq); 3985 1.1 yamaguch break; 3986 1.1 yamaguch case IAVF_VC_OP_EVENT: 3987 1.1 yamaguch iavf_process_vc_event(sc, iaq, aqb); 3988 1.1 yamaguch break; 3989 1.1 yamaguch case IAVF_VC_OP_GET_STATS: 3990 1.1 yamaguch iavf_process_stats(sc, iaq, aqb); 3991 1.1 yamaguch break; 3992 1.1 yamaguch case IAVF_VC_OP_REQUEST_QUEUES: 3993 1.1 yamaguch iavf_process_req_queues(sc, iaq, aqb); 3994 1.1 yamaguch break; 3995 1.1 yamaguch } 3996 1.1 yamaguch 3997 1.1 yamaguch return vc_opcode; 3998 1.1 yamaguch } 3999 1.1 yamaguch 4000 1.1 yamaguch static int 4001 1.1 yamaguch iavf_arq_poll(struct iavf_softc *sc, uint32_t wait_opcode, int retry) 4002 1.1 yamaguch { 4003 1.1 yamaguch struct ixl_aq_desc *arq, *iaq; 4004 1.1 yamaguch struct ixl_aq_buf *aqb; 4005 1.1 yamaguch unsigned int cons = sc->sc_arq_cons; 4006 1.1 yamaguch unsigned int prod; 4007 1.1 yamaguch uint32_t vc_opcode; 4008 1.1 yamaguch bool received; 4009 1.1 yamaguch int i; 4010 1.1 yamaguch 4011 1.1 yamaguch for (i = 0, received = false; i < retry && !received; i++) { 4012 1.1 yamaguch prod = iavf_rd(sc, sc->sc_aq_regs->arq_head); 4013 1.1 yamaguch prod &= sc->sc_aq_regs->arq_head_mask; 4014 1.1 yamaguch 4015 1.1 yamaguch if (prod == cons) { 4016 1.1 yamaguch delaymsec(1); 4017 1.1 yamaguch continue; 4018 1.1 yamaguch } 4019 1.1 yamaguch 4020 1.1 yamaguch if (prod >= IAVF_AQ_NUM) { 4021 1.1 yamaguch return EIO; 4022 1.1 yamaguch } 4023 1.1 yamaguch 4024 1.1 yamaguch arq = IXL_DMA_KVA(&sc->sc_arq); 4025 1.1 yamaguch 4026 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq), 4027 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_arq), 4028 1.1 yamaguch BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 4029 1.1 yamaguch 4030 1.1 yamaguch do { 4031 1.1 yamaguch iaq = &arq[cons]; 4032 1.1 yamaguch aqb = iavf_aqb_get_locked(&sc->sc_arq_live); 4033 1.1 yamaguch KASSERT(aqb != NULL); 4034 1.1 yamaguch 4035 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0, 4036 1.1 yamaguch IAVF_AQ_BUFLEN, BUS_DMASYNC_POSTREAD); 4037 1.1 yamaguch 4038 1.1 yamaguch vc_opcode = iavf_process_arq(sc, iaq, aqb); 4039 1.1 yamaguch 4040 1.1 yamaguch if (vc_opcode == wait_opcode) 4041 1.1 yamaguch received = true; 4042 1.1 yamaguch 4043 1.1 yamaguch memset(iaq, 0, sizeof(*iaq)); 4044 1.1 yamaguch iavf_aqb_put_locked(&sc->sc_arq_idle, aqb); 4045 1.1 yamaguch 4046 1.1 yamaguch cons++; 4047 1.1 yamaguch cons &= IAVF_AQ_MASK; 4048 1.1 yamaguch 4049 1.1 yamaguch } while (cons != prod); 4050 1.1 yamaguch 4051 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq), 4052 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_arq), 4053 1.1 yamaguch BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 4054 1.1 yamaguch 4055 1.1 yamaguch sc->sc_arq_cons = cons; 4056 1.1 yamaguch iavf_arq_fill(sc); 4057 1.1 yamaguch 4058 1.1 yamaguch } 4059 1.1 yamaguch 4060 1.1 yamaguch if (!received) 4061 1.1 yamaguch return ETIMEDOUT; 4062 1.1 yamaguch 4063 1.1 yamaguch return 0; 4064 1.1 yamaguch } 4065 1.1 yamaguch 4066 1.1 yamaguch static int 4067 1.1 yamaguch iavf_arq(struct iavf_softc *sc) 4068 1.1 yamaguch { 4069 1.1 yamaguch struct ixl_aq_desc *arq, *iaq; 4070 1.1 yamaguch struct ixl_aq_buf *aqb; 4071 1.1 yamaguch unsigned int cons = sc->sc_arq_cons; 4072 1.1 yamaguch unsigned int prod; 4073 1.1 yamaguch uint32_t vc_opcode; 4074 1.1 yamaguch 4075 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_adminq_lock)); 4076 1.1 yamaguch 4077 1.1 yamaguch prod = iavf_rd(sc, sc->sc_aq_regs->arq_head); 4078 1.1 yamaguch prod &= sc->sc_aq_regs->arq_head_mask; 4079 1.1 yamaguch 4080 1.1 yamaguch /* broken value at resetting */ 4081 1.1 yamaguch if (prod >= IAVF_AQ_NUM) { 4082 1.1 yamaguch iavf_work_set(&sc->sc_reset_task, iavf_reset_start, sc); 4083 1.1 yamaguch iavf_work_add(sc->sc_workq, &sc->sc_reset_task); 4084 1.1 yamaguch return 0; 4085 1.1 yamaguch } 4086 1.1 yamaguch 4087 1.1 yamaguch if (cons == prod) 4088 1.1 yamaguch return 0; 4089 1.1 yamaguch 4090 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq), 4091 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_arq), 4092 1.1 yamaguch BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 4093 1.1 yamaguch 4094 1.1 yamaguch arq = IXL_DMA_KVA(&sc->sc_arq); 4095 1.1 yamaguch 4096 1.1 yamaguch do { 4097 1.1 yamaguch iaq = &arq[cons]; 4098 1.1 yamaguch aqb = iavf_aqb_get_locked(&sc->sc_arq_live); 4099 1.1 yamaguch 4100 1.1 yamaguch KASSERT(aqb != NULL); 4101 1.1 yamaguch 4102 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0, IAVF_AQ_BUFLEN, 4103 1.1 yamaguch BUS_DMASYNC_POSTREAD); 4104 1.1 yamaguch 4105 1.1 yamaguch vc_opcode = iavf_process_arq(sc, iaq, aqb); 4106 1.1 yamaguch 4107 1.1 yamaguch switch (vc_opcode) { 4108 1.1 yamaguch case IAVF_VC_OP_CONFIG_TX_QUEUE: 4109 1.1 yamaguch case IAVF_VC_OP_CONFIG_RX_QUEUE: 4110 1.1 yamaguch case IAVF_VC_OP_CONFIG_VSI_QUEUES: 4111 1.1 yamaguch case IAVF_VC_OP_ENABLE_QUEUES: 4112 1.1 yamaguch case IAVF_VC_OP_DISABLE_QUEUES: 4113 1.1 yamaguch case IAVF_VC_OP_GET_RSS_HENA_CAPS: 4114 1.1 yamaguch case IAVF_VC_OP_SET_RSS_HENA: 4115 1.1 yamaguch case IAVF_VC_OP_ADD_ETH_ADDR: 4116 1.1 yamaguch case IAVF_VC_OP_DEL_ETH_ADDR: 4117 1.1 yamaguch case IAVF_VC_OP_CONFIG_PROMISC: 4118 1.1 yamaguch case IAVF_VC_OP_ADD_VLAN: 4119 1.1 yamaguch case IAVF_VC_OP_DEL_VLAN: 4120 1.1 yamaguch case IAVF_VC_OP_ENABLE_VLAN_STRIP: 4121 1.1 yamaguch case IAVF_VC_OP_DISABLE_VLAN_STRIP: 4122 1.1 yamaguch case IAVF_VC_OP_CONFIG_RSS_KEY: 4123 1.1 yamaguch case IAVF_VC_OP_CONFIG_RSS_LUT: 4124 1.1 yamaguch sc->sc_arq_retval = iavf_aq_vc_get_retval(iaq); 4125 1.1 yamaguch sc->sc_arq_opcode = vc_opcode; 4126 1.1 yamaguch cv_signal(&sc->sc_adminq_cv); 4127 1.1 yamaguch break; 4128 1.1 yamaguch } 4129 1.1 yamaguch 4130 1.1 yamaguch memset(iaq, 0, sizeof(*iaq)); 4131 1.1 yamaguch iavf_aqb_put_locked(&sc->sc_arq_idle, aqb); 4132 1.1 yamaguch 4133 1.1 yamaguch cons++; 4134 1.1 yamaguch cons &= IAVF_AQ_MASK; 4135 1.1 yamaguch } while (cons != prod); 4136 1.1 yamaguch 4137 1.1 yamaguch sc->sc_arq_cons = cons; 4138 1.1 yamaguch iavf_work_add(sc->sc_workq, &sc->sc_arq_refill); 4139 1.1 yamaguch 4140 1.1 yamaguch return 1; 4141 1.1 yamaguch } 4142 1.1 yamaguch 4143 1.1 yamaguch static int 4144 1.1 yamaguch iavf_atq_post(struct iavf_softc *sc, struct ixl_aq_desc *iaq, 4145 1.1 yamaguch struct ixl_aq_buf *aqb) 4146 1.1 yamaguch { 4147 1.1 yamaguch struct ixl_aq_desc *atq, *slot; 4148 1.1 yamaguch unsigned int prod; 4149 1.1 yamaguch 4150 1.1 yamaguch atq = IXL_DMA_KVA(&sc->sc_atq); 4151 1.1 yamaguch prod = sc->sc_atq_prod; 4152 1.1 yamaguch slot = &atq[prod]; 4153 1.1 yamaguch 4154 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 4155 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_POSTWRITE); 4156 1.1 yamaguch 4157 1.1 yamaguch *slot = *iaq; 4158 1.1 yamaguch slot->iaq_flags |= htole16(IXL_AQ_SI); 4159 1.1 yamaguch if (aqb != NULL) { 4160 1.1 yamaguch ixl_aq_dva(slot, IXL_AQB_DVA(aqb)); 4161 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_AQB_MAP(aqb), 4162 1.1 yamaguch 0, IXL_AQB_LEN(aqb), BUS_DMASYNC_PREWRITE); 4163 1.1 yamaguch iavf_aqb_put_locked(&sc->sc_atq_live, aqb); 4164 1.1 yamaguch } else { 4165 1.1 yamaguch ixl_aq_dva(slot, (bus_addr_t)0); 4166 1.1 yamaguch } 4167 1.1 yamaguch 4168 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 4169 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_PREWRITE); 4170 1.1 yamaguch 4171 1.1 yamaguch if (atomic_load_relaxed(&sc->sc_debuglevel) >= 3) 4172 1.1 yamaguch iavf_aq_dump(sc, slot, "post"); 4173 1.1 yamaguch 4174 1.1 yamaguch prod++; 4175 1.1 yamaguch prod &= IAVF_AQ_MASK; 4176 1.1 yamaguch sc->sc_atq_prod = prod; 4177 1.1 yamaguch iavf_wr(sc, sc->sc_aq_regs->atq_tail, prod); 4178 1.1 yamaguch return prod; 4179 1.1 yamaguch } 4180 1.1 yamaguch 4181 1.1 yamaguch static int 4182 1.1 yamaguch iavf_atq_poll(struct iavf_softc *sc, unsigned int tm) 4183 1.1 yamaguch { 4184 1.1 yamaguch struct ixl_aq_desc *atq, *slot; 4185 1.1 yamaguch struct ixl_aq_desc iaq; 4186 1.1 yamaguch unsigned int prod; 4187 1.1 yamaguch unsigned int t; 4188 1.1 yamaguch int dbg; 4189 1.1 yamaguch 4190 1.1 yamaguch dbg = atomic_load_relaxed(&sc->sc_debuglevel); 4191 1.1 yamaguch atq = IXL_DMA_KVA(&sc->sc_atq); 4192 1.1 yamaguch prod = sc->sc_atq_prod; 4193 1.1 yamaguch slot = &atq[prod]; 4194 1.1 yamaguch t = 0; 4195 1.1 yamaguch 4196 1.1 yamaguch while (iavf_rd(sc, sc->sc_aq_regs->atq_head) != prod) { 4197 1.1 yamaguch delaymsec(1); 4198 1.1 yamaguch 4199 1.1 yamaguch if (t++ > tm) { 4200 1.1 yamaguch if (dbg >= 2) { 4201 1.1 yamaguch device_printf(sc->sc_dev, 4202 1.1 yamaguch "atq timedout\n"); 4203 1.1 yamaguch } 4204 1.1 yamaguch return ETIMEDOUT; 4205 1.1 yamaguch } 4206 1.1 yamaguch } 4207 1.1 yamaguch 4208 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 4209 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_POSTREAD); 4210 1.1 yamaguch iaq = *slot; 4211 1.1 yamaguch memset(slot, 0, sizeof(*slot)); 4212 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 4213 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_PREREAD); 4214 1.1 yamaguch 4215 1.1 yamaguch if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK)) { 4216 1.1 yamaguch if (dbg >= 2) { 4217 1.1 yamaguch device_printf(sc->sc_dev, 4218 1.1 yamaguch "atq retcode=0x%04x\n", le16toh(iaq.iaq_retval)); 4219 1.1 yamaguch } 4220 1.1 yamaguch return EIO; 4221 1.1 yamaguch } 4222 1.1 yamaguch 4223 1.1 yamaguch return 0; 4224 1.1 yamaguch } 4225 1.1 yamaguch 4226 1.1 yamaguch static void 4227 1.1 yamaguch iavf_atq_done(struct iavf_softc *sc) 4228 1.1 yamaguch { 4229 1.1 yamaguch struct ixl_aq_desc *atq, *slot; 4230 1.1 yamaguch struct ixl_aq_buf *aqb; 4231 1.1 yamaguch unsigned int cons; 4232 1.1 yamaguch unsigned int prod; 4233 1.1 yamaguch 4234 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_adminq_lock)); 4235 1.1 yamaguch 4236 1.1 yamaguch prod = sc->sc_atq_prod; 4237 1.1 yamaguch cons = sc->sc_atq_cons; 4238 1.1 yamaguch 4239 1.1 yamaguch if (prod == cons) 4240 1.1 yamaguch return; 4241 1.1 yamaguch 4242 1.1 yamaguch atq = IXL_DMA_KVA(&sc->sc_atq); 4243 1.1 yamaguch 4244 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 4245 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), 4246 1.1 yamaguch BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 4247 1.1 yamaguch 4248 1.1 yamaguch do { 4249 1.1 yamaguch slot = &atq[cons]; 4250 1.1 yamaguch if (!ISSET(slot->iaq_flags, htole16(IXL_AQ_DD))) 4251 1.1 yamaguch break; 4252 1.1 yamaguch 4253 1.1 yamaguch if (ixl_aq_has_dva(slot) && 4254 1.1 yamaguch (aqb = iavf_aqb_get_locked(&sc->sc_atq_live)) != NULL) { 4255 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_AQB_MAP(aqb), 4256 1.1 yamaguch 0, IXL_AQB_LEN(aqb), BUS_DMASYNC_POSTWRITE); 4257 1.1 yamaguch iavf_aqb_put_locked(&sc->sc_atq_idle, aqb); 4258 1.1 yamaguch } 4259 1.1 yamaguch 4260 1.1 yamaguch memset(slot, 0, sizeof(*slot)); 4261 1.1 yamaguch 4262 1.1 yamaguch cons++; 4263 1.1 yamaguch cons &= IAVF_AQ_MASK; 4264 1.1 yamaguch } while (cons != prod); 4265 1.1 yamaguch 4266 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 4267 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), 4268 1.1 yamaguch BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 4269 1.1 yamaguch 4270 1.1 yamaguch sc->sc_atq_cons = cons; 4271 1.1 yamaguch } 4272 1.1 yamaguch 4273 1.1 yamaguch static int 4274 1.1 yamaguch iavf_adminq_poll(struct iavf_softc *sc, struct ixl_aq_desc *iaq, 4275 1.1 yamaguch struct ixl_aq_buf *aqb, int retry) 4276 1.1 yamaguch { 4277 1.1 yamaguch int error; 4278 1.1 yamaguch 4279 1.1 yamaguch mutex_enter(&sc->sc_adminq_lock); 4280 1.1 yamaguch error = iavf_adminq_poll_locked(sc, iaq, aqb, retry); 4281 1.1 yamaguch mutex_exit(&sc->sc_adminq_lock); 4282 1.1 yamaguch 4283 1.1 yamaguch return error; 4284 1.1 yamaguch } 4285 1.1 yamaguch 4286 1.1 yamaguch static int 4287 1.1 yamaguch iavf_adminq_poll_locked(struct iavf_softc *sc, 4288 1.1 yamaguch struct ixl_aq_desc *iaq, struct ixl_aq_buf *aqb, int retry) 4289 1.1 yamaguch { 4290 1.1 yamaguch uint32_t opcode; 4291 1.1 yamaguch int error; 4292 1.1 yamaguch 4293 1.1 yamaguch KASSERT(!sc->sc_attached || mutex_owned(&sc->sc_adminq_lock)); 4294 1.1 yamaguch 4295 1.1 yamaguch opcode = iavf_aq_vc_get_opcode(iaq); 4296 1.1 yamaguch 4297 1.1 yamaguch iavf_atq_post(sc, iaq, aqb); 4298 1.1 yamaguch 4299 1.1 yamaguch error = iavf_atq_poll(sc, retry); 4300 1.7 yamaguch 4301 1.7 yamaguch /* 4302 1.7 yamaguch * collect the aqb used in the current command and 4303 1.7 yamaguch * added to sc_atq_live at iavf_atq_post(), 4304 1.7 yamaguch * whether or not the command succeeded. 4305 1.7 yamaguch */ 4306 1.7 yamaguch if (aqb != NULL) { 4307 1.7 yamaguch (void)iavf_aqb_get_locked(&sc->sc_atq_live); 4308 1.7 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_AQB_MAP(aqb), 4309 1.7 yamaguch 0, IXL_AQB_LEN(aqb), BUS_DMASYNC_POSTWRITE); 4310 1.7 yamaguch } 4311 1.7 yamaguch 4312 1.1 yamaguch if (error) 4313 1.1 yamaguch return error; 4314 1.1 yamaguch 4315 1.1 yamaguch error = iavf_arq_poll(sc, opcode, retry); 4316 1.1 yamaguch 4317 1.1 yamaguch if (error != 0 && 4318 1.1 yamaguch atomic_load_relaxed(&sc->sc_debuglevel) >= 1) { 4319 1.1 yamaguch device_printf(sc->sc_dev, "%s failed=%d(polling)\n", 4320 1.1 yamaguch iavf_aq_vc_opcode_str(iaq), error); 4321 1.1 yamaguch } 4322 1.1 yamaguch 4323 1.1 yamaguch return error; 4324 1.1 yamaguch } 4325 1.1 yamaguch 4326 1.1 yamaguch static int 4327 1.1 yamaguch iavf_adminq_exec(struct iavf_softc *sc, struct ixl_aq_desc *iaq, 4328 1.1 yamaguch struct ixl_aq_buf *aqb) 4329 1.1 yamaguch { 4330 1.1 yamaguch int error; 4331 1.1 yamaguch uint32_t opcode; 4332 1.1 yamaguch 4333 1.1 yamaguch opcode = iavf_aq_vc_get_opcode(iaq); 4334 1.1 yamaguch 4335 1.1 yamaguch mutex_enter(&sc->sc_adminq_lock); 4336 1.1 yamaguch iavf_atq_post(sc, iaq, aqb); 4337 1.1 yamaguch 4338 1.1 yamaguch error = iavf_arq_wait(sc, opcode); 4339 1.1 yamaguch if (error == 0) { 4340 1.1 yamaguch error = sc->sc_arq_retval; 4341 1.1 yamaguch if (error != IAVF_VC_RC_SUCCESS && 4342 1.1 yamaguch atomic_load_relaxed(&sc->sc_debuglevel) >= 1) { 4343 1.1 yamaguch device_printf(sc->sc_dev, "%s failed=%d\n", 4344 1.1 yamaguch iavf_aq_vc_opcode_str(iaq), error); 4345 1.1 yamaguch } 4346 1.1 yamaguch } 4347 1.1 yamaguch 4348 1.1 yamaguch mutex_exit(&sc->sc_adminq_lock); 4349 1.1 yamaguch return error; 4350 1.1 yamaguch } 4351 1.1 yamaguch 4352 1.1 yamaguch static void 4353 1.1 yamaguch iavf_process_version(struct iavf_softc *sc, struct ixl_aq_desc *iaq, 4354 1.1 yamaguch struct ixl_aq_buf *aqb) 4355 1.1 yamaguch { 4356 1.1 yamaguch struct iavf_vc_version_info *ver; 4357 1.1 yamaguch 4358 1.1 yamaguch ver = (struct iavf_vc_version_info *)aqb->aqb_data; 4359 1.1 yamaguch sc->sc_major_ver = le32toh(ver->major); 4360 1.1 yamaguch sc->sc_minor_ver = le32toh(ver->minor); 4361 1.1 yamaguch } 4362 1.1 yamaguch 4363 1.1 yamaguch static void 4364 1.1 yamaguch iavf_process_vf_resources(struct iavf_softc *sc, struct ixl_aq_desc *iaq, 4365 1.1 yamaguch struct ixl_aq_buf *aqb) 4366 1.1 yamaguch { 4367 1.1 yamaguch struct iavf_vc_vf_resource *vf_res; 4368 1.1 yamaguch struct iavf_vc_vsi_resource *vsi_res; 4369 1.1 yamaguch uint8_t *enaddr; 4370 1.1 yamaguch int mtu, dbg; 4371 1.1 yamaguch char buf[512]; 4372 1.1 yamaguch 4373 1.1 yamaguch dbg = atomic_load_relaxed(&sc->sc_debuglevel); 4374 1.1 yamaguch sc->sc_got_vf_resources = 1; 4375 1.1 yamaguch 4376 1.1 yamaguch vf_res = aqb->aqb_data; 4377 1.1 yamaguch sc->sc_max_vectors = le16toh(vf_res->max_vectors); 4378 1.1 yamaguch if (le16toh(vf_res->num_vsis) == 0) { 4379 1.1 yamaguch if (dbg >= 1) { 4380 1.1 yamaguch device_printf(sc->sc_dev, "no vsi available\n"); 4381 1.1 yamaguch } 4382 1.1 yamaguch return; 4383 1.1 yamaguch } 4384 1.1 yamaguch sc->sc_vf_cap = le32toh(vf_res->offload_flags); 4385 1.1 yamaguch if (dbg >= 2) { 4386 1.1 yamaguch snprintb(buf, sizeof(buf), 4387 1.1 yamaguch IAVF_VC_OFFLOAD_FMT, sc->sc_vf_cap); 4388 1.1 yamaguch device_printf(sc->sc_dev, "VF cap=%s\n", buf); 4389 1.1 yamaguch } 4390 1.1 yamaguch 4391 1.1 yamaguch mtu = le16toh(vf_res->max_mtu); 4392 1.1 yamaguch if (IAVF_MIN_MTU < mtu && mtu < IAVF_MAX_MTU) { 4393 1.1 yamaguch sc->sc_max_mtu = MIN(IAVF_MAX_MTU, mtu); 4394 1.1 yamaguch } 4395 1.1 yamaguch 4396 1.1 yamaguch vsi_res = &vf_res->vsi_res[0]; 4397 1.1 yamaguch sc->sc_vsi_id = le16toh(vsi_res->vsi_id); 4398 1.1 yamaguch sc->sc_vf_id = le32toh(iaq->iaq_param[0]); 4399 1.1 yamaguch sc->sc_qset_handle = le16toh(vsi_res->qset_handle); 4400 1.1 yamaguch sc->sc_nqps_vsi = le16toh(vsi_res->num_queue_pairs); 4401 1.1 yamaguch if (!iavf_is_etheranyaddr(vsi_res->default_mac)) { 4402 1.1 yamaguch enaddr = vsi_res->default_mac; 4403 1.1 yamaguch } else { 4404 1.1 yamaguch enaddr = sc->sc_enaddr_fake; 4405 1.1 yamaguch } 4406 1.1 yamaguch memcpy(sc->sc_enaddr, enaddr, ETHER_ADDR_LEN); 4407 1.1 yamaguch } 4408 1.1 yamaguch 4409 1.1 yamaguch static void 4410 1.1 yamaguch iavf_process_irq_map(struct iavf_softc *sc, struct ixl_aq_desc *iaq) 4411 1.1 yamaguch { 4412 1.1 yamaguch uint32_t retval; 4413 1.1 yamaguch 4414 1.1 yamaguch retval = iavf_aq_vc_get_retval(iaq); 4415 1.1 yamaguch if (retval != IAVF_VC_RC_SUCCESS) { 4416 1.1 yamaguch return; 4417 1.1 yamaguch } 4418 1.1 yamaguch 4419 1.1 yamaguch sc->sc_got_irq_map = 1; 4420 1.1 yamaguch } 4421 1.1 yamaguch 4422 1.1 yamaguch static void 4423 1.1 yamaguch iavf_process_vc_event(struct iavf_softc *sc, struct ixl_aq_desc *iaq, 4424 1.1 yamaguch struct ixl_aq_buf *aqb) 4425 1.1 yamaguch { 4426 1.1 yamaguch struct iavf_vc_pf_event *event; 4427 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 4428 1.1 yamaguch const struct iavf_link_speed *speed; 4429 1.1 yamaguch int link; 4430 1.1 yamaguch 4431 1.1 yamaguch event = aqb->aqb_data; 4432 1.1 yamaguch switch (event->event) { 4433 1.1 yamaguch case IAVF_VC_EVENT_LINK_CHANGE: 4434 1.1 yamaguch sc->sc_media_status = IFM_AVALID; 4435 1.1 yamaguch sc->sc_media_active = IFM_ETHER; 4436 1.1 yamaguch link = LINK_STATE_DOWN; 4437 1.1 yamaguch if (event->link_status) { 4438 1.1 yamaguch link = LINK_STATE_UP; 4439 1.1 yamaguch sc->sc_media_status |= IFM_ACTIVE; 4440 1.13 yamaguch sc->sc_media_active |= IFM_FDX; 4441 1.1 yamaguch 4442 1.1 yamaguch ifp->if_baudrate = 0; 4443 1.1 yamaguch speed = iavf_find_link_speed(sc, event->link_speed); 4444 1.1 yamaguch if (speed != NULL) { 4445 1.1 yamaguch sc->sc_media_active |= speed->media; 4446 1.1 yamaguch ifp->if_baudrate = speed->baudrate; 4447 1.1 yamaguch } 4448 1.1 yamaguch } 4449 1.1 yamaguch 4450 1.1 yamaguch if (sc->sc_link_state != link) { 4451 1.1 yamaguch sc->sc_link_state = link; 4452 1.1 yamaguch if (sc->sc_attached) { 4453 1.1 yamaguch if_link_state_change(ifp, link); 4454 1.1 yamaguch } 4455 1.1 yamaguch } 4456 1.1 yamaguch break; 4457 1.1 yamaguch case IAVF_VC_EVENT_RESET_IMPENDING: 4458 1.1 yamaguch log(LOG_INFO, "%s: Reset warning received from the PF\n", 4459 1.1 yamaguch ifp->if_xname); 4460 1.1 yamaguch iavf_work_set(&sc->sc_reset_task, iavf_reset_request, sc); 4461 1.1 yamaguch iavf_work_add(sc->sc_workq, &sc->sc_reset_task); 4462 1.1 yamaguch break; 4463 1.1 yamaguch } 4464 1.1 yamaguch } 4465 1.1 yamaguch 4466 1.1 yamaguch static void 4467 1.1 yamaguch iavf_process_stats(struct iavf_softc *sc, struct ixl_aq_desc *iaq, 4468 1.1 yamaguch struct ixl_aq_buf *aqb) 4469 1.1 yamaguch { 4470 1.1 yamaguch struct iavf_stat_counters *isc; 4471 1.1 yamaguch struct i40e_eth_stats *st; 4472 1.1 yamaguch 4473 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_adminq_lock)); 4474 1.1 yamaguch 4475 1.1 yamaguch st = aqb->aqb_data; 4476 1.1 yamaguch isc = &sc->sc_stat_counters; 4477 1.1 yamaguch 4478 1.1 yamaguch isc->isc_rx_bytes.ev_count = st->rx_bytes; 4479 1.1 yamaguch isc->isc_rx_unicast.ev_count = st->rx_unicast; 4480 1.1 yamaguch isc->isc_rx_multicast.ev_count = st->rx_multicast; 4481 1.1 yamaguch isc->isc_rx_broadcast.ev_count = st->rx_broadcast; 4482 1.1 yamaguch isc->isc_rx_discards.ev_count = st->rx_discards; 4483 1.1 yamaguch isc->isc_rx_unknown_protocol.ev_count = st->rx_unknown_protocol; 4484 1.1 yamaguch 4485 1.1 yamaguch isc->isc_tx_bytes.ev_count = st->tx_bytes; 4486 1.1 yamaguch isc->isc_tx_unicast.ev_count = st->tx_unicast; 4487 1.1 yamaguch isc->isc_tx_multicast.ev_count = st->tx_multicast; 4488 1.1 yamaguch isc->isc_tx_broadcast.ev_count = st->tx_broadcast; 4489 1.1 yamaguch isc->isc_tx_discards.ev_count = st->tx_discards; 4490 1.1 yamaguch isc->isc_tx_errors.ev_count = st->tx_errors; 4491 1.1 yamaguch } 4492 1.1 yamaguch 4493 1.1 yamaguch static void 4494 1.1 yamaguch iavf_process_req_queues(struct iavf_softc *sc, struct ixl_aq_desc *iaq, 4495 1.1 yamaguch struct ixl_aq_buf *aqb) 4496 1.1 yamaguch { 4497 1.1 yamaguch struct iavf_vc_res_request *req; 4498 1.1 yamaguch struct ifnet *ifp; 4499 1.1 yamaguch uint32_t vc_retval; 4500 1.1 yamaguch 4501 1.1 yamaguch ifp = &sc->sc_ec.ec_if; 4502 1.1 yamaguch req = aqb->aqb_data; 4503 1.1 yamaguch 4504 1.1 yamaguch vc_retval = iavf_aq_vc_get_retval(iaq); 4505 1.1 yamaguch if (vc_retval != IAVF_VC_RC_SUCCESS) { 4506 1.1 yamaguch return; 4507 1.1 yamaguch } 4508 1.1 yamaguch 4509 1.1 yamaguch if (sc->sc_nqps_req < req->num_queue_pairs) { 4510 1.1 yamaguch log(LOG_INFO, 4511 1.1 yamaguch "%s: requested %d queues, but only %d left.\n", 4512 1.1 yamaguch ifp->if_xname, 4513 1.1 yamaguch sc->sc_nqps_req, req->num_queue_pairs); 4514 1.1 yamaguch } 4515 1.1 yamaguch 4516 1.1 yamaguch if (sc->sc_nqps_vsi < req->num_queue_pairs) { 4517 1.1 yamaguch if (!sc->sc_req_queues_retried) { 4518 1.1 yamaguch /* req->num_queue_pairs indicates max qps */ 4519 1.1 yamaguch sc->sc_nqps_req = req->num_queue_pairs; 4520 1.1 yamaguch 4521 1.1 yamaguch sc->sc_req_queues_retried = true; 4522 1.1 yamaguch iavf_work_add(sc->sc_workq, &sc->sc_req_queues_task); 4523 1.1 yamaguch } 4524 1.1 yamaguch } 4525 1.1 yamaguch } 4526 1.1 yamaguch 4527 1.1 yamaguch static int 4528 1.1 yamaguch iavf_get_version(struct iavf_softc *sc, struct ixl_aq_buf *aqb) 4529 1.1 yamaguch { 4530 1.1 yamaguch struct ixl_aq_desc iaq; 4531 1.1 yamaguch struct iavf_vc_version_info *ver; 4532 1.1 yamaguch int error; 4533 1.1 yamaguch 4534 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4535 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD); 4536 1.1 yamaguch iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF); 4537 1.1 yamaguch iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_VERSION); 4538 1.1 yamaguch iaq.iaq_datalen = htole16(sizeof(struct iavf_vc_version_info)); 4539 1.1 yamaguch 4540 1.1 yamaguch ver = IXL_AQB_KVA(aqb); 4541 1.1 yamaguch ver->major = htole32(IAVF_VF_MAJOR); 4542 1.1 yamaguch ver->minor = htole32(IAVF_VF_MINOR); 4543 1.1 yamaguch 4544 1.1 yamaguch sc->sc_major_ver = UINT_MAX; 4545 1.1 yamaguch sc->sc_minor_ver = UINT_MAX; 4546 1.1 yamaguch 4547 1.1 yamaguch if (sc->sc_attached) { 4548 1.1 yamaguch error = iavf_adminq_poll(sc, &iaq, aqb, 250); 4549 1.1 yamaguch } else { 4550 1.1 yamaguch error = iavf_adminq_poll_locked(sc, &iaq, aqb, 250); 4551 1.1 yamaguch } 4552 1.1 yamaguch 4553 1.1 yamaguch if (error) 4554 1.1 yamaguch return -1; 4555 1.1 yamaguch 4556 1.1 yamaguch return 0; 4557 1.1 yamaguch } 4558 1.1 yamaguch 4559 1.1 yamaguch static int 4560 1.1 yamaguch iavf_get_vf_resources(struct iavf_softc *sc, struct ixl_aq_buf *aqb) 4561 1.1 yamaguch { 4562 1.1 yamaguch struct ixl_aq_desc iaq; 4563 1.1 yamaguch uint32_t *cap, cap0; 4564 1.1 yamaguch int error; 4565 1.1 yamaguch 4566 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4567 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD); 4568 1.1 yamaguch iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF); 4569 1.1 yamaguch iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_GET_VF_RESOURCES); 4570 1.1 yamaguch 4571 1.1 yamaguch if (sc->sc_major_ver > 0) { 4572 1.1 yamaguch cap0 = IAVF_VC_OFFLOAD_L2 | 4573 1.1 yamaguch IAVF_VC_OFFLOAD_VLAN | 4574 1.1 yamaguch IAVF_VC_OFFLOAD_RSS_PF | 4575 1.1 yamaguch IAVF_VC_OFFLOAD_REQ_QUEUES; 4576 1.1 yamaguch 4577 1.1 yamaguch cap = IXL_AQB_KVA(aqb); 4578 1.1 yamaguch *cap = htole32(cap0); 4579 1.1 yamaguch iaq.iaq_datalen = htole16(sizeof(*cap)); 4580 1.1 yamaguch } 4581 1.1 yamaguch 4582 1.1 yamaguch sc->sc_got_vf_resources = 0; 4583 1.1 yamaguch if (sc->sc_attached) { 4584 1.1 yamaguch error = iavf_adminq_poll(sc, &iaq, aqb, 250); 4585 1.1 yamaguch } else { 4586 1.1 yamaguch error = iavf_adminq_poll_locked(sc, &iaq, aqb, 250); 4587 1.1 yamaguch } 4588 1.1 yamaguch 4589 1.1 yamaguch if (error) 4590 1.1 yamaguch return -1; 4591 1.1 yamaguch return 0; 4592 1.1 yamaguch } 4593 1.1 yamaguch 4594 1.1 yamaguch static int 4595 1.1 yamaguch iavf_get_stats(struct iavf_softc *sc) 4596 1.1 yamaguch { 4597 1.1 yamaguch struct ixl_aq_desc iaq; 4598 1.1 yamaguch struct ixl_aq_buf *aqb; 4599 1.1 yamaguch struct iavf_vc_queue_select *qsel; 4600 1.1 yamaguch int error; 4601 1.1 yamaguch 4602 1.1 yamaguch mutex_enter(&sc->sc_adminq_lock); 4603 1.1 yamaguch aqb = iavf_aqb_get_locked(&sc->sc_atq_idle); 4604 1.1 yamaguch mutex_exit(&sc->sc_adminq_lock); 4605 1.1 yamaguch 4606 1.1 yamaguch if (aqb == NULL) 4607 1.1 yamaguch return ENOMEM; 4608 1.1 yamaguch 4609 1.1 yamaguch qsel = IXL_AQB_KVA(aqb); 4610 1.1 yamaguch memset(qsel, 0, sizeof(*qsel)); 4611 1.1 yamaguch qsel->vsi_id = htole16(sc->sc_vsi_id); 4612 1.1 yamaguch 4613 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4614 1.1 yamaguch 4615 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD); 4616 1.1 yamaguch iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF); 4617 1.1 yamaguch iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_GET_STATS); 4618 1.1 yamaguch iaq.iaq_datalen = htole16(sizeof(*qsel)); 4619 1.1 yamaguch 4620 1.1 yamaguch if (atomic_load_relaxed(&sc->sc_debuglevel) >= 3) { 4621 1.1 yamaguch device_printf(sc->sc_dev, "post GET_STATS command\n"); 4622 1.1 yamaguch } 4623 1.1 yamaguch 4624 1.1 yamaguch mutex_enter(&sc->sc_adminq_lock); 4625 1.1 yamaguch error = iavf_atq_post(sc, &iaq, aqb); 4626 1.1 yamaguch mutex_exit(&sc->sc_adminq_lock); 4627 1.1 yamaguch 4628 1.1 yamaguch return error; 4629 1.1 yamaguch } 4630 1.1 yamaguch 4631 1.1 yamaguch static int 4632 1.1 yamaguch iavf_config_irq_map(struct iavf_softc *sc, struct ixl_aq_buf *aqb) 4633 1.1 yamaguch { 4634 1.1 yamaguch struct ixl_aq_desc iaq; 4635 1.1 yamaguch struct iavf_vc_vector_map *vec; 4636 1.1 yamaguch struct iavf_vc_irq_map_info *map; 4637 1.1 yamaguch struct iavf_rx_ring *rxr; 4638 1.1 yamaguch struct iavf_tx_ring *txr; 4639 1.1 yamaguch unsigned int num_vec; 4640 1.1 yamaguch int error; 4641 1.1 yamaguch 4642 1.1 yamaguch map = IXL_AQB_KVA(aqb); 4643 1.1 yamaguch vec = map->vecmap; 4644 1.1 yamaguch num_vec = 0; 4645 1.1 yamaguch 4646 1.1 yamaguch if (sc->sc_nintrs == 1) { 4647 1.1 yamaguch vec[0].vsi_id = htole16(sc->sc_vsi_id); 4648 1.1 yamaguch vec[0].vector_id = htole16(0); 4649 1.1 yamaguch vec[0].rxq_map = htole16(iavf_allqueues(sc)); 4650 1.1 yamaguch vec[0].txq_map = htole16(iavf_allqueues(sc)); 4651 1.1 yamaguch vec[0].rxitr_idx = htole16(IAVF_NOITR); 4652 1.1 yamaguch vec[0].rxitr_idx = htole16(IAVF_NOITR); 4653 1.1 yamaguch num_vec = 1; 4654 1.1 yamaguch } else if (sc->sc_nintrs > 1) { 4655 1.1 yamaguch KASSERT(sc->sc_nqps_alloc >= (sc->sc_nintrs - 1)); 4656 1.1 yamaguch for (; num_vec < (sc->sc_nintrs - 1); num_vec++) { 4657 1.1 yamaguch rxr = sc->sc_qps[num_vec].qp_rxr; 4658 1.1 yamaguch txr = sc->sc_qps[num_vec].qp_txr; 4659 1.1 yamaguch 4660 1.1 yamaguch vec[num_vec].vsi_id = htole16(sc->sc_vsi_id); 4661 1.1 yamaguch vec[num_vec].vector_id = htole16(num_vec + 1); 4662 1.1 yamaguch vec[num_vec].rxq_map = htole16(__BIT(rxr->rxr_qid)); 4663 1.1 yamaguch vec[num_vec].txq_map = htole16(__BIT(txr->txr_qid)); 4664 1.1 yamaguch vec[num_vec].rxitr_idx = htole16(IAVF_ITR_RX); 4665 1.1 yamaguch vec[num_vec].txitr_idx = htole16(IAVF_ITR_TX); 4666 1.1 yamaguch } 4667 1.1 yamaguch 4668 1.1 yamaguch vec[num_vec].vsi_id = htole16(sc->sc_vsi_id); 4669 1.1 yamaguch vec[num_vec].vector_id = htole16(0); 4670 1.1 yamaguch vec[num_vec].rxq_map = htole16(0); 4671 1.1 yamaguch vec[num_vec].txq_map = htole16(0); 4672 1.1 yamaguch num_vec++; 4673 1.1 yamaguch } 4674 1.1 yamaguch 4675 1.1 yamaguch map->num_vectors = htole16(num_vec); 4676 1.1 yamaguch 4677 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4678 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD); 4679 1.1 yamaguch iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF); 4680 1.1 yamaguch iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_CONFIG_IRQ_MAP); 4681 1.1 yamaguch iaq.iaq_datalen = htole16(sizeof(*map) + sizeof(*vec) * num_vec); 4682 1.1 yamaguch 4683 1.1 yamaguch if (sc->sc_attached) { 4684 1.1 yamaguch error = iavf_adminq_poll(sc, &iaq, aqb, 250); 4685 1.1 yamaguch } else { 4686 1.1 yamaguch error = iavf_adminq_poll_locked(sc, &iaq, aqb, 250); 4687 1.1 yamaguch } 4688 1.1 yamaguch 4689 1.1 yamaguch if (error) 4690 1.1 yamaguch return -1; 4691 1.1 yamaguch 4692 1.1 yamaguch return 0; 4693 1.1 yamaguch } 4694 1.1 yamaguch 4695 1.1 yamaguch static int 4696 1.1 yamaguch iavf_config_vsi_queues(struct iavf_softc *sc) 4697 1.1 yamaguch { 4698 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 4699 1.1 yamaguch struct ixl_aq_desc iaq; 4700 1.1 yamaguch struct ixl_aq_buf *aqb; 4701 1.1 yamaguch struct iavf_vc_queue_config_info *config; 4702 1.1 yamaguch struct iavf_vc_txq_info *txq; 4703 1.1 yamaguch struct iavf_vc_rxq_info *rxq; 4704 1.1 yamaguch struct iavf_rx_ring *rxr; 4705 1.1 yamaguch struct iavf_tx_ring *txr; 4706 1.1 yamaguch uint32_t rxmtu_max; 4707 1.1 yamaguch unsigned int i; 4708 1.1 yamaguch int error; 4709 1.1 yamaguch 4710 1.1 yamaguch rxmtu_max = ifp->if_mtu + IAVF_MTU_ETHERLEN; 4711 1.1 yamaguch 4712 1.1 yamaguch aqb = iavf_aqb_get(sc, &sc->sc_atq_idle); 4713 1.1 yamaguch 4714 1.1 yamaguch if (aqb == NULL) 4715 1.1 yamaguch return -1; 4716 1.1 yamaguch 4717 1.1 yamaguch config = IXL_AQB_KVA(aqb); 4718 1.1 yamaguch memset(config, 0, sizeof(*config)); 4719 1.1 yamaguch config->vsi_id = htole16(sc->sc_vsi_id); 4720 1.1 yamaguch config->num_queue_pairs = htole16(sc->sc_nqueue_pairs); 4721 1.1 yamaguch 4722 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 4723 1.1 yamaguch rxr = sc->sc_qps[i].qp_rxr; 4724 1.1 yamaguch txr = sc->sc_qps[i].qp_txr; 4725 1.1 yamaguch 4726 1.1 yamaguch txq = &config->qpair[i].txq; 4727 1.1 yamaguch txq->vsi_id = htole16(sc->sc_vsi_id); 4728 1.1 yamaguch txq->queue_id = htole16(txr->txr_qid); 4729 1.1 yamaguch txq->ring_len = htole16(sc->sc_tx_ring_ndescs); 4730 1.1 yamaguch txq->headwb_ena = 0; 4731 1.1 yamaguch txq->dma_ring_addr = htole64(IXL_DMA_DVA(&txr->txr_mem)); 4732 1.1 yamaguch txq->dma_headwb_addr = 0; 4733 1.1 yamaguch 4734 1.1 yamaguch rxq = &config->qpair[i].rxq; 4735 1.1 yamaguch rxq->vsi_id = htole16(sc->sc_vsi_id); 4736 1.1 yamaguch rxq->queue_id = htole16(rxr->rxr_qid); 4737 1.1 yamaguch rxq->ring_len = htole16(sc->sc_rx_ring_ndescs); 4738 1.1 yamaguch rxq->splithdr_ena = 0; 4739 1.1 yamaguch rxq->databuf_size = htole32(IAVF_MCLBYTES); 4740 1.1 yamaguch rxq->max_pkt_size = htole32(rxmtu_max); 4741 1.1 yamaguch rxq->dma_ring_addr = htole64(IXL_DMA_DVA(&rxr->rxr_mem)); 4742 1.1 yamaguch rxq->rx_split_pos = 0; 4743 1.1 yamaguch } 4744 1.1 yamaguch 4745 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4746 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD); 4747 1.1 yamaguch iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF); 4748 1.1 yamaguch iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_CONFIG_VSI_QUEUES); 4749 1.1 yamaguch iaq.iaq_datalen = htole16(sizeof(*config) + 4750 1.1 yamaguch sizeof(config->qpair[0]) * sc->sc_nqueue_pairs); 4751 1.1 yamaguch 4752 1.1 yamaguch error = iavf_adminq_exec(sc, &iaq, aqb); 4753 1.1 yamaguch if (error != IAVF_VC_RC_SUCCESS) { 4754 1.1 yamaguch return -1; 4755 1.1 yamaguch } 4756 1.1 yamaguch 4757 1.1 yamaguch return 0; 4758 1.1 yamaguch } 4759 1.1 yamaguch 4760 1.1 yamaguch static int 4761 1.1 yamaguch iavf_config_hena(struct iavf_softc *sc) 4762 1.1 yamaguch { 4763 1.1 yamaguch struct ixl_aq_desc iaq; 4764 1.1 yamaguch struct ixl_aq_buf *aqb; 4765 1.1 yamaguch uint64_t *caps; 4766 1.1 yamaguch int error; 4767 1.1 yamaguch 4768 1.1 yamaguch aqb = iavf_aqb_get(sc, &sc->sc_atq_idle); 4769 1.1 yamaguch 4770 1.1 yamaguch if (aqb == NULL) 4771 1.1 yamaguch return -1; 4772 1.1 yamaguch 4773 1.1 yamaguch caps = IXL_AQB_KVA(aqb); 4774 1.1 yamaguch if (sc->sc_mac_type == I40E_MAC_X722_VF) 4775 1.9 yamaguch *caps = IXL_RSS_HENA_DEFAULT_X722; 4776 1.9 yamaguch else 4777 1.1 yamaguch *caps = IXL_RSS_HENA_DEFAULT_XL710; 4778 1.1 yamaguch 4779 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4780 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD); 4781 1.1 yamaguch iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF); 4782 1.1 yamaguch iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_SET_RSS_HENA); 4783 1.2 jakllsch iaq.iaq_datalen = htole16(sizeof(*caps)); 4784 1.1 yamaguch 4785 1.1 yamaguch error = iavf_adminq_exec(sc, &iaq, aqb); 4786 1.1 yamaguch if (error != IAVF_VC_RC_SUCCESS) { 4787 1.1 yamaguch return -1; 4788 1.1 yamaguch } 4789 1.1 yamaguch 4790 1.1 yamaguch return 0; 4791 1.1 yamaguch } 4792 1.1 yamaguch 4793 1.1 yamaguch static inline void 4794 1.1 yamaguch iavf_get_default_rss_key(uint8_t *buf, size_t len) 4795 1.1 yamaguch { 4796 1.1 yamaguch uint8_t rss_seed[RSS_KEYSIZE]; 4797 1.1 yamaguch size_t cplen; 4798 1.1 yamaguch 4799 1.1 yamaguch cplen = MIN(len, sizeof(rss_seed)); 4800 1.1 yamaguch rss_getkey(rss_seed); 4801 1.1 yamaguch 4802 1.1 yamaguch memcpy(buf, rss_seed, cplen); 4803 1.1 yamaguch if (cplen < len) 4804 1.1 yamaguch memset(buf + cplen, 0, len - cplen); 4805 1.1 yamaguch } 4806 1.1 yamaguch 4807 1.1 yamaguch static int 4808 1.1 yamaguch iavf_config_rss_key(struct iavf_softc *sc) 4809 1.1 yamaguch { 4810 1.1 yamaguch struct ixl_aq_desc iaq; 4811 1.1 yamaguch struct ixl_aq_buf *aqb; 4812 1.1 yamaguch struct iavf_vc_rss_key *rss_key; 4813 1.1 yamaguch size_t key_len; 4814 1.1 yamaguch int rv; 4815 1.1 yamaguch 4816 1.1 yamaguch aqb = iavf_aqb_get(sc, &sc->sc_atq_idle); 4817 1.1 yamaguch if (aqb == NULL) 4818 1.1 yamaguch return -1; 4819 1.1 yamaguch 4820 1.1 yamaguch rss_key = IXL_AQB_KVA(aqb); 4821 1.1 yamaguch rss_key->vsi_id = htole16(sc->sc_vsi_id); 4822 1.1 yamaguch key_len = IXL_RSS_KEY_SIZE; 4823 1.1 yamaguch iavf_get_default_rss_key(rss_key->key, key_len); 4824 1.1 yamaguch rss_key->key_len = key_len; 4825 1.1 yamaguch 4826 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4827 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD); 4828 1.1 yamaguch iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF); 4829 1.1 yamaguch iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_CONFIG_RSS_KEY); 4830 1.2 jakllsch iaq.iaq_datalen = htole16(sizeof(*rss_key) - sizeof(rss_key->pad) 4831 1.1 yamaguch + (sizeof(rss_key->key[0]) * key_len)); 4832 1.1 yamaguch 4833 1.1 yamaguch rv = iavf_adminq_exec(sc, &iaq, aqb); 4834 1.1 yamaguch if (rv != IAVF_VC_RC_SUCCESS) { 4835 1.1 yamaguch return -1; 4836 1.1 yamaguch } 4837 1.1 yamaguch 4838 1.1 yamaguch return 0; 4839 1.1 yamaguch } 4840 1.1 yamaguch 4841 1.1 yamaguch static int 4842 1.1 yamaguch iavf_config_rss_lut(struct iavf_softc *sc) 4843 1.1 yamaguch { 4844 1.1 yamaguch struct ixl_aq_desc iaq; 4845 1.1 yamaguch struct ixl_aq_buf *aqb; 4846 1.1 yamaguch struct iavf_vc_rss_lut *rss_lut; 4847 1.1 yamaguch uint8_t *lut, v; 4848 1.1 yamaguch int rv, i; 4849 1.1 yamaguch 4850 1.1 yamaguch aqb = iavf_aqb_get(sc, &sc->sc_atq_idle); 4851 1.1 yamaguch if (aqb == NULL) 4852 1.1 yamaguch return -1; 4853 1.1 yamaguch 4854 1.1 yamaguch rss_lut = IXL_AQB_KVA(aqb); 4855 1.1 yamaguch rss_lut->vsi_id = htole16(sc->sc_vsi_id); 4856 1.1 yamaguch rss_lut->lut_entries = htole16(IXL_RSS_VSI_LUT_SIZE); 4857 1.1 yamaguch 4858 1.1 yamaguch lut = rss_lut->lut; 4859 1.1 yamaguch for (i = 0; i < IXL_RSS_VSI_LUT_SIZE; i++) { 4860 1.1 yamaguch v = i % sc->sc_nqueue_pairs; 4861 1.1 yamaguch v &= IAVF_RSS_VSI_LUT_ENTRY_MASK; 4862 1.1 yamaguch lut[i] = v; 4863 1.1 yamaguch } 4864 1.1 yamaguch 4865 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4866 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD); 4867 1.1 yamaguch iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF); 4868 1.1 yamaguch iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_CONFIG_RSS_LUT); 4869 1.2 jakllsch iaq.iaq_datalen = htole16(sizeof(*rss_lut) - sizeof(rss_lut->pad) 4870 1.1 yamaguch + (sizeof(rss_lut->lut[0]) * IXL_RSS_VSI_LUT_SIZE)); 4871 1.1 yamaguch 4872 1.1 yamaguch rv = iavf_adminq_exec(sc, &iaq, aqb); 4873 1.1 yamaguch if (rv != IAVF_VC_RC_SUCCESS) { 4874 1.1 yamaguch return -1; 4875 1.1 yamaguch } 4876 1.1 yamaguch 4877 1.1 yamaguch return 0; 4878 1.1 yamaguch } 4879 1.1 yamaguch 4880 1.1 yamaguch static int 4881 1.1 yamaguch iavf_queue_select(struct iavf_softc *sc, int opcode) 4882 1.1 yamaguch { 4883 1.1 yamaguch struct ixl_aq_desc iaq; 4884 1.1 yamaguch struct ixl_aq_buf *aqb; 4885 1.1 yamaguch struct iavf_vc_queue_select *qsel; 4886 1.1 yamaguch int error; 4887 1.1 yamaguch 4888 1.1 yamaguch aqb = iavf_aqb_get(sc, &sc->sc_atq_idle); 4889 1.1 yamaguch if (aqb == NULL) 4890 1.1 yamaguch return -1; 4891 1.1 yamaguch 4892 1.1 yamaguch qsel = IXL_AQB_KVA(aqb); 4893 1.1 yamaguch qsel->vsi_id = htole16(sc->sc_vsi_id); 4894 1.1 yamaguch qsel->rx_queues = htole32(iavf_allqueues(sc)); 4895 1.1 yamaguch qsel->tx_queues = htole32(iavf_allqueues(sc)); 4896 1.1 yamaguch 4897 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4898 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD); 4899 1.1 yamaguch iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF); 4900 1.1 yamaguch iavf_aq_vc_set_opcode(&iaq, opcode); 4901 1.1 yamaguch iaq.iaq_datalen = htole16(sizeof(*qsel)); 4902 1.1 yamaguch 4903 1.1 yamaguch error = iavf_adminq_exec(sc, &iaq, aqb); 4904 1.1 yamaguch if (error != IAVF_VC_RC_SUCCESS) { 4905 1.1 yamaguch return -1; 4906 1.1 yamaguch } 4907 1.1 yamaguch 4908 1.1 yamaguch return 0; 4909 1.1 yamaguch } 4910 1.1 yamaguch 4911 1.1 yamaguch static int 4912 1.1 yamaguch iavf_request_queues(struct iavf_softc *sc, unsigned int req_num) 4913 1.1 yamaguch { 4914 1.1 yamaguch struct ixl_aq_desc iaq; 4915 1.1 yamaguch struct ixl_aq_buf *aqb; 4916 1.1 yamaguch struct iavf_vc_res_request *req; 4917 1.1 yamaguch int rv; 4918 1.1 yamaguch 4919 1.1 yamaguch aqb = iavf_aqb_get(sc, &sc->sc_atq_idle); 4920 1.1 yamaguch if (aqb == NULL) 4921 1.1 yamaguch return ENOMEM; 4922 1.1 yamaguch 4923 1.1 yamaguch req = IXL_AQB_KVA(aqb); 4924 1.1 yamaguch req->num_queue_pairs = req_num; 4925 1.1 yamaguch 4926 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4927 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD); 4928 1.1 yamaguch iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF); 4929 1.1 yamaguch iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_REQUEST_QUEUES); 4930 1.1 yamaguch iaq.iaq_datalen = htole16(sizeof(*req)); 4931 1.1 yamaguch 4932 1.1 yamaguch mutex_enter(&sc->sc_adminq_lock); 4933 1.1 yamaguch rv = iavf_atq_post(sc, &iaq, aqb); 4934 1.1 yamaguch mutex_exit(&sc->sc_adminq_lock); 4935 1.1 yamaguch 4936 1.1 yamaguch return rv; 4937 1.1 yamaguch } 4938 1.1 yamaguch 4939 1.1 yamaguch static int 4940 1.1 yamaguch iavf_reset_vf(struct iavf_softc *sc) 4941 1.1 yamaguch { 4942 1.1 yamaguch struct ixl_aq_desc iaq; 4943 1.1 yamaguch int error; 4944 1.1 yamaguch 4945 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4946 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_RD); 4947 1.1 yamaguch iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF); 4948 1.1 yamaguch iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_RESET_VF); 4949 1.1 yamaguch iaq.iaq_datalen = htole16(0); 4950 1.1 yamaguch 4951 1.1 yamaguch iavf_wr(sc, I40E_VFGEN_RSTAT, IAVF_VFR_INPROGRESS); 4952 1.1 yamaguch 4953 1.1 yamaguch mutex_enter(&sc->sc_adminq_lock); 4954 1.1 yamaguch error = iavf_atq_post(sc, &iaq, NULL); 4955 1.1 yamaguch mutex_exit(&sc->sc_adminq_lock); 4956 1.1 yamaguch 4957 1.1 yamaguch return error; 4958 1.1 yamaguch } 4959 1.1 yamaguch 4960 1.1 yamaguch static int 4961 1.1 yamaguch iavf_eth_addr(struct iavf_softc *sc, const uint8_t *addr, uint32_t opcode) 4962 1.1 yamaguch { 4963 1.1 yamaguch struct ixl_aq_desc iaq; 4964 1.1 yamaguch struct ixl_aq_buf *aqb; 4965 1.1 yamaguch struct iavf_vc_eth_addr_list *addrs; 4966 1.1 yamaguch struct iavf_vc_eth_addr *vcaddr; 4967 1.1 yamaguch int rv; 4968 1.1 yamaguch 4969 1.1 yamaguch KASSERT(sc->sc_attached); 4970 1.1 yamaguch KASSERT(opcode == IAVF_VC_OP_ADD_ETH_ADDR || 4971 1.1 yamaguch opcode == IAVF_VC_OP_DEL_ETH_ADDR); 4972 1.1 yamaguch 4973 1.1 yamaguch aqb = iavf_aqb_get(sc, &sc->sc_atq_idle); 4974 1.1 yamaguch if (aqb == NULL) 4975 1.1 yamaguch return -1; 4976 1.1 yamaguch 4977 1.1 yamaguch addrs = IXL_AQB_KVA(aqb); 4978 1.1 yamaguch addrs->vsi_id = htole16(sc->sc_vsi_id); 4979 1.1 yamaguch addrs->num_elements = htole16(1); 4980 1.1 yamaguch vcaddr = addrs->list; 4981 1.1 yamaguch memcpy(vcaddr->addr, addr, ETHER_ADDR_LEN); 4982 1.1 yamaguch 4983 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4984 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD); 4985 1.1 yamaguch iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF); 4986 1.1 yamaguch iavf_aq_vc_set_opcode(&iaq, opcode); 4987 1.1 yamaguch iaq.iaq_datalen = htole16(sizeof(*addrs) + sizeof(*vcaddr)); 4988 1.1 yamaguch 4989 1.1 yamaguch if (sc->sc_resetting) { 4990 1.1 yamaguch mutex_enter(&sc->sc_adminq_lock); 4991 1.1 yamaguch rv = iavf_adminq_poll_locked(sc, &iaq, aqb, 250); 4992 1.1 yamaguch iavf_aqb_put_locked(&sc->sc_atq_idle, aqb); 4993 1.1 yamaguch mutex_exit(&sc->sc_adminq_lock); 4994 1.1 yamaguch } else { 4995 1.1 yamaguch rv = iavf_adminq_exec(sc, &iaq, aqb); 4996 1.1 yamaguch } 4997 1.1 yamaguch 4998 1.1 yamaguch if (rv != IAVF_VC_RC_SUCCESS) { 4999 1.1 yamaguch return -1; 5000 1.1 yamaguch } 5001 1.1 yamaguch 5002 1.1 yamaguch return 0; 5003 1.1 yamaguch } 5004 1.1 yamaguch 5005 1.1 yamaguch static int 5006 1.1 yamaguch iavf_config_promisc_mode(struct iavf_softc *sc, int unicast, int multicast) 5007 1.1 yamaguch { 5008 1.1 yamaguch struct ixl_aq_desc iaq; 5009 1.1 yamaguch struct ixl_aq_buf *aqb; 5010 1.1 yamaguch struct iavf_vc_promisc_info *promisc; 5011 1.1 yamaguch int flags; 5012 1.1 yamaguch 5013 1.1 yamaguch KASSERT(sc->sc_attached); 5014 1.1 yamaguch 5015 1.1 yamaguch aqb = iavf_aqb_get(sc, &sc->sc_atq_idle); 5016 1.1 yamaguch if (aqb == NULL) 5017 1.1 yamaguch return -1; 5018 1.1 yamaguch 5019 1.1 yamaguch flags = 0; 5020 1.1 yamaguch if (unicast) 5021 1.1 yamaguch flags |= IAVF_FLAG_VF_UNICAST_PROMISC; 5022 1.1 yamaguch if (multicast) 5023 1.1 yamaguch flags |= IAVF_FLAG_VF_MULTICAST_PROMISC; 5024 1.1 yamaguch 5025 1.1 yamaguch promisc = IXL_AQB_KVA(aqb); 5026 1.1 yamaguch promisc->vsi_id = htole16(sc->sc_vsi_id); 5027 1.1 yamaguch promisc->flags = htole16(flags); 5028 1.1 yamaguch 5029 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 5030 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD); 5031 1.1 yamaguch iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF); 5032 1.1 yamaguch iavf_aq_vc_set_opcode(&iaq, IAVF_VC_OP_CONFIG_PROMISC); 5033 1.1 yamaguch iaq.iaq_datalen = htole16(sizeof(*promisc)); 5034 1.1 yamaguch 5035 1.1 yamaguch if (iavf_adminq_exec(sc, &iaq, aqb) != IAVF_VC_RC_SUCCESS) { 5036 1.1 yamaguch return -1; 5037 1.1 yamaguch } 5038 1.1 yamaguch 5039 1.1 yamaguch return 0; 5040 1.1 yamaguch } 5041 1.1 yamaguch 5042 1.1 yamaguch static int 5043 1.1 yamaguch iavf_config_vlan_stripping(struct iavf_softc *sc, int eccap) 5044 1.1 yamaguch { 5045 1.1 yamaguch struct ixl_aq_desc iaq; 5046 1.1 yamaguch uint32_t opcode; 5047 1.1 yamaguch 5048 1.1 yamaguch opcode = ISSET(eccap, ETHERCAP_VLAN_HWTAGGING) ? 5049 1.1 yamaguch IAVF_VC_OP_ENABLE_VLAN_STRIP : IAVF_VC_OP_DISABLE_VLAN_STRIP; 5050 1.1 yamaguch 5051 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 5052 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_RD); 5053 1.1 yamaguch iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF); 5054 1.1 yamaguch iavf_aq_vc_set_opcode(&iaq, opcode); 5055 1.1 yamaguch iaq.iaq_datalen = htole16(0); 5056 1.1 yamaguch 5057 1.1 yamaguch if (iavf_adminq_exec(sc, &iaq, NULL) != IAVF_VC_RC_SUCCESS) { 5058 1.1 yamaguch return -1; 5059 1.1 yamaguch } 5060 1.1 yamaguch 5061 1.1 yamaguch return 0; 5062 1.1 yamaguch } 5063 1.1 yamaguch 5064 1.1 yamaguch static int 5065 1.1 yamaguch iavf_config_vlan_id(struct iavf_softc *sc, uint16_t vid, uint32_t opcode) 5066 1.1 yamaguch { 5067 1.1 yamaguch struct ixl_aq_desc iaq; 5068 1.1 yamaguch struct ixl_aq_buf *aqb; 5069 1.1 yamaguch struct iavf_vc_vlan_filter *vfilter; 5070 1.1 yamaguch int rv; 5071 1.1 yamaguch 5072 1.1 yamaguch KASSERT(opcode == IAVF_VC_OP_ADD_VLAN || opcode == IAVF_VC_OP_DEL_VLAN); 5073 1.1 yamaguch 5074 1.1 yamaguch aqb = iavf_aqb_get(sc, &sc->sc_atq_idle); 5075 1.1 yamaguch 5076 1.1 yamaguch if (aqb == NULL) 5077 1.1 yamaguch return -1; 5078 1.1 yamaguch 5079 1.1 yamaguch vfilter = IXL_AQB_KVA(aqb); 5080 1.1 yamaguch vfilter->vsi_id = htole16(sc->sc_vsi_id); 5081 1.1 yamaguch vfilter->num_vlan_id = htole16(1); 5082 1.1 yamaguch vfilter->vlan_id[0] = vid; 5083 1.1 yamaguch 5084 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 5085 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD); 5086 1.1 yamaguch iaq.iaq_opcode = htole16(IAVF_AQ_OP_SEND_TO_PF); 5087 1.1 yamaguch iavf_aq_vc_set_opcode(&iaq, opcode); 5088 1.1 yamaguch iaq.iaq_datalen = htole16(sizeof(*vfilter) + sizeof(vid)); 5089 1.1 yamaguch 5090 1.1 yamaguch if (sc->sc_resetting) { 5091 1.1 yamaguch mutex_enter(&sc->sc_adminq_lock); 5092 1.1 yamaguch rv = iavf_adminq_poll_locked(sc, &iaq, aqb, 250); 5093 1.1 yamaguch iavf_aqb_put_locked(&sc->sc_atq_idle, aqb); 5094 1.1 yamaguch mutex_exit(&sc->sc_adminq_lock); 5095 1.1 yamaguch } else { 5096 1.1 yamaguch rv = iavf_adminq_exec(sc, &iaq, aqb); 5097 1.1 yamaguch } 5098 1.1 yamaguch 5099 1.1 yamaguch if (rv != IAVF_VC_RC_SUCCESS) { 5100 1.1 yamaguch return -1; 5101 1.1 yamaguch } 5102 1.1 yamaguch 5103 1.1 yamaguch return 0; 5104 1.1 yamaguch } 5105 1.1 yamaguch 5106 1.1 yamaguch static void 5107 1.1 yamaguch iavf_post_request_queues(void *xsc) 5108 1.1 yamaguch { 5109 1.1 yamaguch struct iavf_softc *sc; 5110 1.1 yamaguch struct ifnet *ifp; 5111 1.1 yamaguch 5112 1.1 yamaguch sc = xsc; 5113 1.1 yamaguch ifp = &sc->sc_ec.ec_if; 5114 1.1 yamaguch 5115 1.1 yamaguch if (!ISSET(sc->sc_vf_cap, IAVF_VC_OFFLOAD_REQ_QUEUES)) { 5116 1.1 yamaguch log(LOG_DEBUG, "%s: the VF has no REQ_QUEUES capability\n", 5117 1.1 yamaguch ifp->if_xname); 5118 1.1 yamaguch return; 5119 1.1 yamaguch } 5120 1.1 yamaguch 5121 1.1 yamaguch log(LOG_INFO, "%s: try to change the number of queue pairs" 5122 1.1 yamaguch " (vsi %u, %u allocated, request %u)\n", 5123 1.1 yamaguch ifp->if_xname, 5124 1.1 yamaguch sc->sc_nqps_vsi, sc->sc_nqps_alloc, sc->sc_nqps_req); 5125 1.1 yamaguch iavf_request_queues(sc, sc->sc_nqps_req); 5126 1.1 yamaguch } 5127 1.1 yamaguch 5128 1.1 yamaguch static bool 5129 1.1 yamaguch iavf_sysctlnode_is_rx(struct sysctlnode *node) 5130 1.1 yamaguch { 5131 1.1 yamaguch 5132 1.1 yamaguch if (strstr(node->sysctl_parent->sysctl_name, "rx") != NULL) 5133 1.1 yamaguch return true; 5134 1.1 yamaguch 5135 1.1 yamaguch return false; 5136 1.1 yamaguch } 5137 1.1 yamaguch 5138 1.1 yamaguch static int 5139 1.1 yamaguch iavf_sysctl_itr_handler(SYSCTLFN_ARGS) 5140 1.1 yamaguch { 5141 1.1 yamaguch struct sysctlnode node = *rnode; 5142 1.1 yamaguch struct iavf_softc *sc = (struct iavf_softc *)node.sysctl_data; 5143 1.1 yamaguch uint32_t newitr, *itrptr; 5144 1.1 yamaguch unsigned int i; 5145 1.1 yamaguch int itr, error; 5146 1.1 yamaguch 5147 1.1 yamaguch if (iavf_sysctlnode_is_rx(&node)) { 5148 1.1 yamaguch itrptr = &sc->sc_rx_itr; 5149 1.1 yamaguch itr = IAVF_ITR_RX; 5150 1.1 yamaguch } else { 5151 1.1 yamaguch itrptr = &sc->sc_tx_itr; 5152 1.1 yamaguch itr = IAVF_ITR_TX; 5153 1.1 yamaguch } 5154 1.1 yamaguch 5155 1.1 yamaguch newitr = *itrptr; 5156 1.1 yamaguch node.sysctl_data = &newitr; 5157 1.1 yamaguch node.sysctl_size = sizeof(newitr); 5158 1.1 yamaguch 5159 1.1 yamaguch error = sysctl_lookup(SYSCTLFN_CALL(&node)); 5160 1.1 yamaguch if (error || newp == NULL) 5161 1.1 yamaguch return error; 5162 1.1 yamaguch 5163 1.1 yamaguch if (newitr > 0x07FF) 5164 1.1 yamaguch return EINVAL; 5165 1.1 yamaguch 5166 1.1 yamaguch *itrptr = newitr; 5167 1.1 yamaguch 5168 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 5169 1.1 yamaguch iavf_wr(sc, I40E_VFINT_ITRN1(itr, i), *itrptr); 5170 1.1 yamaguch } 5171 1.1 yamaguch iavf_wr(sc, I40E_VFINT_ITR01(itr), *itrptr); 5172 1.1 yamaguch 5173 1.1 yamaguch return 0; 5174 1.1 yamaguch } 5175 1.1 yamaguch 5176 1.1 yamaguch static void 5177 1.1 yamaguch iavf_workq_work(struct work *wk, void *context) 5178 1.1 yamaguch { 5179 1.1 yamaguch struct iavf_work *work; 5180 1.1 yamaguch 5181 1.1 yamaguch work = container_of(wk, struct iavf_work, ixw_cookie); 5182 1.1 yamaguch 5183 1.1 yamaguch atomic_swap_uint(&work->ixw_added, 0); 5184 1.1 yamaguch work->ixw_func(work->ixw_arg); 5185 1.1 yamaguch } 5186 1.1 yamaguch 5187 1.1 yamaguch static struct workqueue * 5188 1.1 yamaguch iavf_workq_create(const char *name, pri_t prio, int ipl, int flags) 5189 1.1 yamaguch { 5190 1.1 yamaguch struct workqueue *wq; 5191 1.1 yamaguch int error; 5192 1.1 yamaguch 5193 1.1 yamaguch error = workqueue_create(&wq, name, iavf_workq_work, NULL, 5194 1.1 yamaguch prio, ipl, flags); 5195 1.1 yamaguch 5196 1.1 yamaguch if (error) 5197 1.1 yamaguch return NULL; 5198 1.1 yamaguch 5199 1.1 yamaguch return wq; 5200 1.1 yamaguch } 5201 1.1 yamaguch 5202 1.1 yamaguch static void 5203 1.1 yamaguch iavf_workq_destroy(struct workqueue *wq) 5204 1.1 yamaguch { 5205 1.1 yamaguch 5206 1.1 yamaguch workqueue_destroy(wq); 5207 1.1 yamaguch } 5208 1.1 yamaguch 5209 1.1 yamaguch static int 5210 1.1 yamaguch iavf_work_set(struct iavf_work *work, void (*func)(void *), void *arg) 5211 1.1 yamaguch { 5212 1.1 yamaguch 5213 1.1 yamaguch if (work->ixw_added != 0) 5214 1.1 yamaguch return -1; 5215 1.1 yamaguch 5216 1.1 yamaguch memset(work, 0, sizeof(*work)); 5217 1.1 yamaguch work->ixw_func = func; 5218 1.1 yamaguch work->ixw_arg = arg; 5219 1.1 yamaguch 5220 1.1 yamaguch return 0; 5221 1.1 yamaguch } 5222 1.1 yamaguch 5223 1.1 yamaguch static void 5224 1.1 yamaguch iavf_work_add(struct workqueue *wq, struct iavf_work *work) 5225 1.1 yamaguch { 5226 1.1 yamaguch if (atomic_cas_uint(&work->ixw_added, 0, 1) != 0) 5227 1.1 yamaguch return; 5228 1.1 yamaguch 5229 1.1 yamaguch kpreempt_disable(); 5230 1.1 yamaguch workqueue_enqueue(wq, &work->ixw_cookie, NULL); 5231 1.1 yamaguch kpreempt_enable(); 5232 1.1 yamaguch } 5233 1.1 yamaguch 5234 1.1 yamaguch static void 5235 1.1 yamaguch iavf_work_wait(struct workqueue *wq, struct iavf_work *work) 5236 1.1 yamaguch { 5237 1.1 yamaguch 5238 1.1 yamaguch workqueue_wait(wq, &work->ixw_cookie); 5239 1.1 yamaguch } 5240 1.1 yamaguch 5241 1.1 yamaguch static void 5242 1.1 yamaguch iavf_evcnt_attach(struct evcnt *ec, 5243 1.1 yamaguch const char *n0, const char *n1) 5244 1.1 yamaguch { 5245 1.1 yamaguch 5246 1.1 yamaguch evcnt_attach_dynamic(ec, EVCNT_TYPE_MISC, 5247 1.1 yamaguch NULL, n0, n1); 5248 1.1 yamaguch } 5249 1.1 yamaguch 5250 1.1 yamaguch MODULE(MODULE_CLASS_DRIVER, if_iavf, "pci"); 5251 1.1 yamaguch 5252 1.1 yamaguch #ifdef _MODULE 5253 1.1 yamaguch #include "ioconf.c" 5254 1.1 yamaguch #endif 5255 1.1 yamaguch 5256 1.1 yamaguch #ifdef _MODULE 5257 1.1 yamaguch static void 5258 1.1 yamaguch iavf_parse_modprop(prop_dictionary_t dict) 5259 1.1 yamaguch { 5260 1.1 yamaguch prop_object_t obj; 5261 1.1 yamaguch int64_t val; 5262 1.1 yamaguch uint32_t n; 5263 1.1 yamaguch 5264 1.1 yamaguch if (dict == NULL) 5265 1.1 yamaguch return; 5266 1.1 yamaguch 5267 1.1 yamaguch obj = prop_dictionary_get(dict, "debug_level"); 5268 1.1 yamaguch if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) { 5269 1.1 yamaguch val = prop_number_signed_value((prop_number_t)obj); 5270 1.1 yamaguch 5271 1.1 yamaguch if (val > 0) { 5272 1.1 yamaguch iavf_params.debug = val; 5273 1.1 yamaguch printf("iavf: debug level=%d\n", iavf_params.debug); 5274 1.1 yamaguch } 5275 1.1 yamaguch } 5276 1.1 yamaguch 5277 1.1 yamaguch obj = prop_dictionary_get(dict, "max_qps"); 5278 1.1 yamaguch if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) { 5279 1.1 yamaguch val = prop_number_signed_value((prop_number_t)obj); 5280 1.1 yamaguch 5281 1.3 jakllsch if (val < 1 || val > I40E_MAX_VF_QUEUES) { 5282 1.1 yamaguch printf("iavf: invalid queue size(1 <= n <= %d)", 5283 1.1 yamaguch I40E_MAX_VF_QUEUES); 5284 1.1 yamaguch } else { 5285 1.1 yamaguch iavf_params.max_qps = val; 5286 1.1 yamaguch printf("iavf: request queue pair = %u\n", 5287 1.1 yamaguch iavf_params.max_qps); 5288 1.1 yamaguch } 5289 1.1 yamaguch } 5290 1.1 yamaguch 5291 1.1 yamaguch obj = prop_dictionary_get(dict, "tx_itr"); 5292 1.1 yamaguch if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) { 5293 1.1 yamaguch val = prop_number_signed_value((prop_number_t)obj); 5294 1.1 yamaguch if (val > 0x07FF) { 5295 1.1 yamaguch printf("iavf: TX ITR too big (%" PRId64 " <= %d)", 5296 1.1 yamaguch val, 0x7FF); 5297 1.1 yamaguch } else { 5298 1.1 yamaguch iavf_params.tx_itr = val; 5299 1.1 yamaguch printf("iavf: TX ITR = 0x%" PRIx32, 5300 1.1 yamaguch iavf_params.tx_itr); 5301 1.1 yamaguch } 5302 1.1 yamaguch } 5303 1.1 yamaguch 5304 1.1 yamaguch obj = prop_dictionary_get(dict, "rx_itr"); 5305 1.1 yamaguch if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) { 5306 1.1 yamaguch val = prop_number_signed_value((prop_number_t)obj); 5307 1.1 yamaguch if (val > 0x07FF) { 5308 1.1 yamaguch printf("iavf: RX ITR too big (%" PRId64 " <= %d)", 5309 1.1 yamaguch val, 0x7FF); 5310 1.1 yamaguch } else { 5311 1.1 yamaguch iavf_params.rx_itr = val; 5312 1.1 yamaguch printf("iavf: RX ITR = 0x%" PRIx32, 5313 1.1 yamaguch iavf_params.rx_itr); 5314 1.1 yamaguch } 5315 1.1 yamaguch } 5316 1.1 yamaguch 5317 1.1 yamaguch obj = prop_dictionary_get(dict, "tx_ndescs"); 5318 1.1 yamaguch if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) { 5319 1.1 yamaguch val = prop_number_signed_value((prop_number_t)obj); 5320 1.1 yamaguch n = 1U << (fls32(val) - 1); 5321 1.1 yamaguch if (val != (int64_t) n) { 5322 1.15 andvar printf("iavf: TX desc invalid size" 5323 1.1 yamaguch "(%" PRId64 " != %" PRIu32 ")\n", val, n); 5324 1.1 yamaguch } else if (val > (8192 - 32)) { 5325 1.1 yamaguch printf("iavf: Tx desc too big (%" PRId64 " > %d)", 5326 1.1 yamaguch val, (8192 - 32)); 5327 1.1 yamaguch } else { 5328 1.1 yamaguch iavf_params.tx_ndescs = val; 5329 1.1 yamaguch printf("iavf: TX descriptors = 0x%04x", 5330 1.1 yamaguch iavf_params.tx_ndescs); 5331 1.1 yamaguch } 5332 1.1 yamaguch } 5333 1.1 yamaguch 5334 1.1 yamaguch obj = prop_dictionary_get(dict, "rx_ndescs"); 5335 1.1 yamaguch if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) { 5336 1.1 yamaguch val = prop_number_signed_value((prop_number_t)obj); 5337 1.1 yamaguch n = 1U << (fls32(val) - 1); 5338 1.1 yamaguch if (val != (int64_t) n) { 5339 1.15 andvar printf("iavf: RX desc invalid size" 5340 1.1 yamaguch "(%" PRId64 " != %" PRIu32 ")\n", val, n); 5341 1.1 yamaguch } else if (val > (8192 - 32)) { 5342 1.1 yamaguch printf("iavf: Rx desc too big (%" PRId64 " > %d)", 5343 1.1 yamaguch val, (8192 - 32)); 5344 1.1 yamaguch } else { 5345 1.1 yamaguch iavf_params.rx_ndescs = val; 5346 1.1 yamaguch printf("iavf: RX descriptors = 0x%04x", 5347 1.1 yamaguch iavf_params.rx_ndescs); 5348 1.1 yamaguch } 5349 1.1 yamaguch } 5350 1.1 yamaguch } 5351 1.1 yamaguch #endif 5352 1.1 yamaguch 5353 1.1 yamaguch static int 5354 1.1 yamaguch if_iavf_modcmd(modcmd_t cmd, void *opaque) 5355 1.1 yamaguch { 5356 1.1 yamaguch int error = 0; 5357 1.1 yamaguch 5358 1.1 yamaguch #ifdef _MODULE 5359 1.1 yamaguch switch (cmd) { 5360 1.1 yamaguch case MODULE_CMD_INIT: 5361 1.1 yamaguch iavf_parse_modprop((prop_dictionary_t)opaque); 5362 1.1 yamaguch error = config_init_component(cfdriver_ioconf_if_iavf, 5363 1.1 yamaguch cfattach_ioconf_if_iavf, cfdata_ioconf_if_iavf); 5364 1.1 yamaguch break; 5365 1.1 yamaguch case MODULE_CMD_FINI: 5366 1.1 yamaguch error = config_fini_component(cfdriver_ioconf_if_iavf, 5367 1.1 yamaguch cfattach_ioconf_if_iavf, cfdata_ioconf_if_iavf); 5368 1.1 yamaguch break; 5369 1.1 yamaguch default: 5370 1.1 yamaguch error = ENOTTY; 5371 1.1 yamaguch break; 5372 1.1 yamaguch } 5373 1.1 yamaguch #endif 5374 1.1 yamaguch 5375 1.1 yamaguch return error; 5376 1.1 yamaguch } 5377