1 1.100 christos /* $NetBSD: if_ixl.c,v 1.100 2025/03/25 19:24:07 christos 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 * 37 1.1 yamaguch * Permission to use, copy, modify, and distribute this software for any 38 1.1 yamaguch * purpose with or without fee is hereby granted, provided that the above 39 1.1 yamaguch * copyright notice and this permission notice appear in all copies. 40 1.1 yamaguch * 41 1.1 yamaguch * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 42 1.1 yamaguch * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 43 1.1 yamaguch * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 44 1.1 yamaguch * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 45 1.1 yamaguch * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 46 1.1 yamaguch * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 47 1.1 yamaguch * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 48 1.1 yamaguch */ 49 1.1 yamaguch 50 1.1 yamaguch /* 51 1.1 yamaguch * Copyright (c) 2019 Internet Initiative Japan, Inc. 52 1.1 yamaguch * All rights reserved. 53 1.1 yamaguch * 54 1.1 yamaguch * Redistribution and use in source and binary forms, with or without 55 1.1 yamaguch * modification, are permitted provided that the following conditions 56 1.1 yamaguch * are met: 57 1.1 yamaguch * 1. Redistributions of source code must retain the above copyright 58 1.1 yamaguch * notice, this list of conditions and the following disclaimer. 59 1.1 yamaguch * 2. Redistributions in binary form must reproduce the above copyright 60 1.1 yamaguch * notice, this list of conditions and the following disclaimer in the 61 1.1 yamaguch * documentation and/or other materials provided with the distribution. 62 1.1 yamaguch * 63 1.1 yamaguch * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 64 1.1 yamaguch * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 65 1.1 yamaguch * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 66 1.1 yamaguch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 67 1.1 yamaguch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 68 1.1 yamaguch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 69 1.1 yamaguch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 70 1.1 yamaguch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 71 1.1 yamaguch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 72 1.1 yamaguch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 73 1.1 yamaguch * POSSIBILITY OF SUCH DAMAGE. 74 1.1 yamaguch */ 75 1.1 yamaguch 76 1.1 yamaguch #include <sys/cdefs.h> 77 1.100 christos __KERNEL_RCSID(0, "$NetBSD: if_ixl.c,v 1.100 2025/03/25 19:24:07 christos Exp $"); 78 1.1 yamaguch 79 1.1 yamaguch #ifdef _KERNEL_OPT 80 1.21 yamaguch #include "opt_if_ixl.h" 81 1.1 yamaguch #endif 82 1.1 yamaguch 83 1.1 yamaguch #include <sys/param.h> 84 1.1 yamaguch #include <sys/types.h> 85 1.1 yamaguch 86 1.70 yamaguch #include <sys/bitops.h> 87 1.1 yamaguch #include <sys/cpu.h> 88 1.1 yamaguch #include <sys/device.h> 89 1.1 yamaguch #include <sys/evcnt.h> 90 1.1 yamaguch #include <sys/interrupt.h> 91 1.1 yamaguch #include <sys/kmem.h> 92 1.1 yamaguch #include <sys/module.h> 93 1.1 yamaguch #include <sys/mutex.h> 94 1.1 yamaguch #include <sys/pcq.h> 95 1.1 yamaguch #include <sys/syslog.h> 96 1.1 yamaguch #include <sys/workqueue.h> 97 1.81 yamaguch #include <sys/xcall.h> 98 1.1 yamaguch 99 1.1 yamaguch #include <sys/bus.h> 100 1.1 yamaguch 101 1.1 yamaguch #include <net/bpf.h> 102 1.1 yamaguch #include <net/if.h> 103 1.1 yamaguch #include <net/if_dl.h> 104 1.1 yamaguch #include <net/if_media.h> 105 1.1 yamaguch #include <net/if_ether.h> 106 1.1 yamaguch #include <net/rss_config.h> 107 1.1 yamaguch 108 1.28 yamaguch #include <netinet/tcp.h> /* for struct tcphdr */ 109 1.28 yamaguch #include <netinet/udp.h> /* for struct udphdr */ 110 1.28 yamaguch 111 1.1 yamaguch #include <dev/pci/pcivar.h> 112 1.1 yamaguch #include <dev/pci/pcidevs.h> 113 1.1 yamaguch 114 1.1 yamaguch #include <dev/pci/if_ixlreg.h> 115 1.1 yamaguch #include <dev/pci/if_ixlvar.h> 116 1.1 yamaguch 117 1.19 yamaguch #include <prop/proplib.h> 118 1.19 yamaguch 119 1.1 yamaguch struct ixl_softc; /* defined */ 120 1.1 yamaguch 121 1.1 yamaguch #define I40E_PF_RESET_WAIT_COUNT 200 122 1.1 yamaguch #define I40E_AQ_LARGE_BUF 512 123 1.1 yamaguch 124 1.1 yamaguch /* bitfields for Tx queue mapping in QTX_CTL */ 125 1.1 yamaguch #define I40E_QTX_CTL_VF_QUEUE 0x0 126 1.1 yamaguch #define I40E_QTX_CTL_VM_QUEUE 0x1 127 1.1 yamaguch #define I40E_QTX_CTL_PF_QUEUE 0x2 128 1.1 yamaguch 129 1.1 yamaguch #define I40E_QUEUE_TYPE_EOL 0x7ff 130 1.1 yamaguch #define I40E_INTR_NOTX_QUEUE 0 131 1.1 yamaguch 132 1.1 yamaguch #define I40E_QUEUE_TYPE_RX 0x0 133 1.1 yamaguch #define I40E_QUEUE_TYPE_TX 0x1 134 1.1 yamaguch #define I40E_QUEUE_TYPE_PE_CEQ 0x2 135 1.1 yamaguch #define I40E_QUEUE_TYPE_UNKNOWN 0x3 136 1.1 yamaguch 137 1.1 yamaguch #define I40E_ITR_INDEX_RX 0x0 138 1.1 yamaguch #define I40E_ITR_INDEX_TX 0x1 139 1.1 yamaguch #define I40E_ITR_INDEX_OTHER 0x2 140 1.1 yamaguch #define I40E_ITR_INDEX_NONE 0x3 141 1.64 yamaguch #define IXL_ITR_RX 0x7a /* 4K intrs/sec */ 142 1.64 yamaguch #define IXL_ITR_TX 0x7a /* 4K intrs/sec */ 143 1.1 yamaguch 144 1.1 yamaguch #define I40E_INTR_NOTX_QUEUE 0 145 1.1 yamaguch #define I40E_INTR_NOTX_INTR 0 146 1.1 yamaguch #define I40E_INTR_NOTX_RX_QUEUE 0 147 1.1 yamaguch #define I40E_INTR_NOTX_TX_QUEUE 1 148 1.1 yamaguch #define I40E_INTR_NOTX_RX_MASK I40E_PFINT_ICR0_QUEUE_0_MASK 149 1.1 yamaguch #define I40E_INTR_NOTX_TX_MASK I40E_PFINT_ICR0_QUEUE_1_MASK 150 1.1 yamaguch 151 1.1 yamaguch #define I40E_HASH_LUT_SIZE_128 0 152 1.1 yamaguch 153 1.1 yamaguch #define IXL_ICR0_CRIT_ERR_MASK \ 154 1.1 yamaguch (I40E_PFINT_ICR0_PCI_EXCEPTION_MASK | \ 155 1.1 yamaguch I40E_PFINT_ICR0_ECC_ERR_MASK | \ 156 1.1 yamaguch I40E_PFINT_ICR0_PE_CRITERR_MASK) 157 1.1 yamaguch 158 1.47 yamaguch #define IXL_QUEUE_MAX_XL710 64 159 1.47 yamaguch #define IXL_QUEUE_MAX_X722 128 160 1.47 yamaguch 161 1.1 yamaguch #define IXL_TX_PKT_DESCS 8 162 1.29 yamaguch #define IXL_TX_PKT_MAXSIZE (MCLBYTES * IXL_TX_PKT_DESCS) 163 1.1 yamaguch #define IXL_TX_QUEUE_ALIGN 128 164 1.1 yamaguch #define IXL_RX_QUEUE_ALIGN 128 165 1.1 yamaguch 166 1.29 yamaguch #define IXL_MCLBYTES (MCLBYTES - ETHER_ALIGN) 167 1.29 yamaguch #define IXL_MTU_ETHERLEN ETHER_HDR_LEN \ 168 1.95 yamaguch + ETHER_CRC_LEN \ 169 1.95 yamaguch + ETHER_VLAN_ENCAP_LEN 170 1.29 yamaguch #if 0 171 1.29 yamaguch #define IXL_MAX_MTU (9728 - IXL_MTU_ETHERLEN) 172 1.29 yamaguch #else 173 1.29 yamaguch /* (dbuff * 5) - ETHER_HDR_LEN - ETHER_CRC_LEN */ 174 1.29 yamaguch #define IXL_MAX_MTU (9600 - IXL_MTU_ETHERLEN) 175 1.29 yamaguch #endif 176 1.29 yamaguch #define IXL_MIN_MTU (ETHER_MIN_LEN - ETHER_CRC_LEN) 177 1.1 yamaguch 178 1.1 yamaguch #define IXL_PCIREG PCI_MAPREG_START 179 1.1 yamaguch 180 1.1 yamaguch #define IXL_ITR0 0x0 181 1.1 yamaguch #define IXL_ITR1 0x1 182 1.1 yamaguch #define IXL_ITR2 0x2 183 1.1 yamaguch #define IXL_NOITR 0x3 184 1.1 yamaguch 185 1.1 yamaguch #define IXL_AQ_NUM 256 186 1.1 yamaguch #define IXL_AQ_MASK (IXL_AQ_NUM - 1) 187 1.1 yamaguch #define IXL_AQ_ALIGN 64 /* lol */ 188 1.1 yamaguch #define IXL_AQ_BUFLEN 4096 189 1.1 yamaguch 190 1.1 yamaguch #define IXL_HMC_ROUNDUP 512 191 1.1 yamaguch #define IXL_HMC_PGSIZE 4096 192 1.1 yamaguch #define IXL_HMC_DVASZ sizeof(uint64_t) 193 1.1 yamaguch #define IXL_HMC_PGS (IXL_HMC_PGSIZE / IXL_HMC_DVASZ) 194 1.1 yamaguch #define IXL_HMC_L2SZ (IXL_HMC_PGSIZE * IXL_HMC_PGS) 195 1.1 yamaguch #define IXL_HMC_PDVALID 1ULL 196 1.1 yamaguch 197 1.1 yamaguch #define IXL_ATQ_EXEC_TIMEOUT (10 * hz) 198 1.1 yamaguch 199 1.26 yamaguch #define IXL_SRRD_SRCTL_ATTEMPTS 100000 200 1.26 yamaguch 201 1.1 yamaguch struct ixl_aq_regs { 202 1.1 yamaguch bus_size_t atq_tail; 203 1.1 yamaguch bus_size_t atq_head; 204 1.1 yamaguch bus_size_t atq_len; 205 1.1 yamaguch bus_size_t atq_bal; 206 1.1 yamaguch bus_size_t atq_bah; 207 1.1 yamaguch 208 1.1 yamaguch bus_size_t arq_tail; 209 1.1 yamaguch bus_size_t arq_head; 210 1.1 yamaguch bus_size_t arq_len; 211 1.1 yamaguch bus_size_t arq_bal; 212 1.1 yamaguch bus_size_t arq_bah; 213 1.1 yamaguch 214 1.1 yamaguch uint32_t atq_len_enable; 215 1.1 yamaguch uint32_t atq_tail_mask; 216 1.1 yamaguch uint32_t atq_head_mask; 217 1.1 yamaguch 218 1.1 yamaguch uint32_t arq_len_enable; 219 1.1 yamaguch uint32_t arq_tail_mask; 220 1.1 yamaguch uint32_t arq_head_mask; 221 1.1 yamaguch }; 222 1.1 yamaguch 223 1.1 yamaguch struct ixl_phy_type { 224 1.1 yamaguch uint64_t phy_type; 225 1.1 yamaguch uint64_t ifm_type; 226 1.1 yamaguch }; 227 1.1 yamaguch 228 1.1 yamaguch struct ixl_speed_type { 229 1.1 yamaguch uint8_t dev_speed; 230 1.1 yamaguch uint64_t net_speed; 231 1.1 yamaguch }; 232 1.1 yamaguch 233 1.1 yamaguch struct ixl_hmc_entry { 234 1.1 yamaguch uint64_t hmc_base; 235 1.1 yamaguch uint32_t hmc_count; 236 1.1 yamaguch uint64_t hmc_size; 237 1.1 yamaguch }; 238 1.1 yamaguch 239 1.1 yamaguch enum ixl_hmc_types { 240 1.1 yamaguch IXL_HMC_LAN_TX = 0, 241 1.1 yamaguch IXL_HMC_LAN_RX, 242 1.1 yamaguch IXL_HMC_FCOE_CTX, 243 1.1 yamaguch IXL_HMC_FCOE_FILTER, 244 1.1 yamaguch IXL_HMC_COUNT 245 1.1 yamaguch }; 246 1.1 yamaguch 247 1.1 yamaguch struct ixl_hmc_pack { 248 1.1 yamaguch uint16_t offset; 249 1.1 yamaguch uint16_t width; 250 1.1 yamaguch uint16_t lsb; 251 1.1 yamaguch }; 252 1.1 yamaguch 253 1.1 yamaguch /* 254 1.1 yamaguch * these hmc objects have weird sizes and alignments, so these are abstract 255 1.1 yamaguch * representations of them that are nice for c to populate. 256 1.1 yamaguch * 257 1.1 yamaguch * the packing code relies on little-endian values being stored in the fields, 258 1.1 yamaguch * no high bits in the fields being set, and the fields must be packed in the 259 1.1 yamaguch * same order as they are in the ctx structure. 260 1.1 yamaguch */ 261 1.1 yamaguch 262 1.1 yamaguch struct ixl_hmc_rxq { 263 1.1 yamaguch uint16_t head; 264 1.1 yamaguch uint8_t cpuid; 265 1.1 yamaguch uint64_t base; 266 1.1 yamaguch #define IXL_HMC_RXQ_BASE_UNIT 128 267 1.1 yamaguch uint16_t qlen; 268 1.1 yamaguch uint16_t dbuff; 269 1.1 yamaguch #define IXL_HMC_RXQ_DBUFF_UNIT 128 270 1.1 yamaguch uint8_t hbuff; 271 1.1 yamaguch #define IXL_HMC_RXQ_HBUFF_UNIT 64 272 1.1 yamaguch uint8_t dtype; 273 1.1 yamaguch #define IXL_HMC_RXQ_DTYPE_NOSPLIT 0x0 274 1.1 yamaguch #define IXL_HMC_RXQ_DTYPE_HSPLIT 0x1 275 1.1 yamaguch #define IXL_HMC_RXQ_DTYPE_SPLIT_ALWAYS 0x2 276 1.1 yamaguch uint8_t dsize; 277 1.1 yamaguch #define IXL_HMC_RXQ_DSIZE_16 0 278 1.1 yamaguch #define IXL_HMC_RXQ_DSIZE_32 1 279 1.1 yamaguch uint8_t crcstrip; 280 1.1 yamaguch uint8_t fc_ena; 281 1.1 yamaguch uint8_t l2sel; 282 1.1 yamaguch uint8_t hsplit_0; 283 1.1 yamaguch uint8_t hsplit_1; 284 1.1 yamaguch uint8_t showiv; 285 1.1 yamaguch uint16_t rxmax; 286 1.1 yamaguch uint8_t tphrdesc_ena; 287 1.1 yamaguch uint8_t tphwdesc_ena; 288 1.1 yamaguch uint8_t tphdata_ena; 289 1.1 yamaguch uint8_t tphhead_ena; 290 1.1 yamaguch uint8_t lrxqthresh; 291 1.1 yamaguch uint8_t prefena; 292 1.1 yamaguch }; 293 1.1 yamaguch 294 1.1 yamaguch static const struct ixl_hmc_pack ixl_hmc_pack_rxq[] = { 295 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, head), 13, 0 }, 296 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, cpuid), 8, 13 }, 297 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, base), 57, 32 }, 298 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, qlen), 13, 89 }, 299 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, dbuff), 7, 102 }, 300 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, hbuff), 5, 109 }, 301 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, dtype), 2, 114 }, 302 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, dsize), 1, 116 }, 303 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, crcstrip), 1, 117 }, 304 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, fc_ena), 1, 118 }, 305 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, l2sel), 1, 119 }, 306 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, hsplit_0), 4, 120 }, 307 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, hsplit_1), 2, 124 }, 308 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, showiv), 1, 127 }, 309 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, rxmax), 14, 174 }, 310 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, tphrdesc_ena), 1, 193 }, 311 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, tphwdesc_ena), 1, 194 }, 312 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, tphdata_ena), 1, 195 }, 313 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, tphhead_ena), 1, 196 }, 314 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, lrxqthresh), 3, 198 }, 315 1.1 yamaguch { offsetof(struct ixl_hmc_rxq, prefena), 1, 201 }, 316 1.1 yamaguch }; 317 1.1 yamaguch 318 1.1 yamaguch #define IXL_HMC_RXQ_MINSIZE (201 + 1) 319 1.1 yamaguch 320 1.1 yamaguch struct ixl_hmc_txq { 321 1.1 yamaguch uint16_t head; 322 1.1 yamaguch uint8_t new_context; 323 1.1 yamaguch uint64_t base; 324 1.1 yamaguch #define IXL_HMC_TXQ_BASE_UNIT 128 325 1.1 yamaguch uint8_t fc_ena; 326 1.1 yamaguch uint8_t timesync_ena; 327 1.1 yamaguch uint8_t fd_ena; 328 1.1 yamaguch uint8_t alt_vlan_ena; 329 1.49 yamaguch uint8_t cpuid; 330 1.1 yamaguch uint16_t thead_wb; 331 1.1 yamaguch uint8_t head_wb_ena; 332 1.1 yamaguch #define IXL_HMC_TXQ_DESC_WB 0 333 1.1 yamaguch #define IXL_HMC_TXQ_HEAD_WB 1 334 1.1 yamaguch uint16_t qlen; 335 1.1 yamaguch uint8_t tphrdesc_ena; 336 1.1 yamaguch uint8_t tphrpacket_ena; 337 1.1 yamaguch uint8_t tphwdesc_ena; 338 1.1 yamaguch uint64_t head_wb_addr; 339 1.1 yamaguch uint32_t crc; 340 1.1 yamaguch uint16_t rdylist; 341 1.1 yamaguch uint8_t rdylist_act; 342 1.1 yamaguch }; 343 1.1 yamaguch 344 1.1 yamaguch static const struct ixl_hmc_pack ixl_hmc_pack_txq[] = { 345 1.1 yamaguch { offsetof(struct ixl_hmc_txq, head), 13, 0 }, 346 1.1 yamaguch { offsetof(struct ixl_hmc_txq, new_context), 1, 30 }, 347 1.1 yamaguch { offsetof(struct ixl_hmc_txq, base), 57, 32 }, 348 1.1 yamaguch { offsetof(struct ixl_hmc_txq, fc_ena), 1, 89 }, 349 1.1 yamaguch { offsetof(struct ixl_hmc_txq, timesync_ena), 1, 90 }, 350 1.1 yamaguch { offsetof(struct ixl_hmc_txq, fd_ena), 1, 91 }, 351 1.1 yamaguch { offsetof(struct ixl_hmc_txq, alt_vlan_ena), 1, 92 }, 352 1.1 yamaguch { offsetof(struct ixl_hmc_txq, cpuid), 8, 96 }, 353 1.1 yamaguch /* line 1 */ 354 1.1 yamaguch { offsetof(struct ixl_hmc_txq, thead_wb), 13, 0 + 128 }, 355 1.1 yamaguch { offsetof(struct ixl_hmc_txq, head_wb_ena), 1, 32 + 128 }, 356 1.1 yamaguch { offsetof(struct ixl_hmc_txq, qlen), 13, 33 + 128 }, 357 1.1 yamaguch { offsetof(struct ixl_hmc_txq, tphrdesc_ena), 1, 46 + 128 }, 358 1.1 yamaguch { offsetof(struct ixl_hmc_txq, tphrpacket_ena), 1, 47 + 128 }, 359 1.1 yamaguch { offsetof(struct ixl_hmc_txq, tphwdesc_ena), 1, 48 + 128 }, 360 1.1 yamaguch { offsetof(struct ixl_hmc_txq, head_wb_addr), 64, 64 + 128 }, 361 1.1 yamaguch /* line 7 */ 362 1.1 yamaguch { offsetof(struct ixl_hmc_txq, crc), 32, 0 + (7*128) }, 363 1.1 yamaguch { offsetof(struct ixl_hmc_txq, rdylist), 10, 84 + (7*128) }, 364 1.1 yamaguch { offsetof(struct ixl_hmc_txq, rdylist_act), 1, 94 + (7*128) }, 365 1.1 yamaguch }; 366 1.1 yamaguch 367 1.1 yamaguch #define IXL_HMC_TXQ_MINSIZE (94 + (7*128) + 1) 368 1.1 yamaguch 369 1.1 yamaguch struct ixl_work { 370 1.1 yamaguch struct work ixw_cookie; 371 1.1 yamaguch void (*ixw_func)(void *); 372 1.1 yamaguch void *ixw_arg; 373 1.1 yamaguch unsigned int ixw_added; 374 1.1 yamaguch }; 375 1.1 yamaguch #define IXL_WORKQUEUE_PRI PRI_SOFTNET 376 1.1 yamaguch 377 1.1 yamaguch struct ixl_tx_map { 378 1.1 yamaguch struct mbuf *txm_m; 379 1.1 yamaguch bus_dmamap_t txm_map; 380 1.1 yamaguch unsigned int txm_eop; 381 1.1 yamaguch }; 382 1.1 yamaguch 383 1.1 yamaguch struct ixl_tx_ring { 384 1.1 yamaguch kmutex_t txr_lock; 385 1.1 yamaguch struct ixl_softc *txr_sc; 386 1.1 yamaguch 387 1.1 yamaguch unsigned int txr_prod; 388 1.1 yamaguch unsigned int txr_cons; 389 1.1 yamaguch 390 1.1 yamaguch struct ixl_tx_map *txr_maps; 391 1.1 yamaguch struct ixl_dmamem txr_mem; 392 1.1 yamaguch 393 1.1 yamaguch bus_size_t txr_tail; 394 1.1 yamaguch unsigned int txr_qid; 395 1.1 yamaguch pcq_t *txr_intrq; 396 1.1 yamaguch void *txr_si; 397 1.1 yamaguch 398 1.1 yamaguch struct evcnt txr_defragged; 399 1.1 yamaguch struct evcnt txr_defrag_failed; 400 1.1 yamaguch struct evcnt txr_pcqdrop; 401 1.1 yamaguch struct evcnt txr_transmitdef; 402 1.1 yamaguch struct evcnt txr_intr; 403 1.1 yamaguch struct evcnt txr_defer; 404 1.1 yamaguch }; 405 1.1 yamaguch 406 1.1 yamaguch struct ixl_rx_map { 407 1.1 yamaguch struct mbuf *rxm_m; 408 1.1 yamaguch bus_dmamap_t rxm_map; 409 1.1 yamaguch }; 410 1.1 yamaguch 411 1.1 yamaguch struct ixl_rx_ring { 412 1.1 yamaguch kmutex_t rxr_lock; 413 1.1 yamaguch 414 1.1 yamaguch unsigned int rxr_prod; 415 1.1 yamaguch unsigned int rxr_cons; 416 1.1 yamaguch 417 1.1 yamaguch struct ixl_rx_map *rxr_maps; 418 1.1 yamaguch struct ixl_dmamem rxr_mem; 419 1.1 yamaguch 420 1.1 yamaguch struct mbuf *rxr_m_head; 421 1.1 yamaguch struct mbuf **rxr_m_tail; 422 1.1 yamaguch 423 1.1 yamaguch bus_size_t rxr_tail; 424 1.1 yamaguch unsigned int rxr_qid; 425 1.1 yamaguch 426 1.1 yamaguch struct evcnt rxr_mgethdr_failed; 427 1.1 yamaguch struct evcnt rxr_mgetcl_failed; 428 1.1 yamaguch struct evcnt rxr_mbuf_load_failed; 429 1.1 yamaguch struct evcnt rxr_intr; 430 1.1 yamaguch struct evcnt rxr_defer; 431 1.1 yamaguch }; 432 1.1 yamaguch 433 1.1 yamaguch struct ixl_queue_pair { 434 1.1 yamaguch struct ixl_softc *qp_sc; 435 1.1 yamaguch struct ixl_tx_ring *qp_txr; 436 1.1 yamaguch struct ixl_rx_ring *qp_rxr; 437 1.1 yamaguch 438 1.1 yamaguch char qp_name[16]; 439 1.1 yamaguch 440 1.1 yamaguch void *qp_si; 441 1.45 yamaguch struct work qp_work; 442 1.1 yamaguch bool qp_workqueue; 443 1.1 yamaguch }; 444 1.1 yamaguch 445 1.1 yamaguch struct ixl_atq { 446 1.1 yamaguch struct ixl_aq_desc iatq_desc; 447 1.4 yamaguch void (*iatq_fn)(struct ixl_softc *, 448 1.4 yamaguch const struct ixl_aq_desc *); 449 1.90 yamaguch bool iatq_inuse; 450 1.1 yamaguch }; 451 1.1 yamaguch SIMPLEQ_HEAD(ixl_atq_list, ixl_atq); 452 1.1 yamaguch 453 1.1 yamaguch struct ixl_product { 454 1.1 yamaguch unsigned int vendor_id; 455 1.1 yamaguch unsigned int product_id; 456 1.1 yamaguch }; 457 1.1 yamaguch 458 1.17 yamaguch struct ixl_stats_counters { 459 1.17 yamaguch bool isc_has_offset; 460 1.17 yamaguch struct evcnt isc_crc_errors; 461 1.17 yamaguch uint64_t isc_crc_errors_offset; 462 1.17 yamaguch struct evcnt isc_illegal_bytes; 463 1.17 yamaguch uint64_t isc_illegal_bytes_offset; 464 1.17 yamaguch struct evcnt isc_rx_bytes; 465 1.17 yamaguch uint64_t isc_rx_bytes_offset; 466 1.17 yamaguch struct evcnt isc_rx_discards; 467 1.17 yamaguch uint64_t isc_rx_discards_offset; 468 1.17 yamaguch struct evcnt isc_rx_unicast; 469 1.17 yamaguch uint64_t isc_rx_unicast_offset; 470 1.17 yamaguch struct evcnt isc_rx_multicast; 471 1.17 yamaguch uint64_t isc_rx_multicast_offset; 472 1.17 yamaguch struct evcnt isc_rx_broadcast; 473 1.17 yamaguch uint64_t isc_rx_broadcast_offset; 474 1.17 yamaguch struct evcnt isc_rx_size_64; 475 1.17 yamaguch uint64_t isc_rx_size_64_offset; 476 1.17 yamaguch struct evcnt isc_rx_size_127; 477 1.17 yamaguch uint64_t isc_rx_size_127_offset; 478 1.17 yamaguch struct evcnt isc_rx_size_255; 479 1.17 yamaguch uint64_t isc_rx_size_255_offset; 480 1.17 yamaguch struct evcnt isc_rx_size_511; 481 1.17 yamaguch uint64_t isc_rx_size_511_offset; 482 1.17 yamaguch struct evcnt isc_rx_size_1023; 483 1.17 yamaguch uint64_t isc_rx_size_1023_offset; 484 1.17 yamaguch struct evcnt isc_rx_size_1522; 485 1.17 yamaguch uint64_t isc_rx_size_1522_offset; 486 1.17 yamaguch struct evcnt isc_rx_size_big; 487 1.17 yamaguch uint64_t isc_rx_size_big_offset; 488 1.17 yamaguch struct evcnt isc_rx_undersize; 489 1.17 yamaguch uint64_t isc_rx_undersize_offset; 490 1.17 yamaguch struct evcnt isc_rx_oversize; 491 1.17 yamaguch uint64_t isc_rx_oversize_offset; 492 1.17 yamaguch struct evcnt isc_rx_fragments; 493 1.17 yamaguch uint64_t isc_rx_fragments_offset; 494 1.17 yamaguch struct evcnt isc_rx_jabber; 495 1.17 yamaguch uint64_t isc_rx_jabber_offset; 496 1.17 yamaguch struct evcnt isc_tx_bytes; 497 1.17 yamaguch uint64_t isc_tx_bytes_offset; 498 1.17 yamaguch struct evcnt isc_tx_dropped_link_down; 499 1.17 yamaguch uint64_t isc_tx_dropped_link_down_offset; 500 1.17 yamaguch struct evcnt isc_tx_unicast; 501 1.17 yamaguch uint64_t isc_tx_unicast_offset; 502 1.17 yamaguch struct evcnt isc_tx_multicast; 503 1.17 yamaguch uint64_t isc_tx_multicast_offset; 504 1.17 yamaguch struct evcnt isc_tx_broadcast; 505 1.17 yamaguch uint64_t isc_tx_broadcast_offset; 506 1.17 yamaguch struct evcnt isc_tx_size_64; 507 1.17 yamaguch uint64_t isc_tx_size_64_offset; 508 1.17 yamaguch struct evcnt isc_tx_size_127; 509 1.17 yamaguch uint64_t isc_tx_size_127_offset; 510 1.17 yamaguch struct evcnt isc_tx_size_255; 511 1.17 yamaguch uint64_t isc_tx_size_255_offset; 512 1.17 yamaguch struct evcnt isc_tx_size_511; 513 1.17 yamaguch uint64_t isc_tx_size_511_offset; 514 1.17 yamaguch struct evcnt isc_tx_size_1023; 515 1.17 yamaguch uint64_t isc_tx_size_1023_offset; 516 1.17 yamaguch struct evcnt isc_tx_size_1522; 517 1.17 yamaguch uint64_t isc_tx_size_1522_offset; 518 1.17 yamaguch struct evcnt isc_tx_size_big; 519 1.17 yamaguch uint64_t isc_tx_size_big_offset; 520 1.17 yamaguch struct evcnt isc_mac_local_faults; 521 1.17 yamaguch uint64_t isc_mac_local_faults_offset; 522 1.17 yamaguch struct evcnt isc_mac_remote_faults; 523 1.17 yamaguch uint64_t isc_mac_remote_faults_offset; 524 1.17 yamaguch struct evcnt isc_link_xon_rx; 525 1.17 yamaguch uint64_t isc_link_xon_rx_offset; 526 1.17 yamaguch struct evcnt isc_link_xon_tx; 527 1.17 yamaguch uint64_t isc_link_xon_tx_offset; 528 1.17 yamaguch struct evcnt isc_link_xoff_rx; 529 1.17 yamaguch uint64_t isc_link_xoff_rx_offset; 530 1.17 yamaguch struct evcnt isc_link_xoff_tx; 531 1.17 yamaguch uint64_t isc_link_xoff_tx_offset; 532 1.18 yamaguch struct evcnt isc_vsi_rx_discards; 533 1.18 yamaguch uint64_t isc_vsi_rx_discards_offset; 534 1.18 yamaguch struct evcnt isc_vsi_rx_bytes; 535 1.18 yamaguch uint64_t isc_vsi_rx_bytes_offset; 536 1.18 yamaguch struct evcnt isc_vsi_rx_unicast; 537 1.18 yamaguch uint64_t isc_vsi_rx_unicast_offset; 538 1.18 yamaguch struct evcnt isc_vsi_rx_multicast; 539 1.18 yamaguch uint64_t isc_vsi_rx_multicast_offset; 540 1.18 yamaguch struct evcnt isc_vsi_rx_broadcast; 541 1.18 yamaguch uint64_t isc_vsi_rx_broadcast_offset; 542 1.18 yamaguch struct evcnt isc_vsi_tx_errors; 543 1.18 yamaguch uint64_t isc_vsi_tx_errors_offset; 544 1.18 yamaguch struct evcnt isc_vsi_tx_bytes; 545 1.18 yamaguch uint64_t isc_vsi_tx_bytes_offset; 546 1.18 yamaguch struct evcnt isc_vsi_tx_unicast; 547 1.18 yamaguch uint64_t isc_vsi_tx_unicast_offset; 548 1.18 yamaguch struct evcnt isc_vsi_tx_multicast; 549 1.18 yamaguch uint64_t isc_vsi_tx_multicast_offset; 550 1.18 yamaguch struct evcnt isc_vsi_tx_broadcast; 551 1.18 yamaguch uint64_t isc_vsi_tx_broadcast_offset; 552 1.17 yamaguch }; 553 1.17 yamaguch 554 1.1 yamaguch /* 555 1.1 yamaguch * Locking notes: 556 1.1 yamaguch * + a field in ixl_tx_ring is protected by txr_lock (a spin mutex), and 557 1.1 yamaguch * a field in ixl_rx_ring is protected by rxr_lock (a spin mutex). 558 1.1 yamaguch * - more than one lock of them cannot be held at once. 559 1.1 yamaguch * + a field named sc_atq_* in ixl_softc is protected by sc_atq_lock 560 1.1 yamaguch * (a spin mutex). 561 1.1 yamaguch * - the lock cannot held with txr_lock or rxr_lock. 562 1.1 yamaguch * + a field named sc_arq_* is not protected by any lock. 563 1.1 yamaguch * - operations for sc_arq_* is done in one context related to 564 1.1 yamaguch * sc_arq_task. 565 1.1 yamaguch * + other fields in ixl_softc is protected by sc_cfg_lock 566 1.1 yamaguch * (an adaptive mutex) 567 1.1 yamaguch * - It must be held before another lock is held, and It can be 568 1.1 yamaguch * released after the other lock is released. 569 1.1 yamaguch * */ 570 1.1 yamaguch 571 1.1 yamaguch struct ixl_softc { 572 1.1 yamaguch device_t sc_dev; 573 1.1 yamaguch struct ethercom sc_ec; 574 1.1 yamaguch bool sc_attached; 575 1.1 yamaguch bool sc_dead; 576 1.17 yamaguch uint32_t sc_port; 577 1.1 yamaguch struct sysctllog *sc_sysctllog; 578 1.1 yamaguch struct workqueue *sc_workq; 579 1.1 yamaguch struct workqueue *sc_workq_txrx; 580 1.17 yamaguch int sc_stats_intval; 581 1.17 yamaguch callout_t sc_stats_callout; 582 1.17 yamaguch struct ixl_work sc_stats_task; 583 1.17 yamaguch struct ixl_stats_counters 584 1.17 yamaguch sc_stats_counters; 585 1.1 yamaguch uint8_t sc_enaddr[ETHER_ADDR_LEN]; 586 1.1 yamaguch struct ifmedia sc_media; 587 1.1 yamaguch uint64_t sc_media_status; 588 1.1 yamaguch uint64_t sc_media_active; 589 1.31 yamaguch uint64_t sc_phy_types; 590 1.31 yamaguch uint8_t sc_phy_abilities; 591 1.31 yamaguch uint8_t sc_phy_linkspeed; 592 1.31 yamaguch uint8_t sc_phy_fec_cfg; 593 1.31 yamaguch uint16_t sc_eee_cap; 594 1.31 yamaguch uint32_t sc_eeer_val; 595 1.31 yamaguch uint8_t sc_d3_lpan; 596 1.1 yamaguch kmutex_t sc_cfg_lock; 597 1.1 yamaguch enum i40e_mac_type sc_mac_type; 598 1.1 yamaguch uint32_t sc_rss_table_size; 599 1.1 yamaguch uint32_t sc_rss_table_entry_width; 600 1.1 yamaguch bool sc_txrx_workqueue; 601 1.1 yamaguch u_int sc_tx_process_limit; 602 1.1 yamaguch u_int sc_rx_process_limit; 603 1.1 yamaguch u_int sc_tx_intr_process_limit; 604 1.1 yamaguch u_int sc_rx_intr_process_limit; 605 1.1 yamaguch 606 1.11 yamaguch int sc_cur_ec_capenable; 607 1.11 yamaguch 608 1.1 yamaguch struct pci_attach_args sc_pa; 609 1.1 yamaguch pci_intr_handle_t *sc_ihp; 610 1.1 yamaguch void **sc_ihs; 611 1.1 yamaguch unsigned int sc_nintrs; 612 1.1 yamaguch 613 1.1 yamaguch bus_dma_tag_t sc_dmat; 614 1.1 yamaguch bus_space_tag_t sc_memt; 615 1.1 yamaguch bus_space_handle_t sc_memh; 616 1.1 yamaguch bus_size_t sc_mems; 617 1.1 yamaguch 618 1.1 yamaguch uint8_t sc_pf_id; 619 1.1 yamaguch uint16_t sc_uplink_seid; /* le */ 620 1.1 yamaguch uint16_t sc_downlink_seid; /* le */ 621 1.41 yamaguch uint16_t sc_vsi_number; 622 1.18 yamaguch uint16_t sc_vsi_stat_counter_idx; 623 1.1 yamaguch uint16_t sc_seid; 624 1.1 yamaguch unsigned int sc_base_queue; 625 1.1 yamaguch 626 1.1 yamaguch pci_intr_type_t sc_intrtype; 627 1.1 yamaguch unsigned int sc_msix_vector_queue; 628 1.1 yamaguch 629 1.1 yamaguch struct ixl_dmamem sc_scratch; 630 1.26 yamaguch struct ixl_dmamem sc_aqbuf; 631 1.1 yamaguch 632 1.1 yamaguch const struct ixl_aq_regs * 633 1.1 yamaguch sc_aq_regs; 634 1.25 yamaguch uint32_t sc_aq_flags; 635 1.25 yamaguch #define IXL_SC_AQ_FLAG_RXCTL __BIT(0) 636 1.26 yamaguch #define IXL_SC_AQ_FLAG_NVMLOCK __BIT(1) 637 1.26 yamaguch #define IXL_SC_AQ_FLAG_NVMREAD __BIT(2) 638 1.41 yamaguch #define IXL_SC_AQ_FLAG_RSS __BIT(3) 639 1.1 yamaguch 640 1.1 yamaguch kmutex_t sc_atq_lock; 641 1.1 yamaguch kcondvar_t sc_atq_cv; 642 1.1 yamaguch struct ixl_dmamem sc_atq; 643 1.1 yamaguch unsigned int sc_atq_prod; 644 1.1 yamaguch unsigned int sc_atq_cons; 645 1.1 yamaguch 646 1.1 yamaguch struct ixl_dmamem sc_arq; 647 1.1 yamaguch struct ixl_work sc_arq_task; 648 1.1 yamaguch struct ixl_aq_bufs sc_arq_idle; 649 1.1 yamaguch struct ixl_aq_buf *sc_arq_live[IXL_AQ_NUM]; 650 1.1 yamaguch unsigned int sc_arq_prod; 651 1.1 yamaguch unsigned int sc_arq_cons; 652 1.1 yamaguch 653 1.1 yamaguch struct ixl_work sc_link_state_task; 654 1.92 yamaguch struct ixl_work sc_link_state_done_task; 655 1.1 yamaguch struct ixl_atq sc_link_state_atq; 656 1.1 yamaguch 657 1.1 yamaguch struct ixl_dmamem sc_hmc_sd; 658 1.1 yamaguch struct ixl_dmamem sc_hmc_pd; 659 1.1 yamaguch struct ixl_hmc_entry sc_hmc_entries[IXL_HMC_COUNT]; 660 1.1 yamaguch 661 1.71 yamaguch struct if_percpuq *sc_ipq; 662 1.1 yamaguch unsigned int sc_tx_ring_ndescs; 663 1.1 yamaguch unsigned int sc_rx_ring_ndescs; 664 1.1 yamaguch unsigned int sc_nqueue_pairs; 665 1.1 yamaguch unsigned int sc_nqueue_pairs_max; 666 1.1 yamaguch unsigned int sc_nqueue_pairs_device; 667 1.1 yamaguch struct ixl_queue_pair *sc_qps; 668 1.64 yamaguch uint32_t sc_itr_rx; 669 1.64 yamaguch uint32_t sc_itr_tx; 670 1.1 yamaguch 671 1.1 yamaguch struct evcnt sc_event_atq; 672 1.1 yamaguch struct evcnt sc_event_link; 673 1.1 yamaguch struct evcnt sc_event_ecc_err; 674 1.1 yamaguch struct evcnt sc_event_pci_exception; 675 1.1 yamaguch struct evcnt sc_event_crit_err; 676 1.1 yamaguch }; 677 1.1 yamaguch 678 1.1 yamaguch #define IXL_TXRX_PROCESS_UNLIMIT UINT_MAX 679 1.1 yamaguch #define IXL_TX_PROCESS_LIMIT 256 680 1.1 yamaguch #define IXL_RX_PROCESS_LIMIT 256 681 1.1 yamaguch #define IXL_TX_INTR_PROCESS_LIMIT 256 682 1.1 yamaguch #define IXL_RX_INTR_PROCESS_LIMIT 0U 683 1.1 yamaguch 684 1.28 yamaguch #define IXL_IFCAP_RXCSUM (IFCAP_CSUM_IPv4_Rx | \ 685 1.28 yamaguch IFCAP_CSUM_TCPv4_Rx | \ 686 1.28 yamaguch IFCAP_CSUM_UDPv4_Rx | \ 687 1.28 yamaguch IFCAP_CSUM_TCPv6_Rx | \ 688 1.14 yamaguch IFCAP_CSUM_UDPv6_Rx) 689 1.28 yamaguch #define IXL_IFCAP_TXCSUM (IFCAP_CSUM_IPv4_Tx | \ 690 1.28 yamaguch IFCAP_CSUM_TCPv4_Tx | \ 691 1.28 yamaguch IFCAP_CSUM_UDPv4_Tx | \ 692 1.28 yamaguch IFCAP_CSUM_TCPv6_Tx | \ 693 1.28 yamaguch IFCAP_CSUM_UDPv6_Tx) 694 1.28 yamaguch #define IXL_CSUM_ALL_OFFLOAD (M_CSUM_IPv4 | \ 695 1.28 yamaguch M_CSUM_TCPv4 | M_CSUM_TCPv6 | \ 696 1.28 yamaguch M_CSUM_UDPv4 | M_CSUM_UDPv6) 697 1.14 yamaguch 698 1.1 yamaguch #define delaymsec(_x) DELAY(1000 * (_x)) 699 1.1 yamaguch #ifdef IXL_DEBUG 700 1.13 yamaguch #define DDPRINTF(sc, fmt, args...) \ 701 1.13 yamaguch do { \ 702 1.13 yamaguch if ((sc) != NULL) { \ 703 1.13 yamaguch device_printf( \ 704 1.13 yamaguch ((struct ixl_softc *)(sc))->sc_dev, \ 705 1.13 yamaguch ""); \ 706 1.13 yamaguch } \ 707 1.13 yamaguch printf("%s:\t" fmt, __func__, ##args); \ 708 1.1 yamaguch } while (0) 709 1.1 yamaguch #else 710 1.1 yamaguch #define DDPRINTF(sc, fmt, args...) __nothing 711 1.1 yamaguch #endif 712 1.17 yamaguch #ifndef IXL_STATS_INTERVAL_MSEC 713 1.17 yamaguch #define IXL_STATS_INTERVAL_MSEC 10000 714 1.17 yamaguch #endif 715 1.19 yamaguch #ifndef IXL_QUEUE_NUM 716 1.19 yamaguch #define IXL_QUEUE_NUM 0 717 1.19 yamaguch #endif 718 1.19 yamaguch 719 1.92 yamaguch enum ixl_link_flags { 720 1.92 yamaguch IXL_LINK_NOFLAGS = 0, 721 1.92 yamaguch IXL_LINK_FLAG_WAITDONE = __BIT(0), 722 1.92 yamaguch }; 723 1.92 yamaguch 724 1.19 yamaguch static bool ixl_param_nomsix = false; 725 1.19 yamaguch static int ixl_param_stats_interval = IXL_STATS_INTERVAL_MSEC; 726 1.19 yamaguch static int ixl_param_nqps_limit = IXL_QUEUE_NUM; 727 1.73 yamaguch static unsigned int ixl_param_tx_ndescs = 512; 728 1.86 knakahar static unsigned int ixl_param_rx_ndescs = 512; 729 1.1 yamaguch 730 1.1 yamaguch static enum i40e_mac_type 731 1.68 yamaguch ixl_mactype(pci_product_id_t); 732 1.68 yamaguch static void ixl_pci_csr_setup(pci_chipset_tag_t, pcitag_t); 733 1.1 yamaguch static void ixl_clear_hw(struct ixl_softc *); 734 1.1 yamaguch static int ixl_pf_reset(struct ixl_softc *); 735 1.1 yamaguch 736 1.1 yamaguch static int ixl_dmamem_alloc(struct ixl_softc *, struct ixl_dmamem *, 737 1.1 yamaguch bus_size_t, bus_size_t); 738 1.1 yamaguch static void ixl_dmamem_free(struct ixl_softc *, struct ixl_dmamem *); 739 1.1 yamaguch 740 1.1 yamaguch static int ixl_arq_fill(struct ixl_softc *); 741 1.1 yamaguch static void ixl_arq_unfill(struct ixl_softc *); 742 1.1 yamaguch 743 1.1 yamaguch static int ixl_atq_poll(struct ixl_softc *, struct ixl_aq_desc *, 744 1.1 yamaguch unsigned int); 745 1.4 yamaguch static void ixl_atq_set(struct ixl_atq *, 746 1.4 yamaguch void (*)(struct ixl_softc *, const struct ixl_aq_desc *)); 747 1.92 yamaguch static void ixl_wakeup(struct ixl_softc *, const struct ixl_aq_desc *); 748 1.1 yamaguch static int ixl_atq_post_locked(struct ixl_softc *, struct ixl_atq *); 749 1.1 yamaguch static void ixl_atq_done(struct ixl_softc *); 750 1.1 yamaguch static int ixl_atq_exec(struct ixl_softc *, struct ixl_atq *); 751 1.59 yamaguch static int ixl_atq_exec_locked(struct ixl_softc *, struct ixl_atq *); 752 1.1 yamaguch static int ixl_get_version(struct ixl_softc *); 753 1.26 yamaguch static int ixl_get_nvm_version(struct ixl_softc *); 754 1.1 yamaguch static int ixl_get_hw_capabilities(struct ixl_softc *); 755 1.1 yamaguch static int ixl_pxe_clear(struct ixl_softc *); 756 1.1 yamaguch static int ixl_lldp_shut(struct ixl_softc *); 757 1.1 yamaguch static int ixl_get_mac(struct ixl_softc *); 758 1.1 yamaguch static int ixl_get_switch_config(struct ixl_softc *); 759 1.1 yamaguch static int ixl_phy_mask_ints(struct ixl_softc *); 760 1.31 yamaguch static int ixl_get_phy_info(struct ixl_softc *); 761 1.31 yamaguch static int ixl_set_phy_config(struct ixl_softc *, uint8_t, uint8_t, bool); 762 1.31 yamaguch static int ixl_set_phy_autoselect(struct ixl_softc *); 763 1.1 yamaguch static int ixl_restart_an(struct ixl_softc *); 764 1.1 yamaguch static int ixl_hmc(struct ixl_softc *); 765 1.1 yamaguch static void ixl_hmc_free(struct ixl_softc *); 766 1.1 yamaguch static int ixl_get_vsi(struct ixl_softc *); 767 1.1 yamaguch static int ixl_set_vsi(struct ixl_softc *); 768 1.1 yamaguch static void ixl_set_filter_control(struct ixl_softc *); 769 1.92 yamaguch static int ixl_get_link_status(struct ixl_softc *, enum ixl_link_flags); 770 1.92 yamaguch static void ixl_get_link_status_work(void *); 771 1.37 yamaguch static int ixl_get_link_status_poll(struct ixl_softc *, int *); 772 1.57 yamaguch static void ixl_get_link_status_done(struct ixl_softc *, 773 1.57 yamaguch const struct ixl_aq_desc *); 774 1.92 yamaguch static void ixl_get_link_status_done_work(void *); 775 1.62 yamaguch static int ixl_set_link_status_locked(struct ixl_softc *, 776 1.1 yamaguch const struct ixl_aq_desc *); 777 1.31 yamaguch static uint64_t ixl_search_link_speed(uint8_t); 778 1.31 yamaguch static uint8_t ixl_search_baudrate(uint64_t); 779 1.1 yamaguch static void ixl_config_rss(struct ixl_softc *); 780 1.1 yamaguch static int ixl_add_macvlan(struct ixl_softc *, const uint8_t *, 781 1.1 yamaguch uint16_t, uint16_t); 782 1.12 yamaguch static int ixl_remove_macvlan(struct ixl_softc *, const uint8_t *, 783 1.12 yamaguch uint16_t, uint16_t); 784 1.1 yamaguch static void ixl_arq(void *); 785 1.1 yamaguch static void ixl_hmc_pack(void *, const void *, 786 1.1 yamaguch const struct ixl_hmc_pack *, unsigned int); 787 1.1 yamaguch static uint32_t ixl_rd_rx_csr(struct ixl_softc *, uint32_t); 788 1.1 yamaguch static void ixl_wr_rx_csr(struct ixl_softc *, uint32_t, uint32_t); 789 1.26 yamaguch static int ixl_rd16_nvm(struct ixl_softc *, uint16_t, uint16_t *); 790 1.1 yamaguch 791 1.1 yamaguch static int ixl_match(device_t, cfdata_t, void *); 792 1.1 yamaguch static void ixl_attach(device_t, device_t, void *); 793 1.1 yamaguch static int ixl_detach(device_t, int); 794 1.1 yamaguch 795 1.31 yamaguch static void ixl_media_add(struct ixl_softc *); 796 1.1 yamaguch static int ixl_media_change(struct ifnet *); 797 1.1 yamaguch static void ixl_media_status(struct ifnet *, struct ifmediareq *); 798 1.1 yamaguch static int ixl_ioctl(struct ifnet *, u_long, void *); 799 1.1 yamaguch static void ixl_start(struct ifnet *); 800 1.1 yamaguch static int ixl_transmit(struct ifnet *, struct mbuf *); 801 1.1 yamaguch static void ixl_deferred_transmit(void *); 802 1.1 yamaguch static int ixl_intr(void *); 803 1.1 yamaguch static int ixl_queue_intr(void *); 804 1.1 yamaguch static int ixl_other_intr(void *); 805 1.1 yamaguch static void ixl_handle_queue(void *); 806 1.45 yamaguch static void ixl_handle_queue_wk(struct work *, void *); 807 1.1 yamaguch static void ixl_sched_handle_queue(struct ixl_softc *, 808 1.1 yamaguch struct ixl_queue_pair *); 809 1.1 yamaguch static int ixl_init(struct ifnet *); 810 1.1 yamaguch static int ixl_init_locked(struct ixl_softc *); 811 1.1 yamaguch static void ixl_stop(struct ifnet *, int); 812 1.1 yamaguch static void ixl_stop_locked(struct ixl_softc *); 813 1.1 yamaguch static int ixl_iff(struct ixl_softc *); 814 1.1 yamaguch static int ixl_ifflags_cb(struct ethercom *); 815 1.1 yamaguch static int ixl_setup_interrupts(struct ixl_softc *); 816 1.1 yamaguch static int ixl_establish_intx(struct ixl_softc *); 817 1.1 yamaguch static int ixl_establish_msix(struct ixl_softc *); 818 1.1 yamaguch static void ixl_enable_queue_intr(struct ixl_softc *, 819 1.1 yamaguch struct ixl_queue_pair *); 820 1.1 yamaguch static void ixl_disable_queue_intr(struct ixl_softc *, 821 1.1 yamaguch struct ixl_queue_pair *); 822 1.1 yamaguch static void ixl_enable_other_intr(struct ixl_softc *); 823 1.1 yamaguch static void ixl_disable_other_intr(struct ixl_softc *); 824 1.1 yamaguch static void ixl_config_queue_intr(struct ixl_softc *); 825 1.1 yamaguch static void ixl_config_other_intr(struct ixl_softc *); 826 1.1 yamaguch 827 1.1 yamaguch static struct ixl_tx_ring * 828 1.1 yamaguch ixl_txr_alloc(struct ixl_softc *, unsigned int); 829 1.1 yamaguch static void ixl_txr_qdis(struct ixl_softc *, struct ixl_tx_ring *, int); 830 1.1 yamaguch static void ixl_txr_config(struct ixl_softc *, struct ixl_tx_ring *); 831 1.1 yamaguch static int ixl_txr_enabled(struct ixl_softc *, struct ixl_tx_ring *); 832 1.1 yamaguch static int ixl_txr_disabled(struct ixl_softc *, struct ixl_tx_ring *); 833 1.1 yamaguch static void ixl_txr_unconfig(struct ixl_softc *, struct ixl_tx_ring *); 834 1.1 yamaguch static void ixl_txr_clean(struct ixl_softc *, struct ixl_tx_ring *); 835 1.1 yamaguch static void ixl_txr_free(struct ixl_softc *, struct ixl_tx_ring *); 836 1.1 yamaguch static int ixl_txeof(struct ixl_softc *, struct ixl_tx_ring *, u_int); 837 1.1 yamaguch 838 1.1 yamaguch static struct ixl_rx_ring * 839 1.1 yamaguch ixl_rxr_alloc(struct ixl_softc *, unsigned int); 840 1.1 yamaguch static void ixl_rxr_config(struct ixl_softc *, struct ixl_rx_ring *); 841 1.1 yamaguch static int ixl_rxr_enabled(struct ixl_softc *, struct ixl_rx_ring *); 842 1.1 yamaguch static int ixl_rxr_disabled(struct ixl_softc *, struct ixl_rx_ring *); 843 1.1 yamaguch static void ixl_rxr_unconfig(struct ixl_softc *, struct ixl_rx_ring *); 844 1.1 yamaguch static void ixl_rxr_clean(struct ixl_softc *, struct ixl_rx_ring *); 845 1.1 yamaguch static void ixl_rxr_free(struct ixl_softc *, struct ixl_rx_ring *); 846 1.1 yamaguch static int ixl_rxeof(struct ixl_softc *, struct ixl_rx_ring *, u_int); 847 1.1 yamaguch static int ixl_rxfill(struct ixl_softc *, struct ixl_rx_ring *); 848 1.1 yamaguch 849 1.1 yamaguch static struct workqueue * 850 1.1 yamaguch ixl_workq_create(const char *, pri_t, int, int); 851 1.1 yamaguch static void ixl_workq_destroy(struct workqueue *); 852 1.1 yamaguch static int ixl_workqs_teardown(device_t); 853 1.1 yamaguch static void ixl_work_set(struct ixl_work *, void (*)(void *), void *); 854 1.1 yamaguch static void ixl_work_add(struct workqueue *, struct ixl_work *); 855 1.1 yamaguch static void ixl_work_wait(struct workqueue *, struct ixl_work *); 856 1.1 yamaguch static void ixl_workq_work(struct work *, void *); 857 1.1 yamaguch static const struct ixl_product * 858 1.1 yamaguch ixl_lookup(const struct pci_attach_args *pa); 859 1.4 yamaguch static void ixl_link_state_update(struct ixl_softc *, 860 1.4 yamaguch const struct ixl_aq_desc *); 861 1.12 yamaguch static int ixl_vlan_cb(struct ethercom *, uint16_t, bool); 862 1.12 yamaguch static int ixl_setup_vlan_hwfilter(struct ixl_softc *); 863 1.12 yamaguch static void ixl_teardown_vlan_hwfilter(struct ixl_softc *); 864 1.12 yamaguch static int ixl_update_macvlan(struct ixl_softc *); 865 1.66 msaitoh static int ixl_setup_interrupts(struct ixl_softc *); 866 1.1 yamaguch static void ixl_teardown_interrupts(struct ixl_softc *); 867 1.1 yamaguch static int ixl_setup_stats(struct ixl_softc *); 868 1.1 yamaguch static void ixl_teardown_stats(struct ixl_softc *); 869 1.17 yamaguch static void ixl_stats_callout(void *); 870 1.17 yamaguch static void ixl_stats_update(void *); 871 1.1 yamaguch static int ixl_setup_sysctls(struct ixl_softc *); 872 1.1 yamaguch static void ixl_teardown_sysctls(struct ixl_softc *); 873 1.69 yamaguch static int ixl_sysctl_itr_handler(SYSCTLFN_PROTO); 874 1.1 yamaguch static int ixl_queue_pairs_alloc(struct ixl_softc *); 875 1.1 yamaguch static void ixl_queue_pairs_free(struct ixl_softc *); 876 1.1 yamaguch 877 1.1 yamaguch static const struct ixl_phy_type ixl_phy_type_map[] = { 878 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_SGMII, IFM_1000_SGMII }, 879 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_1000BASE_KX, IFM_1000_KX }, 880 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_10GBASE_KX4, IFM_10G_KX4 }, 881 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_10GBASE_KR, IFM_10G_KR }, 882 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_40GBASE_KR4, IFM_40G_KR4 }, 883 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_XAUI | 884 1.1 yamaguch 1ULL << IXL_PHY_TYPE_XFI, IFM_10G_CX4 }, 885 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_SFI, IFM_10G_SFI }, 886 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_XLAUI | 887 1.1 yamaguch 1ULL << IXL_PHY_TYPE_XLPPI, IFM_40G_XLPPI }, 888 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_40GBASE_CR4_CU | 889 1.1 yamaguch 1ULL << IXL_PHY_TYPE_40GBASE_CR4, IFM_40G_CR4 }, 890 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_10GBASE_CR1_CU | 891 1.1 yamaguch 1ULL << IXL_PHY_TYPE_10GBASE_CR1, IFM_10G_CR1 }, 892 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_10GBASE_AOC, IFM_10G_AOC }, 893 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_40GBASE_AOC, IFM_40G_AOC }, 894 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_100BASE_TX, IFM_100_TX }, 895 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_1000BASE_T_OPTICAL | 896 1.1 yamaguch 1ULL << IXL_PHY_TYPE_1000BASE_T, IFM_1000_T }, 897 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_10GBASE_T, IFM_10G_T }, 898 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_10GBASE_SR, IFM_10G_SR }, 899 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_10GBASE_LR, IFM_10G_LR }, 900 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_10GBASE_SFPP_CU, IFM_10G_TWINAX }, 901 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_40GBASE_SR4, IFM_40G_SR4 }, 902 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_40GBASE_LR4, IFM_40G_LR4 }, 903 1.34 yamaguch { 1ULL << IXL_PHY_TYPE_1000BASE_SX, IFM_1000_SX }, 904 1.34 yamaguch { 1ULL << IXL_PHY_TYPE_1000BASE_LX, IFM_1000_LX }, 905 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_20GBASE_KR2, IFM_20G_KR2 }, 906 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_25GBASE_KR, IFM_25G_KR }, 907 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_25GBASE_CR, IFM_25G_CR }, 908 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_25GBASE_SR, IFM_25G_SR }, 909 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_25GBASE_LR, IFM_25G_LR }, 910 1.1 yamaguch { 1ULL << IXL_PHY_TYPE_25GBASE_AOC, IFM_25G_AOC }, 911 1.55 yamaguch { 1ULL << IXL_PHY_TYPE_25GBASE_ACC, IFM_25G_ACC }, 912 1.78 yamaguch { 1ULL << IXL_PHY_TYPE_2500BASE_T_1, IFM_2500_T }, 913 1.78 yamaguch { 1ULL << IXL_PHY_TYPE_5000BASE_T_1, IFM_5000_T }, 914 1.78 yamaguch { 1ULL << IXL_PHY_TYPE_2500BASE_T_2, IFM_2500_T }, 915 1.78 yamaguch { 1ULL << IXL_PHY_TYPE_5000BASE_T_2, IFM_5000_T }, 916 1.1 yamaguch }; 917 1.1 yamaguch 918 1.1 yamaguch static const struct ixl_speed_type ixl_speed_type_map[] = { 919 1.1 yamaguch { IXL_AQ_LINK_SPEED_40GB, IF_Gbps(40) }, 920 1.1 yamaguch { IXL_AQ_LINK_SPEED_25GB, IF_Gbps(25) }, 921 1.1 yamaguch { IXL_AQ_LINK_SPEED_10GB, IF_Gbps(10) }, 922 1.78 yamaguch { IXL_AQ_LINK_SPEED_5000MB, IF_Mbps(5000) }, 923 1.78 yamaguch { IXL_AQ_LINK_SPEED_2500MB, IF_Mbps(2500) }, 924 1.1 yamaguch { IXL_AQ_LINK_SPEED_1000MB, IF_Mbps(1000) }, 925 1.1 yamaguch { IXL_AQ_LINK_SPEED_100MB, IF_Mbps(100)}, 926 1.1 yamaguch }; 927 1.1 yamaguch 928 1.1 yamaguch static const struct ixl_aq_regs ixl_pf_aq_regs = { 929 1.1 yamaguch .atq_tail = I40E_PF_ATQT, 930 1.1 yamaguch .atq_tail_mask = I40E_PF_ATQT_ATQT_MASK, 931 1.1 yamaguch .atq_head = I40E_PF_ATQH, 932 1.1 yamaguch .atq_head_mask = I40E_PF_ATQH_ATQH_MASK, 933 1.1 yamaguch .atq_len = I40E_PF_ATQLEN, 934 1.1 yamaguch .atq_bal = I40E_PF_ATQBAL, 935 1.1 yamaguch .atq_bah = I40E_PF_ATQBAH, 936 1.1 yamaguch .atq_len_enable = I40E_PF_ATQLEN_ATQENABLE_MASK, 937 1.1 yamaguch 938 1.1 yamaguch .arq_tail = I40E_PF_ARQT, 939 1.1 yamaguch .arq_tail_mask = I40E_PF_ARQT_ARQT_MASK, 940 1.1 yamaguch .arq_head = I40E_PF_ARQH, 941 1.1 yamaguch .arq_head_mask = I40E_PF_ARQH_ARQH_MASK, 942 1.1 yamaguch .arq_len = I40E_PF_ARQLEN, 943 1.1 yamaguch .arq_bal = I40E_PF_ARQBAL, 944 1.1 yamaguch .arq_bah = I40E_PF_ARQBAH, 945 1.1 yamaguch .arq_len_enable = I40E_PF_ARQLEN_ARQENABLE_MASK, 946 1.1 yamaguch }; 947 1.1 yamaguch 948 1.1 yamaguch #define ixl_rd(_s, _r) \ 949 1.1 yamaguch bus_space_read_4((_s)->sc_memt, (_s)->sc_memh, (_r)) 950 1.1 yamaguch #define ixl_wr(_s, _r, _v) \ 951 1.1 yamaguch bus_space_write_4((_s)->sc_memt, (_s)->sc_memh, (_r), (_v)) 952 1.1 yamaguch #define ixl_barrier(_s, _r, _l, _o) \ 953 1.1 yamaguch bus_space_barrier((_s)->sc_memt, (_s)->sc_memh, (_r), (_l), (_o)) 954 1.1 yamaguch #define ixl_flush(_s) (void)ixl_rd((_s), I40E_GLGEN_STAT) 955 1.1 yamaguch #define ixl_nqueues(_sc) (1 << ((_sc)->sc_nqueue_pairs - 1)) 956 1.2 yamaguch 957 1.1 yamaguch CFATTACH_DECL3_NEW(ixl, sizeof(struct ixl_softc), 958 1.1 yamaguch ixl_match, ixl_attach, ixl_detach, NULL, NULL, NULL, 959 1.1 yamaguch DVF_DETACH_SHUTDOWN); 960 1.1 yamaguch 961 1.1 yamaguch static const struct ixl_product ixl_products[] = { 962 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_XL710_SFP }, 963 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_XL710_KX_B }, 964 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_XL710_KX_C }, 965 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_XL710_QSFP_A }, 966 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_XL710_QSFP_B }, 967 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_XL710_QSFP_C }, 968 1.78 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_X710_10G_T_1 }, 969 1.78 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_X710_10G_T_2 }, 970 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_XL710_20G_BP_1 }, 971 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_XL710_20G_BP_2 }, 972 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_X710_T4_10G }, 973 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_XXV710_25G_BP }, 974 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_XXV710_25G_SFP28 }, 975 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_X722_KX }, 976 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_X722_QSFP }, 977 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_X722_SFP }, 978 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_X722_1G_BASET }, 979 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_X722_10G_BASET }, 980 1.1 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_X722_I_SFP }, 981 1.78 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_X710_10G_SFP }, 982 1.78 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_X710_10G_BP }, 983 1.79 yamaguch { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_V710_5G_T}, 984 1.1 yamaguch /* required last entry */ 985 1.1 yamaguch {0, 0} 986 1.1 yamaguch }; 987 1.1 yamaguch 988 1.1 yamaguch static const struct ixl_product * 989 1.1 yamaguch ixl_lookup(const struct pci_attach_args *pa) 990 1.1 yamaguch { 991 1.1 yamaguch const struct ixl_product *ixlp; 992 1.1 yamaguch 993 1.1 yamaguch for (ixlp = ixl_products; ixlp->vendor_id != 0; ixlp++) { 994 1.1 yamaguch if (PCI_VENDOR(pa->pa_id) == ixlp->vendor_id && 995 1.1 yamaguch PCI_PRODUCT(pa->pa_id) == ixlp->product_id) 996 1.1 yamaguch return ixlp; 997 1.1 yamaguch } 998 1.1 yamaguch 999 1.1 yamaguch return NULL; 1000 1.1 yamaguch } 1001 1.1 yamaguch 1002 1.81 yamaguch static void 1003 1.81 yamaguch ixl_intr_barrier(void) 1004 1.81 yamaguch { 1005 1.81 yamaguch 1006 1.81 yamaguch /* wait for finish of all handler */ 1007 1.81 yamaguch xc_barrier(0); 1008 1.81 yamaguch } 1009 1.81 yamaguch 1010 1.1 yamaguch static int 1011 1.1 yamaguch ixl_match(device_t parent, cfdata_t match, void *aux) 1012 1.1 yamaguch { 1013 1.1 yamaguch const struct pci_attach_args *pa = aux; 1014 1.1 yamaguch 1015 1.1 yamaguch return (ixl_lookup(pa) != NULL) ? 1 : 0; 1016 1.1 yamaguch } 1017 1.1 yamaguch 1018 1.1 yamaguch static void 1019 1.1 yamaguch ixl_attach(device_t parent, device_t self, void *aux) 1020 1.1 yamaguch { 1021 1.1 yamaguch struct ixl_softc *sc; 1022 1.1 yamaguch struct pci_attach_args *pa = aux; 1023 1.1 yamaguch struct ifnet *ifp; 1024 1.23 yamaguch pcireg_t memtype; 1025 1.1 yamaguch uint32_t firstq, port, ari, func; 1026 1.1 yamaguch char xnamebuf[32]; 1027 1.37 yamaguch int tries, rv, link; 1028 1.1 yamaguch 1029 1.1 yamaguch sc = device_private(self); 1030 1.1 yamaguch sc->sc_dev = self; 1031 1.1 yamaguch ifp = &sc->sc_ec.ec_if; 1032 1.1 yamaguch 1033 1.1 yamaguch sc->sc_pa = *pa; 1034 1.1 yamaguch sc->sc_dmat = (pci_dma64_available(pa)) ? 1035 1.1 yamaguch pa->pa_dmat64 : pa->pa_dmat; 1036 1.1 yamaguch sc->sc_aq_regs = &ixl_pf_aq_regs; 1037 1.1 yamaguch 1038 1.23 yamaguch sc->sc_mac_type = ixl_mactype(PCI_PRODUCT(pa->pa_id)); 1039 1.1 yamaguch 1040 1.68 yamaguch ixl_pci_csr_setup(pa->pa_pc, pa->pa_tag); 1041 1.68 yamaguch 1042 1.93 rin pci_aprint_devinfo(pa, "Ethernet controller"); 1043 1.93 rin 1044 1.1 yamaguch memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, IXL_PCIREG); 1045 1.1 yamaguch if (pci_mapreg_map(pa, IXL_PCIREG, memtype, 0, 1046 1.1 yamaguch &sc->sc_memt, &sc->sc_memh, NULL, &sc->sc_mems)) { 1047 1.1 yamaguch aprint_error(": unable to map registers\n"); 1048 1.1 yamaguch return; 1049 1.1 yamaguch } 1050 1.1 yamaguch 1051 1.1 yamaguch mutex_init(&sc->sc_cfg_lock, MUTEX_DEFAULT, IPL_SOFTNET); 1052 1.1 yamaguch 1053 1.1 yamaguch firstq = ixl_rd(sc, I40E_PFLAN_QALLOC); 1054 1.1 yamaguch firstq &= I40E_PFLAN_QALLOC_FIRSTQ_MASK; 1055 1.1 yamaguch firstq >>= I40E_PFLAN_QALLOC_FIRSTQ_SHIFT; 1056 1.1 yamaguch sc->sc_base_queue = firstq; 1057 1.1 yamaguch 1058 1.1 yamaguch ixl_clear_hw(sc); 1059 1.1 yamaguch if (ixl_pf_reset(sc) == -1) { 1060 1.1 yamaguch /* error printed by ixl pf_reset */ 1061 1.1 yamaguch goto unmap; 1062 1.1 yamaguch } 1063 1.1 yamaguch 1064 1.1 yamaguch port = ixl_rd(sc, I40E_PFGEN_PORTNUM); 1065 1.1 yamaguch port &= I40E_PFGEN_PORTNUM_PORT_NUM_MASK; 1066 1.1 yamaguch port >>= I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT; 1067 1.17 yamaguch sc->sc_port = port; 1068 1.93 rin aprint_normal_dev(self, "port %u", sc->sc_port); 1069 1.1 yamaguch 1070 1.1 yamaguch ari = ixl_rd(sc, I40E_GLPCI_CAPSUP); 1071 1.1 yamaguch ari &= I40E_GLPCI_CAPSUP_ARI_EN_MASK; 1072 1.1 yamaguch ari >>= I40E_GLPCI_CAPSUP_ARI_EN_SHIFT; 1073 1.1 yamaguch 1074 1.1 yamaguch func = ixl_rd(sc, I40E_PF_FUNC_RID); 1075 1.1 yamaguch sc->sc_pf_id = func & (ari ? 0xff : 0x7); 1076 1.1 yamaguch 1077 1.1 yamaguch /* initialise the adminq */ 1078 1.1 yamaguch 1079 1.1 yamaguch mutex_init(&sc->sc_atq_lock, MUTEX_DEFAULT, IPL_NET); 1080 1.1 yamaguch 1081 1.1 yamaguch if (ixl_dmamem_alloc(sc, &sc->sc_atq, 1082 1.1 yamaguch sizeof(struct ixl_aq_desc) * IXL_AQ_NUM, IXL_AQ_ALIGN) != 0) { 1083 1.1 yamaguch aprint_error("\n" "%s: unable to allocate atq\n", 1084 1.1 yamaguch device_xname(self)); 1085 1.1 yamaguch goto unmap; 1086 1.1 yamaguch } 1087 1.1 yamaguch 1088 1.1 yamaguch SIMPLEQ_INIT(&sc->sc_arq_idle); 1089 1.1 yamaguch ixl_work_set(&sc->sc_arq_task, ixl_arq, sc); 1090 1.1 yamaguch sc->sc_arq_cons = 0; 1091 1.1 yamaguch sc->sc_arq_prod = 0; 1092 1.1 yamaguch 1093 1.1 yamaguch if (ixl_dmamem_alloc(sc, &sc->sc_arq, 1094 1.1 yamaguch sizeof(struct ixl_aq_desc) * IXL_AQ_NUM, IXL_AQ_ALIGN) != 0) { 1095 1.1 yamaguch aprint_error("\n" "%s: unable to allocate arq\n", 1096 1.1 yamaguch device_xname(self)); 1097 1.1 yamaguch goto free_atq; 1098 1.1 yamaguch } 1099 1.1 yamaguch 1100 1.1 yamaguch if (!ixl_arq_fill(sc)) { 1101 1.1 yamaguch aprint_error("\n" "%s: unable to fill arq descriptors\n", 1102 1.1 yamaguch device_xname(self)); 1103 1.1 yamaguch goto free_arq; 1104 1.1 yamaguch } 1105 1.1 yamaguch 1106 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 1107 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), 1108 1.1 yamaguch BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1109 1.1 yamaguch 1110 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq), 1111 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_arq), 1112 1.1 yamaguch BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1113 1.1 yamaguch 1114 1.1 yamaguch for (tries = 0; tries < 10; tries++) { 1115 1.1 yamaguch sc->sc_atq_cons = 0; 1116 1.1 yamaguch sc->sc_atq_prod = 0; 1117 1.1 yamaguch 1118 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_head, 0); 1119 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_head, 0); 1120 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_tail, 0); 1121 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_tail, 0); 1122 1.1 yamaguch 1123 1.1 yamaguch ixl_barrier(sc, 0, sc->sc_mems, BUS_SPACE_BARRIER_WRITE); 1124 1.1 yamaguch 1125 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_bal, 1126 1.1 yamaguch ixl_dmamem_lo(&sc->sc_atq)); 1127 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_bah, 1128 1.1 yamaguch ixl_dmamem_hi(&sc->sc_atq)); 1129 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_len, 1130 1.1 yamaguch sc->sc_aq_regs->atq_len_enable | IXL_AQ_NUM); 1131 1.1 yamaguch 1132 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_bal, 1133 1.1 yamaguch ixl_dmamem_lo(&sc->sc_arq)); 1134 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_bah, 1135 1.1 yamaguch ixl_dmamem_hi(&sc->sc_arq)); 1136 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_len, 1137 1.1 yamaguch sc->sc_aq_regs->arq_len_enable | IXL_AQ_NUM); 1138 1.1 yamaguch 1139 1.1 yamaguch rv = ixl_get_version(sc); 1140 1.1 yamaguch if (rv == 0) 1141 1.1 yamaguch break; 1142 1.1 yamaguch if (rv != ETIMEDOUT) { 1143 1.1 yamaguch aprint_error(", unable to get firmware version\n"); 1144 1.1 yamaguch goto shutdown; 1145 1.1 yamaguch } 1146 1.1 yamaguch 1147 1.1 yamaguch delaymsec(100); 1148 1.1 yamaguch } 1149 1.1 yamaguch 1150 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_tail, sc->sc_arq_prod); 1151 1.1 yamaguch 1152 1.26 yamaguch if (ixl_dmamem_alloc(sc, &sc->sc_aqbuf, IXL_AQ_BUFLEN, 0) != 0) { 1153 1.26 yamaguch aprint_error_dev(self, ", unable to allocate nvm buffer\n"); 1154 1.26 yamaguch goto shutdown; 1155 1.26 yamaguch } 1156 1.26 yamaguch 1157 1.26 yamaguch ixl_get_nvm_version(sc); 1158 1.26 yamaguch 1159 1.1 yamaguch if (sc->sc_mac_type == I40E_MAC_X722) 1160 1.47 yamaguch sc->sc_nqueue_pairs_device = IXL_QUEUE_MAX_X722; 1161 1.1 yamaguch else 1162 1.47 yamaguch sc->sc_nqueue_pairs_device = IXL_QUEUE_MAX_XL710; 1163 1.1 yamaguch 1164 1.1 yamaguch rv = ixl_get_hw_capabilities(sc); 1165 1.1 yamaguch if (rv != 0) { 1166 1.1 yamaguch aprint_error(", GET HW CAPABILITIES %s\n", 1167 1.1 yamaguch rv == ETIMEDOUT ? "timeout" : "error"); 1168 1.26 yamaguch goto free_aqbuf; 1169 1.1 yamaguch } 1170 1.1 yamaguch 1171 1.19 yamaguch sc->sc_nqueue_pairs_max = MIN((int)sc->sc_nqueue_pairs_device, ncpu); 1172 1.19 yamaguch if (ixl_param_nqps_limit > 0) { 1173 1.19 yamaguch sc->sc_nqueue_pairs_max = MIN((int)sc->sc_nqueue_pairs_max, 1174 1.19 yamaguch ixl_param_nqps_limit); 1175 1.19 yamaguch } 1176 1.19 yamaguch 1177 1.19 yamaguch sc->sc_nqueue_pairs = sc->sc_nqueue_pairs_max; 1178 1.19 yamaguch sc->sc_tx_ring_ndescs = ixl_param_tx_ndescs; 1179 1.19 yamaguch sc->sc_rx_ring_ndescs = ixl_param_rx_ndescs; 1180 1.1 yamaguch 1181 1.1 yamaguch KASSERT(IXL_TXRX_PROCESS_UNLIMIT > sc->sc_rx_ring_ndescs); 1182 1.1 yamaguch KASSERT(IXL_TXRX_PROCESS_UNLIMIT > sc->sc_tx_ring_ndescs); 1183 1.70 yamaguch KASSERT(sc->sc_rx_ring_ndescs == 1184 1.70 yamaguch (1U << (fls32(sc->sc_rx_ring_ndescs) - 1))); 1185 1.70 yamaguch KASSERT(sc->sc_tx_ring_ndescs == 1186 1.70 yamaguch (1U << (fls32(sc->sc_tx_ring_ndescs) - 1))); 1187 1.1 yamaguch 1188 1.1 yamaguch if (ixl_get_mac(sc) != 0) { 1189 1.1 yamaguch /* error printed by ixl_get_mac */ 1190 1.26 yamaguch goto free_aqbuf; 1191 1.1 yamaguch } 1192 1.1 yamaguch 1193 1.1 yamaguch aprint_normal("\n"); 1194 1.1 yamaguch aprint_naive("\n"); 1195 1.1 yamaguch 1196 1.1 yamaguch aprint_normal_dev(self, "Ethernet address %s\n", 1197 1.1 yamaguch ether_sprintf(sc->sc_enaddr)); 1198 1.1 yamaguch 1199 1.1 yamaguch rv = ixl_pxe_clear(sc); 1200 1.1 yamaguch if (rv != 0) { 1201 1.1 yamaguch aprint_debug_dev(self, "CLEAR PXE MODE %s\n", 1202 1.1 yamaguch rv == ETIMEDOUT ? "timeout" : "error"); 1203 1.1 yamaguch } 1204 1.1 yamaguch 1205 1.1 yamaguch ixl_set_filter_control(sc); 1206 1.1 yamaguch 1207 1.1 yamaguch if (ixl_hmc(sc) != 0) { 1208 1.1 yamaguch /* error printed by ixl_hmc */ 1209 1.26 yamaguch goto free_aqbuf; 1210 1.1 yamaguch } 1211 1.1 yamaguch 1212 1.1 yamaguch if (ixl_lldp_shut(sc) != 0) { 1213 1.1 yamaguch /* error printed by ixl_lldp_shut */ 1214 1.1 yamaguch goto free_hmc; 1215 1.1 yamaguch } 1216 1.1 yamaguch 1217 1.1 yamaguch if (ixl_phy_mask_ints(sc) != 0) { 1218 1.1 yamaguch /* error printed by ixl_phy_mask_ints */ 1219 1.1 yamaguch goto free_hmc; 1220 1.1 yamaguch } 1221 1.1 yamaguch 1222 1.1 yamaguch if (ixl_restart_an(sc) != 0) { 1223 1.1 yamaguch /* error printed by ixl_restart_an */ 1224 1.1 yamaguch goto free_hmc; 1225 1.1 yamaguch } 1226 1.1 yamaguch 1227 1.1 yamaguch if (ixl_get_switch_config(sc) != 0) { 1228 1.1 yamaguch /* error printed by ixl_get_switch_config */ 1229 1.1 yamaguch goto free_hmc; 1230 1.1 yamaguch } 1231 1.1 yamaguch 1232 1.37 yamaguch rv = ixl_get_link_status_poll(sc, NULL); 1233 1.1 yamaguch if (rv != 0) { 1234 1.1 yamaguch aprint_error_dev(self, "GET LINK STATUS %s\n", 1235 1.1 yamaguch rv == ETIMEDOUT ? "timeout" : "error"); 1236 1.1 yamaguch goto free_hmc; 1237 1.1 yamaguch } 1238 1.1 yamaguch 1239 1.38 yamaguch /* 1240 1.38 yamaguch * The FW often returns EIO in "Get PHY Abilities" command 1241 1.38 yamaguch * if there is no delay 1242 1.38 yamaguch */ 1243 1.38 yamaguch DELAY(500); 1244 1.38 yamaguch if (ixl_get_phy_info(sc) != 0) { 1245 1.38 yamaguch /* error printed by ixl_get_phy_info */ 1246 1.38 yamaguch goto free_hmc; 1247 1.38 yamaguch } 1248 1.38 yamaguch 1249 1.1 yamaguch if (ixl_dmamem_alloc(sc, &sc->sc_scratch, 1250 1.1 yamaguch sizeof(struct ixl_aq_vsi_data), 8) != 0) { 1251 1.1 yamaguch aprint_error_dev(self, "unable to allocate scratch buffer\n"); 1252 1.1 yamaguch goto free_hmc; 1253 1.1 yamaguch } 1254 1.1 yamaguch 1255 1.11 yamaguch rv = ixl_get_vsi(sc); 1256 1.11 yamaguch if (rv != 0) { 1257 1.11 yamaguch aprint_error_dev(self, "GET VSI %s %d\n", 1258 1.11 yamaguch rv == ETIMEDOUT ? "timeout" : "error", rv); 1259 1.1 yamaguch goto free_scratch; 1260 1.1 yamaguch } 1261 1.1 yamaguch 1262 1.11 yamaguch rv = ixl_set_vsi(sc); 1263 1.11 yamaguch if (rv != 0) { 1264 1.11 yamaguch aprint_error_dev(self, "UPDATE VSI error %s %d\n", 1265 1.11 yamaguch rv == ETIMEDOUT ? "timeout" : "error", rv); 1266 1.1 yamaguch goto free_scratch; 1267 1.1 yamaguch } 1268 1.1 yamaguch 1269 1.1 yamaguch if (ixl_queue_pairs_alloc(sc) != 0) { 1270 1.1 yamaguch /* error printed by ixl_queue_pairs_alloc */ 1271 1.1 yamaguch goto free_scratch; 1272 1.1 yamaguch } 1273 1.1 yamaguch 1274 1.1 yamaguch if (ixl_setup_interrupts(sc) != 0) { 1275 1.1 yamaguch /* error printed by ixl_setup_interrupts */ 1276 1.1 yamaguch goto free_queue_pairs; 1277 1.1 yamaguch } 1278 1.1 yamaguch 1279 1.1 yamaguch if (ixl_setup_stats(sc) != 0) { 1280 1.1 yamaguch aprint_error_dev(self, "failed to setup event counters\n"); 1281 1.1 yamaguch goto teardown_intrs; 1282 1.1 yamaguch } 1283 1.1 yamaguch 1284 1.1 yamaguch if (ixl_setup_sysctls(sc) != 0) { 1285 1.1 yamaguch /* error printed by ixl_setup_sysctls */ 1286 1.1 yamaguch goto teardown_stats; 1287 1.1 yamaguch } 1288 1.1 yamaguch 1289 1.1 yamaguch snprintf(xnamebuf, sizeof(xnamebuf), "%s_wq_cfg", device_xname(self)); 1290 1.1 yamaguch sc->sc_workq = ixl_workq_create(xnamebuf, IXL_WORKQUEUE_PRI, 1291 1.44 yamaguch IPL_NET, WQ_MPSAFE); 1292 1.1 yamaguch if (sc->sc_workq == NULL) 1293 1.1 yamaguch goto teardown_sysctls; 1294 1.1 yamaguch 1295 1.1 yamaguch snprintf(xnamebuf, sizeof(xnamebuf), "%s_wq_txrx", device_xname(self)); 1296 1.45 yamaguch rv = workqueue_create(&sc->sc_workq_txrx, xnamebuf, ixl_handle_queue_wk, 1297 1.45 yamaguch sc, IXL_WORKQUEUE_PRI, IPL_NET, WQ_PERCPU | WQ_MPSAFE); 1298 1.45 yamaguch if (rv != 0) { 1299 1.45 yamaguch sc->sc_workq_txrx = NULL; 1300 1.1 yamaguch goto teardown_wqs; 1301 1.45 yamaguch } 1302 1.1 yamaguch 1303 1.1 yamaguch snprintf(xnamebuf, sizeof(xnamebuf), "%s_atq_cv", device_xname(self)); 1304 1.1 yamaguch cv_init(&sc->sc_atq_cv, xnamebuf); 1305 1.1 yamaguch 1306 1.1 yamaguch strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ); 1307 1.1 yamaguch 1308 1.1 yamaguch ifp->if_softc = sc; 1309 1.1 yamaguch ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1310 1.1 yamaguch ifp->if_extflags = IFEF_MPSAFE; 1311 1.1 yamaguch ifp->if_ioctl = ixl_ioctl; 1312 1.1 yamaguch ifp->if_start = ixl_start; 1313 1.1 yamaguch ifp->if_transmit = ixl_transmit; 1314 1.1 yamaguch ifp->if_init = ixl_init; 1315 1.1 yamaguch ifp->if_stop = ixl_stop; 1316 1.1 yamaguch IFQ_SET_MAXLEN(&ifp->if_snd, sc->sc_tx_ring_ndescs); 1317 1.1 yamaguch IFQ_SET_READY(&ifp->if_snd); 1318 1.14 yamaguch ifp->if_capabilities |= IXL_IFCAP_RXCSUM; 1319 1.28 yamaguch ifp->if_capabilities |= IXL_IFCAP_TXCSUM; 1320 1.1 yamaguch #if 0 1321 1.28 yamaguch ifp->if_capabilities |= IFCAP_TSOv4 | IFCAP_TSOv6; 1322 1.1 yamaguch #endif 1323 1.12 yamaguch ether_set_vlan_cb(&sc->sc_ec, ixl_vlan_cb); 1324 1.29 yamaguch sc->sc_ec.ec_capabilities |= ETHERCAP_JUMBO_MTU; 1325 1.94 yamaguch sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU; 1326 1.1 yamaguch sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_HWTAGGING; 1327 1.12 yamaguch sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_HWFILTER; 1328 1.11 yamaguch 1329 1.11 yamaguch sc->sc_ec.ec_capenable = sc->sc_ec.ec_capabilities; 1330 1.12 yamaguch /* Disable VLAN_HWFILTER by default */ 1331 1.12 yamaguch CLR(sc->sc_ec.ec_capenable, ETHERCAP_VLAN_HWFILTER); 1332 1.12 yamaguch 1333 1.11 yamaguch sc->sc_cur_ec_capenable = sc->sc_ec.ec_capenable; 1334 1.1 yamaguch 1335 1.1 yamaguch sc->sc_ec.ec_ifmedia = &sc->sc_media; 1336 1.65 yamaguch ifmedia_init_with_lock(&sc->sc_media, IFM_IMASK, ixl_media_change, 1337 1.65 yamaguch ixl_media_status, &sc->sc_cfg_lock); 1338 1.1 yamaguch 1339 1.31 yamaguch ixl_media_add(sc); 1340 1.1 yamaguch ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL); 1341 1.31 yamaguch if (ISSET(sc->sc_phy_abilities, 1342 1.31 yamaguch (IXL_PHY_ABILITY_PAUSE_TX | IXL_PHY_ABILITY_PAUSE_RX))) { 1343 1.31 yamaguch ifmedia_add(&sc->sc_media, 1344 1.31 yamaguch IFM_ETHER | IFM_AUTO | IFM_FLOW, 0, NULL); 1345 1.31 yamaguch } 1346 1.31 yamaguch ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_NONE, 0, NULL); 1347 1.1 yamaguch ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO); 1348 1.1 yamaguch 1349 1.77 riastrad if_initialize(ifp); 1350 1.71 yamaguch 1351 1.71 yamaguch sc->sc_ipq = if_percpuq_create(ifp); 1352 1.1 yamaguch if_deferred_start_init(ifp, NULL); 1353 1.1 yamaguch ether_ifattach(ifp, sc->sc_enaddr); 1354 1.1 yamaguch ether_set_ifflags_cb(&sc->sc_ec, ixl_ifflags_cb); 1355 1.1 yamaguch 1356 1.37 yamaguch rv = ixl_get_link_status_poll(sc, &link); 1357 1.37 yamaguch if (rv != 0) 1358 1.37 yamaguch link = LINK_STATE_UNKNOWN; 1359 1.37 yamaguch if_link_state_change(ifp, link); 1360 1.37 yamaguch 1361 1.57 yamaguch ixl_atq_set(&sc->sc_link_state_atq, ixl_get_link_status_done); 1362 1.92 yamaguch ixl_work_set(&sc->sc_link_state_task, 1363 1.92 yamaguch ixl_get_link_status_work, sc); 1364 1.92 yamaguch ixl_work_set(&sc->sc_link_state_done_task, 1365 1.92 yamaguch ixl_get_link_status_done_work, sc); 1366 1.1 yamaguch 1367 1.1 yamaguch ixl_config_other_intr(sc); 1368 1.10 yamaguch ixl_enable_other_intr(sc); 1369 1.1 yamaguch 1370 1.31 yamaguch ixl_set_phy_autoselect(sc); 1371 1.31 yamaguch 1372 1.12 yamaguch /* remove default mac filter and replace it so we can see vlans */ 1373 1.12 yamaguch rv = ixl_remove_macvlan(sc, sc->sc_enaddr, 0, 0); 1374 1.12 yamaguch if (rv != ENOENT) { 1375 1.12 yamaguch aprint_debug_dev(self, 1376 1.12 yamaguch "unable to remove macvlan %u\n", rv); 1377 1.12 yamaguch } 1378 1.12 yamaguch rv = ixl_remove_macvlan(sc, sc->sc_enaddr, 0, 1379 1.12 yamaguch IXL_AQ_OP_REMOVE_MACVLAN_IGNORE_VLAN); 1380 1.12 yamaguch if (rv != ENOENT) { 1381 1.12 yamaguch aprint_debug_dev(self, 1382 1.12 yamaguch "unable to remove macvlan, ignore vlan %u\n", rv); 1383 1.12 yamaguch } 1384 1.12 yamaguch 1385 1.12 yamaguch if (ixl_update_macvlan(sc) != 0) { 1386 1.12 yamaguch aprint_debug_dev(self, 1387 1.12 yamaguch "couldn't enable vlan hardware filter\n"); 1388 1.12 yamaguch CLR(sc->sc_ec.ec_capenable, ETHERCAP_VLAN_HWFILTER); 1389 1.12 yamaguch CLR(sc->sc_cur_ec_capenable, ETHERCAP_VLAN_HWFILTER); 1390 1.12 yamaguch } 1391 1.1 yamaguch 1392 1.1 yamaguch sc->sc_txrx_workqueue = true; 1393 1.1 yamaguch sc->sc_tx_process_limit = IXL_TX_PROCESS_LIMIT; 1394 1.1 yamaguch sc->sc_rx_process_limit = IXL_RX_PROCESS_LIMIT; 1395 1.1 yamaguch sc->sc_tx_intr_process_limit = IXL_TX_INTR_PROCESS_LIMIT; 1396 1.1 yamaguch sc->sc_rx_intr_process_limit = IXL_RX_INTR_PROCESS_LIMIT; 1397 1.1 yamaguch 1398 1.17 yamaguch ixl_stats_update(sc); 1399 1.17 yamaguch sc->sc_stats_counters.isc_has_offset = true; 1400 1.17 yamaguch 1401 1.1 yamaguch if (pmf_device_register(self, NULL, NULL) != true) 1402 1.1 yamaguch aprint_debug_dev(self, "couldn't establish power handler\n"); 1403 1.64 yamaguch sc->sc_itr_rx = IXL_ITR_RX; 1404 1.64 yamaguch sc->sc_itr_tx = IXL_ITR_TX; 1405 1.1 yamaguch sc->sc_attached = true; 1406 1.71 yamaguch if_register(ifp); 1407 1.71 yamaguch 1408 1.1 yamaguch return; 1409 1.1 yamaguch 1410 1.1 yamaguch teardown_wqs: 1411 1.1 yamaguch config_finalize_register(self, ixl_workqs_teardown); 1412 1.1 yamaguch teardown_sysctls: 1413 1.1 yamaguch ixl_teardown_sysctls(sc); 1414 1.1 yamaguch teardown_stats: 1415 1.1 yamaguch ixl_teardown_stats(sc); 1416 1.1 yamaguch teardown_intrs: 1417 1.1 yamaguch ixl_teardown_interrupts(sc); 1418 1.1 yamaguch free_queue_pairs: 1419 1.1 yamaguch ixl_queue_pairs_free(sc); 1420 1.1 yamaguch free_scratch: 1421 1.1 yamaguch ixl_dmamem_free(sc, &sc->sc_scratch); 1422 1.1 yamaguch free_hmc: 1423 1.1 yamaguch ixl_hmc_free(sc); 1424 1.26 yamaguch free_aqbuf: 1425 1.26 yamaguch ixl_dmamem_free(sc, &sc->sc_aqbuf); 1426 1.1 yamaguch shutdown: 1427 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_head, 0); 1428 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_head, 0); 1429 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_tail, 0); 1430 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_tail, 0); 1431 1.1 yamaguch 1432 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_bal, 0); 1433 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_bah, 0); 1434 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_len, 0); 1435 1.1 yamaguch 1436 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_bal, 0); 1437 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_bah, 0); 1438 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_len, 0); 1439 1.1 yamaguch 1440 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq), 1441 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_arq), 1442 1.1 yamaguch BUS_DMASYNC_POSTREAD); 1443 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 1444 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), 1445 1.1 yamaguch BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1446 1.1 yamaguch 1447 1.1 yamaguch ixl_arq_unfill(sc); 1448 1.1 yamaguch free_arq: 1449 1.1 yamaguch ixl_dmamem_free(sc, &sc->sc_arq); 1450 1.1 yamaguch free_atq: 1451 1.1 yamaguch ixl_dmamem_free(sc, &sc->sc_atq); 1452 1.1 yamaguch unmap: 1453 1.1 yamaguch mutex_destroy(&sc->sc_atq_lock); 1454 1.1 yamaguch bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems); 1455 1.1 yamaguch mutex_destroy(&sc->sc_cfg_lock); 1456 1.1 yamaguch sc->sc_mems = 0; 1457 1.1 yamaguch 1458 1.1 yamaguch sc->sc_attached = false; 1459 1.1 yamaguch } 1460 1.1 yamaguch 1461 1.1 yamaguch static int 1462 1.1 yamaguch ixl_detach(device_t self, int flags) 1463 1.1 yamaguch { 1464 1.1 yamaguch struct ixl_softc *sc = device_private(self); 1465 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 1466 1.1 yamaguch 1467 1.1 yamaguch if (!sc->sc_attached) 1468 1.1 yamaguch return 0; 1469 1.1 yamaguch 1470 1.1 yamaguch ixl_stop(ifp, 1); 1471 1.1 yamaguch 1472 1.51 yamaguch callout_halt(&sc->sc_stats_callout, NULL); 1473 1.17 yamaguch ixl_work_wait(sc->sc_workq, &sc->sc_stats_task); 1474 1.17 yamaguch 1475 1.82 yamaguch /* detach the I/F before stop adminq due to callbacks */ 1476 1.82 yamaguch ether_ifdetach(ifp); 1477 1.82 yamaguch if_detach(ifp); 1478 1.82 yamaguch ifmedia_fini(&sc->sc_media); 1479 1.82 yamaguch if_percpuq_destroy(sc->sc_ipq); 1480 1.82 yamaguch 1481 1.82 yamaguch ixl_disable_other_intr(sc); 1482 1.82 yamaguch ixl_intr_barrier(); 1483 1.10 yamaguch ixl_work_wait(sc->sc_workq, &sc->sc_arq_task); 1484 1.10 yamaguch ixl_work_wait(sc->sc_workq, &sc->sc_link_state_task); 1485 1.10 yamaguch 1486 1.1 yamaguch if (sc->sc_workq != NULL) { 1487 1.1 yamaguch ixl_workq_destroy(sc->sc_workq); 1488 1.1 yamaguch sc->sc_workq = NULL; 1489 1.1 yamaguch } 1490 1.1 yamaguch 1491 1.1 yamaguch if (sc->sc_workq_txrx != NULL) { 1492 1.45 yamaguch workqueue_destroy(sc->sc_workq_txrx); 1493 1.1 yamaguch sc->sc_workq_txrx = NULL; 1494 1.1 yamaguch } 1495 1.1 yamaguch 1496 1.1 yamaguch ixl_teardown_interrupts(sc); 1497 1.1 yamaguch ixl_teardown_stats(sc); 1498 1.15 yamaguch ixl_teardown_sysctls(sc); 1499 1.1 yamaguch 1500 1.1 yamaguch ixl_queue_pairs_free(sc); 1501 1.1 yamaguch 1502 1.1 yamaguch ixl_dmamem_free(sc, &sc->sc_scratch); 1503 1.1 yamaguch ixl_hmc_free(sc); 1504 1.1 yamaguch 1505 1.1 yamaguch /* shutdown */ 1506 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_head, 0); 1507 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_head, 0); 1508 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_tail, 0); 1509 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_tail, 0); 1510 1.1 yamaguch 1511 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_bal, 0); 1512 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_bah, 0); 1513 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_len, 0); 1514 1.1 yamaguch 1515 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_bal, 0); 1516 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_bah, 0); 1517 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_len, 0); 1518 1.1 yamaguch 1519 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq), 1520 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_arq), 1521 1.1 yamaguch BUS_DMASYNC_POSTREAD); 1522 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 1523 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), 1524 1.1 yamaguch BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1525 1.1 yamaguch 1526 1.1 yamaguch ixl_arq_unfill(sc); 1527 1.1 yamaguch 1528 1.1 yamaguch ixl_dmamem_free(sc, &sc->sc_arq); 1529 1.1 yamaguch ixl_dmamem_free(sc, &sc->sc_atq); 1530 1.26 yamaguch ixl_dmamem_free(sc, &sc->sc_aqbuf); 1531 1.1 yamaguch 1532 1.1 yamaguch cv_destroy(&sc->sc_atq_cv); 1533 1.1 yamaguch mutex_destroy(&sc->sc_atq_lock); 1534 1.1 yamaguch 1535 1.1 yamaguch if (sc->sc_mems != 0) { 1536 1.1 yamaguch bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems); 1537 1.1 yamaguch sc->sc_mems = 0; 1538 1.1 yamaguch } 1539 1.1 yamaguch 1540 1.1 yamaguch mutex_destroy(&sc->sc_cfg_lock); 1541 1.1 yamaguch 1542 1.1 yamaguch return 0; 1543 1.1 yamaguch } 1544 1.1 yamaguch 1545 1.1 yamaguch static int 1546 1.1 yamaguch ixl_workqs_teardown(device_t self) 1547 1.1 yamaguch { 1548 1.1 yamaguch struct ixl_softc *sc = device_private(self); 1549 1.1 yamaguch 1550 1.1 yamaguch if (sc->sc_workq != NULL) { 1551 1.1 yamaguch ixl_workq_destroy(sc->sc_workq); 1552 1.1 yamaguch sc->sc_workq = NULL; 1553 1.1 yamaguch } 1554 1.1 yamaguch 1555 1.1 yamaguch if (sc->sc_workq_txrx != NULL) { 1556 1.45 yamaguch workqueue_destroy(sc->sc_workq_txrx); 1557 1.1 yamaguch sc->sc_workq_txrx = NULL; 1558 1.1 yamaguch } 1559 1.1 yamaguch 1560 1.1 yamaguch return 0; 1561 1.1 yamaguch } 1562 1.1 yamaguch 1563 1.12 yamaguch static int 1564 1.12 yamaguch ixl_vlan_cb(struct ethercom *ec, uint16_t vid, bool set) 1565 1.12 yamaguch { 1566 1.12 yamaguch struct ifnet *ifp = &ec->ec_if; 1567 1.12 yamaguch struct ixl_softc *sc = ifp->if_softc; 1568 1.12 yamaguch int rv; 1569 1.12 yamaguch 1570 1.12 yamaguch if (!ISSET(sc->sc_cur_ec_capenable, ETHERCAP_VLAN_HWFILTER)) { 1571 1.12 yamaguch return 0; 1572 1.12 yamaguch } 1573 1.12 yamaguch 1574 1.12 yamaguch if (set) { 1575 1.12 yamaguch rv = ixl_add_macvlan(sc, sc->sc_enaddr, vid, 1576 1.12 yamaguch IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH); 1577 1.12 yamaguch if (rv == 0) { 1578 1.12 yamaguch rv = ixl_add_macvlan(sc, etherbroadcastaddr, 1579 1.12 yamaguch vid, IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH); 1580 1.12 yamaguch } 1581 1.12 yamaguch } else { 1582 1.12 yamaguch rv = ixl_remove_macvlan(sc, sc->sc_enaddr, vid, 1583 1.12 yamaguch IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH); 1584 1.12 yamaguch (void)ixl_remove_macvlan(sc, etherbroadcastaddr, vid, 1585 1.12 yamaguch IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH); 1586 1.12 yamaguch } 1587 1.12 yamaguch 1588 1.12 yamaguch return rv; 1589 1.12 yamaguch } 1590 1.12 yamaguch 1591 1.1 yamaguch static void 1592 1.31 yamaguch ixl_media_add(struct ixl_softc *sc) 1593 1.1 yamaguch { 1594 1.1 yamaguch struct ifmedia *ifm = &sc->sc_media; 1595 1.1 yamaguch const struct ixl_phy_type *itype; 1596 1.1 yamaguch unsigned int i; 1597 1.31 yamaguch bool flow; 1598 1.31 yamaguch 1599 1.31 yamaguch if (ISSET(sc->sc_phy_abilities, 1600 1.31 yamaguch (IXL_PHY_ABILITY_PAUSE_TX | IXL_PHY_ABILITY_PAUSE_RX))) { 1601 1.31 yamaguch flow = true; 1602 1.31 yamaguch } else { 1603 1.31 yamaguch flow = false; 1604 1.31 yamaguch } 1605 1.1 yamaguch 1606 1.1 yamaguch for (i = 0; i < __arraycount(ixl_phy_type_map); i++) { 1607 1.1 yamaguch itype = &ixl_phy_type_map[i]; 1608 1.1 yamaguch 1609 1.31 yamaguch if (ISSET(sc->sc_phy_types, itype->phy_type)) { 1610 1.1 yamaguch ifmedia_add(ifm, 1611 1.1 yamaguch IFM_ETHER | IFM_FDX | itype->ifm_type, 0, NULL); 1612 1.1 yamaguch 1613 1.31 yamaguch if (flow) { 1614 1.31 yamaguch ifmedia_add(ifm, 1615 1.31 yamaguch IFM_ETHER | IFM_FDX | IFM_FLOW | 1616 1.31 yamaguch itype->ifm_type, 0, NULL); 1617 1.31 yamaguch } 1618 1.31 yamaguch 1619 1.31 yamaguch if (itype->ifm_type != IFM_100_TX) 1620 1.31 yamaguch continue; 1621 1.31 yamaguch 1622 1.31 yamaguch ifmedia_add(ifm, IFM_ETHER | itype->ifm_type, 1623 1.31 yamaguch 0, NULL); 1624 1.31 yamaguch if (flow) { 1625 1.31 yamaguch ifmedia_add(ifm, 1626 1.31 yamaguch IFM_ETHER | IFM_FLOW | itype->ifm_type, 1627 1.1 yamaguch 0, NULL); 1628 1.1 yamaguch } 1629 1.1 yamaguch } 1630 1.1 yamaguch } 1631 1.1 yamaguch } 1632 1.1 yamaguch 1633 1.1 yamaguch static void 1634 1.1 yamaguch ixl_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) 1635 1.1 yamaguch { 1636 1.1 yamaguch struct ixl_softc *sc = ifp->if_softc; 1637 1.1 yamaguch 1638 1.65 yamaguch KASSERT(mutex_owned(&sc->sc_cfg_lock)); 1639 1.65 yamaguch 1640 1.1 yamaguch ifmr->ifm_status = sc->sc_media_status; 1641 1.1 yamaguch ifmr->ifm_active = sc->sc_media_active; 1642 1.1 yamaguch } 1643 1.1 yamaguch 1644 1.1 yamaguch static int 1645 1.1 yamaguch ixl_media_change(struct ifnet *ifp) 1646 1.1 yamaguch { 1647 1.31 yamaguch struct ixl_softc *sc = ifp->if_softc; 1648 1.31 yamaguch struct ifmedia *ifm = &sc->sc_media; 1649 1.31 yamaguch uint64_t ifm_active = sc->sc_media_active; 1650 1.31 yamaguch uint8_t link_speed, abilities; 1651 1.31 yamaguch 1652 1.31 yamaguch switch (IFM_SUBTYPE(ifm_active)) { 1653 1.31 yamaguch case IFM_1000_SGMII: 1654 1.31 yamaguch case IFM_1000_KX: 1655 1.31 yamaguch case IFM_10G_KX4: 1656 1.31 yamaguch case IFM_10G_KR: 1657 1.31 yamaguch case IFM_40G_KR4: 1658 1.31 yamaguch case IFM_20G_KR2: 1659 1.31 yamaguch case IFM_25G_KR: 1660 1.31 yamaguch /* backplanes */ 1661 1.31 yamaguch return EINVAL; 1662 1.31 yamaguch } 1663 1.31 yamaguch 1664 1.31 yamaguch abilities = IXL_PHY_ABILITY_AUTONEGO | IXL_PHY_ABILITY_LINKUP; 1665 1.1 yamaguch 1666 1.31 yamaguch switch (IFM_SUBTYPE(ifm->ifm_media)) { 1667 1.31 yamaguch case IFM_AUTO: 1668 1.31 yamaguch link_speed = sc->sc_phy_linkspeed; 1669 1.31 yamaguch break; 1670 1.31 yamaguch case IFM_NONE: 1671 1.31 yamaguch link_speed = 0; 1672 1.31 yamaguch CLR(abilities, IXL_PHY_ABILITY_LINKUP); 1673 1.31 yamaguch break; 1674 1.31 yamaguch default: 1675 1.31 yamaguch link_speed = ixl_search_baudrate( 1676 1.31 yamaguch ifmedia_baudrate(ifm->ifm_media)); 1677 1.31 yamaguch } 1678 1.31 yamaguch 1679 1.31 yamaguch if (ISSET(abilities, IXL_PHY_ABILITY_LINKUP)) { 1680 1.31 yamaguch if (ISSET(link_speed, sc->sc_phy_linkspeed) == 0) 1681 1.31 yamaguch return EINVAL; 1682 1.31 yamaguch } 1683 1.31 yamaguch 1684 1.31 yamaguch if (ifm->ifm_media & IFM_FLOW) { 1685 1.31 yamaguch abilities |= sc->sc_phy_abilities & 1686 1.31 yamaguch (IXL_PHY_ABILITY_PAUSE_TX | IXL_PHY_ABILITY_PAUSE_RX); 1687 1.31 yamaguch } 1688 1.31 yamaguch 1689 1.31 yamaguch return ixl_set_phy_config(sc, link_speed, abilities, false); 1690 1.1 yamaguch } 1691 1.1 yamaguch 1692 1.1 yamaguch 1693 1.1 yamaguch static void 1694 1.1 yamaguch ixl_del_all_multiaddr(struct ixl_softc *sc) 1695 1.1 yamaguch { 1696 1.1 yamaguch struct ethercom *ec = &sc->sc_ec; 1697 1.1 yamaguch struct ether_multi *enm; 1698 1.1 yamaguch struct ether_multistep step; 1699 1.1 yamaguch 1700 1.1 yamaguch ETHER_LOCK(ec); 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 ixl_remove_macvlan(sc, enm->enm_addrlo, 0, 1704 1.1 yamaguch IXL_AQ_OP_REMOVE_MACVLAN_IGNORE_VLAN); 1705 1.1 yamaguch } 1706 1.1 yamaguch ETHER_UNLOCK(ec); 1707 1.1 yamaguch } 1708 1.1 yamaguch 1709 1.1 yamaguch static int 1710 1.1 yamaguch ixl_add_multi(struct ixl_softc *sc, uint8_t *addrlo, uint8_t *addrhi) 1711 1.1 yamaguch { 1712 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 1713 1.1 yamaguch int rv; 1714 1.1 yamaguch 1715 1.1 yamaguch if (ISSET(ifp->if_flags, IFF_ALLMULTI)) 1716 1.1 yamaguch return 0; 1717 1.1 yamaguch 1718 1.1 yamaguch if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0) { 1719 1.1 yamaguch ixl_del_all_multiaddr(sc); 1720 1.1 yamaguch SET(ifp->if_flags, IFF_ALLMULTI); 1721 1.8 yamaguch return ENETRESET; 1722 1.1 yamaguch } 1723 1.1 yamaguch 1724 1.12 yamaguch /* multicast address can not use VLAN HWFILTER */ 1725 1.1 yamaguch rv = ixl_add_macvlan(sc, addrlo, 0, 1726 1.1 yamaguch IXL_AQ_OP_ADD_MACVLAN_IGNORE_VLAN); 1727 1.1 yamaguch 1728 1.7 yamaguch if (rv == ENOSPC) { 1729 1.1 yamaguch ixl_del_all_multiaddr(sc); 1730 1.1 yamaguch SET(ifp->if_flags, IFF_ALLMULTI); 1731 1.8 yamaguch return ENETRESET; 1732 1.1 yamaguch } 1733 1.1 yamaguch 1734 1.7 yamaguch return rv; 1735 1.1 yamaguch } 1736 1.1 yamaguch 1737 1.8 yamaguch static int 1738 1.1 yamaguch ixl_del_multi(struct ixl_softc *sc, uint8_t *addrlo, uint8_t *addrhi) 1739 1.1 yamaguch { 1740 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 1741 1.1 yamaguch struct ethercom *ec = &sc->sc_ec; 1742 1.1 yamaguch struct ether_multi *enm, *enm_last; 1743 1.1 yamaguch struct ether_multistep step; 1744 1.8 yamaguch int error, rv = 0; 1745 1.1 yamaguch 1746 1.1 yamaguch if (!ISSET(ifp->if_flags, IFF_ALLMULTI)) { 1747 1.1 yamaguch ixl_remove_macvlan(sc, addrlo, 0, 1748 1.1 yamaguch IXL_AQ_OP_REMOVE_MACVLAN_IGNORE_VLAN); 1749 1.8 yamaguch return 0; 1750 1.1 yamaguch } 1751 1.1 yamaguch 1752 1.1 yamaguch ETHER_LOCK(ec); 1753 1.1 yamaguch for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL; 1754 1.1 yamaguch ETHER_NEXT_MULTI(step, enm)) { 1755 1.1 yamaguch if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 1756 1.1 yamaguch ETHER_ADDR_LEN) != 0) { 1757 1.8 yamaguch goto out; 1758 1.1 yamaguch } 1759 1.1 yamaguch } 1760 1.1 yamaguch 1761 1.1 yamaguch for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL; 1762 1.1 yamaguch ETHER_NEXT_MULTI(step, enm)) { 1763 1.8 yamaguch error = ixl_add_macvlan(sc, enm->enm_addrlo, 0, 1764 1.1 yamaguch IXL_AQ_OP_ADD_MACVLAN_IGNORE_VLAN); 1765 1.8 yamaguch if (error != 0) 1766 1.1 yamaguch break; 1767 1.1 yamaguch } 1768 1.1 yamaguch 1769 1.1 yamaguch if (enm != NULL) { 1770 1.1 yamaguch enm_last = enm; 1771 1.1 yamaguch for (ETHER_FIRST_MULTI(step, ec, enm); enm != NULL; 1772 1.1 yamaguch ETHER_NEXT_MULTI(step, enm)) { 1773 1.1 yamaguch if (enm == enm_last) 1774 1.1 yamaguch break; 1775 1.1 yamaguch 1776 1.1 yamaguch ixl_remove_macvlan(sc, enm->enm_addrlo, 0, 1777 1.1 yamaguch IXL_AQ_OP_REMOVE_MACVLAN_IGNORE_VLAN); 1778 1.1 yamaguch } 1779 1.1 yamaguch } else { 1780 1.1 yamaguch CLR(ifp->if_flags, IFF_ALLMULTI); 1781 1.8 yamaguch rv = ENETRESET; 1782 1.1 yamaguch } 1783 1.1 yamaguch 1784 1.8 yamaguch out: 1785 1.1 yamaguch ETHER_UNLOCK(ec); 1786 1.8 yamaguch return rv; 1787 1.1 yamaguch } 1788 1.1 yamaguch 1789 1.1 yamaguch static int 1790 1.1 yamaguch ixl_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1791 1.1 yamaguch { 1792 1.1 yamaguch struct ifreq *ifr = (struct ifreq *)data; 1793 1.1 yamaguch struct ixl_softc *sc = (struct ixl_softc *)ifp->if_softc; 1794 1.1 yamaguch const struct sockaddr *sa; 1795 1.1 yamaguch uint8_t addrhi[ETHER_ADDR_LEN], addrlo[ETHER_ADDR_LEN]; 1796 1.1 yamaguch int s, error = 0; 1797 1.35 thorpej unsigned int nmtu; 1798 1.1 yamaguch 1799 1.1 yamaguch switch (cmd) { 1800 1.29 yamaguch case SIOCSIFMTU: 1801 1.29 yamaguch nmtu = ifr->ifr_mtu; 1802 1.29 yamaguch 1803 1.29 yamaguch if (nmtu < IXL_MIN_MTU || nmtu > IXL_MAX_MTU) { 1804 1.29 yamaguch error = EINVAL; 1805 1.29 yamaguch break; 1806 1.29 yamaguch } 1807 1.29 yamaguch if (ifp->if_mtu != nmtu) { 1808 1.29 yamaguch s = splnet(); 1809 1.29 yamaguch error = ether_ioctl(ifp, cmd, data); 1810 1.29 yamaguch splx(s); 1811 1.29 yamaguch if (error == ENETRESET) 1812 1.29 yamaguch error = ixl_init(ifp); 1813 1.29 yamaguch } 1814 1.29 yamaguch break; 1815 1.1 yamaguch case SIOCADDMULTI: 1816 1.1 yamaguch sa = ifreq_getaddr(SIOCADDMULTI, ifr); 1817 1.1 yamaguch if (ether_addmulti(sa, &sc->sc_ec) == ENETRESET) { 1818 1.1 yamaguch error = ether_multiaddr(sa, addrlo, addrhi); 1819 1.1 yamaguch if (error != 0) 1820 1.1 yamaguch return error; 1821 1.1 yamaguch 1822 1.8 yamaguch error = ixl_add_multi(sc, addrlo, addrhi); 1823 1.8 yamaguch if (error != 0 && error != ENETRESET) { 1824 1.1 yamaguch ether_delmulti(sa, &sc->sc_ec); 1825 1.1 yamaguch error = EIO; 1826 1.1 yamaguch } 1827 1.1 yamaguch } 1828 1.1 yamaguch break; 1829 1.1 yamaguch 1830 1.1 yamaguch case SIOCDELMULTI: 1831 1.1 yamaguch sa = ifreq_getaddr(SIOCDELMULTI, ifr); 1832 1.1 yamaguch if (ether_delmulti(sa, &sc->sc_ec) == ENETRESET) { 1833 1.1 yamaguch error = ether_multiaddr(sa, addrlo, addrhi); 1834 1.1 yamaguch if (error != 0) 1835 1.1 yamaguch return error; 1836 1.1 yamaguch 1837 1.8 yamaguch error = ixl_del_multi(sc, addrlo, addrhi); 1838 1.1 yamaguch } 1839 1.1 yamaguch break; 1840 1.1 yamaguch 1841 1.1 yamaguch default: 1842 1.1 yamaguch s = splnet(); 1843 1.1 yamaguch error = ether_ioctl(ifp, cmd, data); 1844 1.1 yamaguch splx(s); 1845 1.1 yamaguch } 1846 1.1 yamaguch 1847 1.1 yamaguch if (error == ENETRESET) 1848 1.1 yamaguch error = ixl_iff(sc); 1849 1.1 yamaguch 1850 1.1 yamaguch return error; 1851 1.1 yamaguch } 1852 1.1 yamaguch 1853 1.1 yamaguch static enum i40e_mac_type 1854 1.1 yamaguch ixl_mactype(pci_product_id_t id) 1855 1.1 yamaguch { 1856 1.1 yamaguch 1857 1.1 yamaguch switch (id) { 1858 1.1 yamaguch case PCI_PRODUCT_INTEL_XL710_SFP: 1859 1.1 yamaguch case PCI_PRODUCT_INTEL_XL710_KX_B: 1860 1.1 yamaguch case PCI_PRODUCT_INTEL_XL710_KX_C: 1861 1.1 yamaguch case PCI_PRODUCT_INTEL_XL710_QSFP_A: 1862 1.1 yamaguch case PCI_PRODUCT_INTEL_XL710_QSFP_B: 1863 1.1 yamaguch case PCI_PRODUCT_INTEL_XL710_QSFP_C: 1864 1.78 yamaguch case PCI_PRODUCT_INTEL_X710_10G_T_1: 1865 1.78 yamaguch case PCI_PRODUCT_INTEL_X710_10G_T_2: 1866 1.1 yamaguch case PCI_PRODUCT_INTEL_XL710_20G_BP_1: 1867 1.1 yamaguch case PCI_PRODUCT_INTEL_XL710_20G_BP_2: 1868 1.1 yamaguch case PCI_PRODUCT_INTEL_X710_T4_10G: 1869 1.1 yamaguch case PCI_PRODUCT_INTEL_XXV710_25G_BP: 1870 1.1 yamaguch case PCI_PRODUCT_INTEL_XXV710_25G_SFP28: 1871 1.78 yamaguch case PCI_PRODUCT_INTEL_X710_10G_SFP: 1872 1.78 yamaguch case PCI_PRODUCT_INTEL_X710_10G_BP: 1873 1.1 yamaguch return I40E_MAC_XL710; 1874 1.1 yamaguch 1875 1.1 yamaguch case PCI_PRODUCT_INTEL_X722_KX: 1876 1.1 yamaguch case PCI_PRODUCT_INTEL_X722_QSFP: 1877 1.1 yamaguch case PCI_PRODUCT_INTEL_X722_SFP: 1878 1.1 yamaguch case PCI_PRODUCT_INTEL_X722_1G_BASET: 1879 1.1 yamaguch case PCI_PRODUCT_INTEL_X722_10G_BASET: 1880 1.1 yamaguch case PCI_PRODUCT_INTEL_X722_I_SFP: 1881 1.1 yamaguch return I40E_MAC_X722; 1882 1.1 yamaguch } 1883 1.1 yamaguch 1884 1.1 yamaguch return I40E_MAC_GENERIC; 1885 1.1 yamaguch } 1886 1.1 yamaguch 1887 1.68 yamaguch static void 1888 1.68 yamaguch ixl_pci_csr_setup(pci_chipset_tag_t pc, pcitag_t tag) 1889 1.68 yamaguch { 1890 1.68 yamaguch pcireg_t csr; 1891 1.68 yamaguch 1892 1.68 yamaguch csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 1893 1.68 yamaguch csr |= (PCI_COMMAND_MASTER_ENABLE | 1894 1.68 yamaguch PCI_COMMAND_MEM_ENABLE); 1895 1.68 yamaguch pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr); 1896 1.68 yamaguch } 1897 1.68 yamaguch 1898 1.1 yamaguch static inline void * 1899 1.1 yamaguch ixl_hmc_kva(struct ixl_softc *sc, enum ixl_hmc_types type, unsigned int i) 1900 1.1 yamaguch { 1901 1.1 yamaguch uint8_t *kva = IXL_DMA_KVA(&sc->sc_hmc_pd); 1902 1.1 yamaguch struct ixl_hmc_entry *e = &sc->sc_hmc_entries[type]; 1903 1.1 yamaguch 1904 1.1 yamaguch if (i >= e->hmc_count) 1905 1.1 yamaguch return NULL; 1906 1.1 yamaguch 1907 1.1 yamaguch kva += e->hmc_base; 1908 1.1 yamaguch kva += i * e->hmc_size; 1909 1.1 yamaguch 1910 1.1 yamaguch return kva; 1911 1.1 yamaguch } 1912 1.1 yamaguch 1913 1.1 yamaguch static inline size_t 1914 1.1 yamaguch ixl_hmc_len(struct ixl_softc *sc, enum ixl_hmc_types type) 1915 1.1 yamaguch { 1916 1.1 yamaguch struct ixl_hmc_entry *e = &sc->sc_hmc_entries[type]; 1917 1.1 yamaguch 1918 1.1 yamaguch return e->hmc_size; 1919 1.1 yamaguch } 1920 1.1 yamaguch 1921 1.1 yamaguch static void 1922 1.1 yamaguch ixl_enable_queue_intr(struct ixl_softc *sc, struct ixl_queue_pair *qp) 1923 1.1 yamaguch { 1924 1.1 yamaguch struct ixl_rx_ring *rxr = qp->qp_rxr; 1925 1.1 yamaguch 1926 1.1 yamaguch ixl_wr(sc, I40E_PFINT_DYN_CTLN(rxr->rxr_qid), 1927 1.1 yamaguch I40E_PFINT_DYN_CTLN_INTENA_MASK | 1928 1.1 yamaguch I40E_PFINT_DYN_CTLN_CLEARPBA_MASK | 1929 1.1 yamaguch (IXL_NOITR << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT)); 1930 1.1 yamaguch ixl_flush(sc); 1931 1.1 yamaguch } 1932 1.1 yamaguch 1933 1.1 yamaguch static void 1934 1.1 yamaguch ixl_disable_queue_intr(struct ixl_softc *sc, struct ixl_queue_pair *qp) 1935 1.1 yamaguch { 1936 1.1 yamaguch struct ixl_rx_ring *rxr = qp->qp_rxr; 1937 1.1 yamaguch 1938 1.1 yamaguch ixl_wr(sc, I40E_PFINT_DYN_CTLN(rxr->rxr_qid), 1939 1.1 yamaguch (IXL_NOITR << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT)); 1940 1.1 yamaguch ixl_flush(sc); 1941 1.1 yamaguch } 1942 1.1 yamaguch 1943 1.1 yamaguch static void 1944 1.1 yamaguch ixl_enable_other_intr(struct ixl_softc *sc) 1945 1.1 yamaguch { 1946 1.1 yamaguch 1947 1.1 yamaguch ixl_wr(sc, I40E_PFINT_DYN_CTL0, 1948 1.1 yamaguch I40E_PFINT_DYN_CTL0_INTENA_MASK | 1949 1.1 yamaguch I40E_PFINT_DYN_CTL0_CLEARPBA_MASK | 1950 1.1 yamaguch (IXL_NOITR << I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT)); 1951 1.1 yamaguch ixl_flush(sc); 1952 1.1 yamaguch } 1953 1.1 yamaguch 1954 1.1 yamaguch static void 1955 1.1 yamaguch ixl_disable_other_intr(struct ixl_softc *sc) 1956 1.1 yamaguch { 1957 1.1 yamaguch 1958 1.1 yamaguch ixl_wr(sc, I40E_PFINT_DYN_CTL0, 1959 1.1 yamaguch (IXL_NOITR << I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT)); 1960 1.1 yamaguch ixl_flush(sc); 1961 1.1 yamaguch } 1962 1.1 yamaguch 1963 1.1 yamaguch static int 1964 1.1 yamaguch ixl_reinit(struct ixl_softc *sc) 1965 1.1 yamaguch { 1966 1.1 yamaguch struct ixl_rx_ring *rxr; 1967 1.1 yamaguch struct ixl_tx_ring *txr; 1968 1.1 yamaguch unsigned int i; 1969 1.1 yamaguch uint32_t reg; 1970 1.1 yamaguch 1971 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_cfg_lock)); 1972 1.1 yamaguch 1973 1.11 yamaguch if (ixl_get_vsi(sc) != 0) 1974 1.11 yamaguch return EIO; 1975 1.11 yamaguch 1976 1.11 yamaguch if (ixl_set_vsi(sc) != 0) 1977 1.11 yamaguch return EIO; 1978 1.11 yamaguch 1979 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 1980 1.1 yamaguch txr = sc->sc_qps[i].qp_txr; 1981 1.1 yamaguch rxr = sc->sc_qps[i].qp_rxr; 1982 1.1 yamaguch 1983 1.1 yamaguch ixl_txr_config(sc, txr); 1984 1.1 yamaguch ixl_rxr_config(sc, rxr); 1985 1.1 yamaguch } 1986 1.1 yamaguch 1987 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_hmc_pd), 1988 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_hmc_pd), BUS_DMASYNC_PREWRITE); 1989 1.1 yamaguch 1990 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 1991 1.1 yamaguch txr = sc->sc_qps[i].qp_txr; 1992 1.1 yamaguch rxr = sc->sc_qps[i].qp_rxr; 1993 1.1 yamaguch 1994 1.1 yamaguch ixl_wr(sc, I40E_QTX_CTL(i), I40E_QTX_CTL_PF_QUEUE | 1995 1.1 yamaguch (sc->sc_pf_id << I40E_QTX_CTL_PF_INDX_SHIFT)); 1996 1.1 yamaguch ixl_flush(sc); 1997 1.1 yamaguch 1998 1.1 yamaguch ixl_wr(sc, txr->txr_tail, txr->txr_prod); 1999 1.1 yamaguch ixl_wr(sc, rxr->rxr_tail, rxr->rxr_prod); 2000 1.1 yamaguch 2001 1.1 yamaguch /* ixl_rxfill() needs lock held */ 2002 1.1 yamaguch mutex_enter(&rxr->rxr_lock); 2003 1.1 yamaguch ixl_rxfill(sc, rxr); 2004 1.1 yamaguch mutex_exit(&rxr->rxr_lock); 2005 1.1 yamaguch 2006 1.1 yamaguch reg = ixl_rd(sc, I40E_QRX_ENA(i)); 2007 1.1 yamaguch SET(reg, I40E_QRX_ENA_QENA_REQ_MASK); 2008 1.1 yamaguch ixl_wr(sc, I40E_QRX_ENA(i), reg); 2009 1.1 yamaguch if (ixl_rxr_enabled(sc, rxr) != 0) 2010 1.1 yamaguch goto stop; 2011 1.1 yamaguch 2012 1.1 yamaguch ixl_txr_qdis(sc, txr, 1); 2013 1.1 yamaguch 2014 1.1 yamaguch reg = ixl_rd(sc, I40E_QTX_ENA(i)); 2015 1.1 yamaguch SET(reg, I40E_QTX_ENA_QENA_REQ_MASK); 2016 1.1 yamaguch ixl_wr(sc, I40E_QTX_ENA(i), reg); 2017 1.1 yamaguch 2018 1.1 yamaguch if (ixl_txr_enabled(sc, txr) != 0) 2019 1.1 yamaguch goto stop; 2020 1.1 yamaguch } 2021 1.1 yamaguch 2022 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_hmc_pd), 2023 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_hmc_pd), BUS_DMASYNC_POSTWRITE); 2024 1.1 yamaguch 2025 1.1 yamaguch return 0; 2026 1.1 yamaguch 2027 1.1 yamaguch stop: 2028 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_hmc_pd), 2029 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_hmc_pd), BUS_DMASYNC_POSTWRITE); 2030 1.1 yamaguch 2031 1.1 yamaguch return ETIMEDOUT; 2032 1.1 yamaguch } 2033 1.1 yamaguch 2034 1.1 yamaguch static int 2035 1.1 yamaguch ixl_init_locked(struct ixl_softc *sc) 2036 1.1 yamaguch { 2037 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 2038 1.1 yamaguch unsigned int i; 2039 1.12 yamaguch int error, eccap_change; 2040 1.1 yamaguch 2041 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_cfg_lock)); 2042 1.1 yamaguch 2043 1.11 yamaguch if (ISSET(ifp->if_flags, IFF_RUNNING)) 2044 1.11 yamaguch ixl_stop_locked(sc); 2045 1.11 yamaguch 2046 1.1 yamaguch if (sc->sc_dead) { 2047 1.1 yamaguch return ENXIO; 2048 1.1 yamaguch } 2049 1.1 yamaguch 2050 1.12 yamaguch eccap_change = sc->sc_ec.ec_capenable ^ sc->sc_cur_ec_capenable; 2051 1.12 yamaguch if (ISSET(eccap_change, ETHERCAP_VLAN_HWTAGGING)) 2052 1.12 yamaguch sc->sc_cur_ec_capenable ^= ETHERCAP_VLAN_HWTAGGING; 2053 1.12 yamaguch 2054 1.12 yamaguch if (ISSET(eccap_change, ETHERCAP_VLAN_HWFILTER)) { 2055 1.12 yamaguch if (ixl_update_macvlan(sc) == 0) { 2056 1.12 yamaguch sc->sc_cur_ec_capenable ^= ETHERCAP_VLAN_HWFILTER; 2057 1.12 yamaguch } else { 2058 1.12 yamaguch CLR(sc->sc_ec.ec_capenable, ETHERCAP_VLAN_HWFILTER); 2059 1.12 yamaguch CLR(sc->sc_cur_ec_capenable, ETHERCAP_VLAN_HWFILTER); 2060 1.12 yamaguch } 2061 1.12 yamaguch } 2062 1.11 yamaguch 2063 1.1 yamaguch if (sc->sc_intrtype != PCI_INTR_TYPE_MSIX) 2064 1.1 yamaguch sc->sc_nqueue_pairs = 1; 2065 1.1 yamaguch else 2066 1.1 yamaguch sc->sc_nqueue_pairs = sc->sc_nqueue_pairs_max; 2067 1.1 yamaguch 2068 1.1 yamaguch error = ixl_reinit(sc); 2069 1.1 yamaguch if (error) { 2070 1.1 yamaguch ixl_stop_locked(sc); 2071 1.1 yamaguch return error; 2072 1.1 yamaguch } 2073 1.1 yamaguch 2074 1.1 yamaguch SET(ifp->if_flags, IFF_RUNNING); 2075 1.1 yamaguch CLR(ifp->if_flags, IFF_OACTIVE); 2076 1.4 yamaguch 2077 1.1 yamaguch ixl_config_rss(sc); 2078 1.1 yamaguch ixl_config_queue_intr(sc); 2079 1.1 yamaguch 2080 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 2081 1.1 yamaguch ixl_enable_queue_intr(sc, &sc->sc_qps[i]); 2082 1.1 yamaguch } 2083 1.1 yamaguch 2084 1.1 yamaguch error = ixl_iff(sc); 2085 1.1 yamaguch if (error) { 2086 1.1 yamaguch ixl_stop_locked(sc); 2087 1.1 yamaguch return error; 2088 1.1 yamaguch } 2089 1.1 yamaguch 2090 1.50 yamaguch callout_schedule(&sc->sc_stats_callout, mstohz(sc->sc_stats_intval)); 2091 1.50 yamaguch 2092 1.1 yamaguch return 0; 2093 1.1 yamaguch } 2094 1.1 yamaguch 2095 1.1 yamaguch static int 2096 1.1 yamaguch ixl_init(struct ifnet *ifp) 2097 1.1 yamaguch { 2098 1.1 yamaguch struct ixl_softc *sc = ifp->if_softc; 2099 1.1 yamaguch int error; 2100 1.1 yamaguch 2101 1.1 yamaguch mutex_enter(&sc->sc_cfg_lock); 2102 1.1 yamaguch error = ixl_init_locked(sc); 2103 1.1 yamaguch mutex_exit(&sc->sc_cfg_lock); 2104 1.1 yamaguch 2105 1.92 yamaguch if (error == 0) { 2106 1.92 yamaguch error = ixl_get_link_status(sc, 2107 1.92 yamaguch IXL_LINK_FLAG_WAITDONE); 2108 1.92 yamaguch } 2109 1.63 yamaguch 2110 1.1 yamaguch return error; 2111 1.1 yamaguch } 2112 1.1 yamaguch 2113 1.1 yamaguch static int 2114 1.1 yamaguch ixl_iff(struct ixl_softc *sc) 2115 1.1 yamaguch { 2116 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 2117 1.1 yamaguch struct ixl_atq iatq; 2118 1.1 yamaguch struct ixl_aq_desc *iaq; 2119 1.1 yamaguch struct ixl_aq_vsi_promisc_param *param; 2120 1.12 yamaguch uint16_t flag_add, flag_del; 2121 1.1 yamaguch int error; 2122 1.1 yamaguch 2123 1.1 yamaguch if (!ISSET(ifp->if_flags, IFF_RUNNING)) 2124 1.1 yamaguch return 0; 2125 1.1 yamaguch 2126 1.1 yamaguch memset(&iatq, 0, sizeof(iatq)); 2127 1.1 yamaguch 2128 1.1 yamaguch iaq = &iatq.iatq_desc; 2129 1.1 yamaguch iaq->iaq_opcode = htole16(IXL_AQ_OP_SET_VSI_PROMISC); 2130 1.1 yamaguch 2131 1.1 yamaguch param = (struct ixl_aq_vsi_promisc_param *)&iaq->iaq_param; 2132 1.12 yamaguch param->flags = htole16(0); 2133 1.12 yamaguch 2134 1.12 yamaguch if (!ISSET(sc->sc_cur_ec_capenable, ETHERCAP_VLAN_HWFILTER) 2135 1.12 yamaguch || ISSET(ifp->if_flags, IFF_PROMISC)) { 2136 1.12 yamaguch param->flags |= htole16(IXL_AQ_VSI_PROMISC_FLAG_BCAST | 2137 1.12 yamaguch IXL_AQ_VSI_PROMISC_FLAG_VLAN); 2138 1.12 yamaguch } 2139 1.12 yamaguch 2140 1.1 yamaguch if (ISSET(ifp->if_flags, IFF_PROMISC)) { 2141 1.1 yamaguch param->flags |= htole16(IXL_AQ_VSI_PROMISC_FLAG_UCAST | 2142 1.1 yamaguch IXL_AQ_VSI_PROMISC_FLAG_MCAST); 2143 1.1 yamaguch } else if (ISSET(ifp->if_flags, IFF_ALLMULTI)) { 2144 1.1 yamaguch param->flags |= htole16(IXL_AQ_VSI_PROMISC_FLAG_MCAST); 2145 1.1 yamaguch } 2146 1.1 yamaguch param->valid_flags = htole16(IXL_AQ_VSI_PROMISC_FLAG_UCAST | 2147 1.1 yamaguch IXL_AQ_VSI_PROMISC_FLAG_MCAST | IXL_AQ_VSI_PROMISC_FLAG_BCAST | 2148 1.1 yamaguch IXL_AQ_VSI_PROMISC_FLAG_VLAN); 2149 1.1 yamaguch param->seid = sc->sc_seid; 2150 1.1 yamaguch 2151 1.1 yamaguch error = ixl_atq_exec(sc, &iatq); 2152 1.1 yamaguch if (error) 2153 1.1 yamaguch return error; 2154 1.1 yamaguch 2155 1.1 yamaguch if (iaq->iaq_retval != htole16(IXL_AQ_RC_OK)) 2156 1.1 yamaguch return EIO; 2157 1.1 yamaguch 2158 1.1 yamaguch if (memcmp(sc->sc_enaddr, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN) != 0) { 2159 1.12 yamaguch if (ISSET(sc->sc_cur_ec_capenable, ETHERCAP_VLAN_HWFILTER)) { 2160 1.12 yamaguch flag_add = IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH; 2161 1.12 yamaguch flag_del = IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH; 2162 1.12 yamaguch } else { 2163 1.12 yamaguch flag_add = IXL_AQ_OP_ADD_MACVLAN_IGNORE_VLAN; 2164 1.12 yamaguch flag_del = IXL_AQ_OP_REMOVE_MACVLAN_IGNORE_VLAN; 2165 1.12 yamaguch } 2166 1.12 yamaguch 2167 1.12 yamaguch ixl_remove_macvlan(sc, sc->sc_enaddr, 0, flag_del); 2168 1.1 yamaguch 2169 1.1 yamaguch memcpy(sc->sc_enaddr, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN); 2170 1.12 yamaguch ixl_add_macvlan(sc, sc->sc_enaddr, 0, flag_add); 2171 1.1 yamaguch } 2172 1.1 yamaguch return 0; 2173 1.1 yamaguch } 2174 1.1 yamaguch 2175 1.1 yamaguch static void 2176 1.1 yamaguch ixl_stop_locked(struct ixl_softc *sc) 2177 1.1 yamaguch { 2178 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 2179 1.1 yamaguch struct ixl_rx_ring *rxr; 2180 1.1 yamaguch struct ixl_tx_ring *txr; 2181 1.1 yamaguch unsigned int i; 2182 1.1 yamaguch uint32_t reg; 2183 1.1 yamaguch 2184 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_cfg_lock)); 2185 1.1 yamaguch 2186 1.1 yamaguch CLR(ifp->if_flags, IFF_RUNNING | IFF_OACTIVE); 2187 1.50 yamaguch callout_stop(&sc->sc_stats_callout); 2188 1.1 yamaguch 2189 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 2190 1.1 yamaguch txr = sc->sc_qps[i].qp_txr; 2191 1.1 yamaguch rxr = sc->sc_qps[i].qp_rxr; 2192 1.1 yamaguch 2193 1.1 yamaguch ixl_disable_queue_intr(sc, &sc->sc_qps[i]); 2194 1.1 yamaguch 2195 1.1 yamaguch mutex_enter(&txr->txr_lock); 2196 1.1 yamaguch ixl_txr_qdis(sc, txr, 0); 2197 1.52 yamaguch mutex_exit(&txr->txr_lock); 2198 1.52 yamaguch } 2199 1.52 yamaguch 2200 1.52 yamaguch /* XXX wait at least 400 usec for all tx queues in one go */ 2201 1.52 yamaguch ixl_flush(sc); 2202 1.52 yamaguch DELAY(500); 2203 1.52 yamaguch 2204 1.52 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 2205 1.52 yamaguch txr = sc->sc_qps[i].qp_txr; 2206 1.52 yamaguch rxr = sc->sc_qps[i].qp_rxr; 2207 1.1 yamaguch 2208 1.52 yamaguch mutex_enter(&txr->txr_lock); 2209 1.1 yamaguch reg = ixl_rd(sc, I40E_QTX_ENA(i)); 2210 1.1 yamaguch CLR(reg, I40E_QTX_ENA_QENA_REQ_MASK); 2211 1.1 yamaguch ixl_wr(sc, I40E_QTX_ENA(i), reg); 2212 1.52 yamaguch mutex_exit(&txr->txr_lock); 2213 1.52 yamaguch 2214 1.52 yamaguch mutex_enter(&rxr->rxr_lock); 2215 1.52 yamaguch reg = ixl_rd(sc, I40E_QRX_ENA(i)); 2216 1.52 yamaguch CLR(reg, I40E_QRX_ENA_QENA_REQ_MASK); 2217 1.52 yamaguch ixl_wr(sc, I40E_QRX_ENA(i), reg); 2218 1.52 yamaguch mutex_exit(&rxr->rxr_lock); 2219 1.52 yamaguch } 2220 1.52 yamaguch 2221 1.52 yamaguch /* XXX short wait for all queue disables to settle */ 2222 1.52 yamaguch ixl_flush(sc); 2223 1.52 yamaguch DELAY(50); 2224 1.52 yamaguch 2225 1.52 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 2226 1.52 yamaguch txr = sc->sc_qps[i].qp_txr; 2227 1.52 yamaguch rxr = sc->sc_qps[i].qp_rxr; 2228 1.1 yamaguch 2229 1.52 yamaguch mutex_enter(&txr->txr_lock); 2230 1.1 yamaguch if (ixl_txr_disabled(sc, txr) != 0) { 2231 1.1 yamaguch mutex_exit(&txr->txr_lock); 2232 1.1 yamaguch goto die; 2233 1.1 yamaguch } 2234 1.1 yamaguch mutex_exit(&txr->txr_lock); 2235 1.1 yamaguch 2236 1.1 yamaguch mutex_enter(&rxr->rxr_lock); 2237 1.1 yamaguch if (ixl_rxr_disabled(sc, rxr) != 0) { 2238 1.1 yamaguch mutex_exit(&rxr->rxr_lock); 2239 1.1 yamaguch goto die; 2240 1.1 yamaguch } 2241 1.1 yamaguch mutex_exit(&rxr->rxr_lock); 2242 1.1 yamaguch } 2243 1.1 yamaguch 2244 1.80 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 2245 1.80 yamaguch sc->sc_qps[i].qp_workqueue = false; 2246 1.80 yamaguch workqueue_wait(sc->sc_workq_txrx, 2247 1.80 yamaguch &sc->sc_qps[i].qp_work); 2248 1.80 yamaguch } 2249 1.1 yamaguch 2250 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 2251 1.1 yamaguch txr = sc->sc_qps[i].qp_txr; 2252 1.1 yamaguch rxr = sc->sc_qps[i].qp_rxr; 2253 1.1 yamaguch 2254 1.48 yamaguch mutex_enter(&txr->txr_lock); 2255 1.1 yamaguch ixl_txr_unconfig(sc, txr); 2256 1.48 yamaguch mutex_exit(&txr->txr_lock); 2257 1.48 yamaguch 2258 1.48 yamaguch mutex_enter(&rxr->rxr_lock); 2259 1.1 yamaguch ixl_rxr_unconfig(sc, rxr); 2260 1.48 yamaguch mutex_exit(&rxr->rxr_lock); 2261 1.1 yamaguch 2262 1.1 yamaguch ixl_txr_clean(sc, txr); 2263 1.1 yamaguch ixl_rxr_clean(sc, rxr); 2264 1.1 yamaguch } 2265 1.1 yamaguch 2266 1.1 yamaguch return; 2267 1.1 yamaguch die: 2268 1.1 yamaguch sc->sc_dead = true; 2269 1.1 yamaguch log(LOG_CRIT, "%s: failed to shut down rings", 2270 1.1 yamaguch device_xname(sc->sc_dev)); 2271 1.1 yamaguch return; 2272 1.1 yamaguch } 2273 1.1 yamaguch 2274 1.1 yamaguch static void 2275 1.1 yamaguch ixl_stop(struct ifnet *ifp, int disable) 2276 1.1 yamaguch { 2277 1.1 yamaguch struct ixl_softc *sc = ifp->if_softc; 2278 1.1 yamaguch 2279 1.1 yamaguch mutex_enter(&sc->sc_cfg_lock); 2280 1.1 yamaguch ixl_stop_locked(sc); 2281 1.1 yamaguch mutex_exit(&sc->sc_cfg_lock); 2282 1.1 yamaguch } 2283 1.1 yamaguch 2284 1.1 yamaguch static int 2285 1.1 yamaguch ixl_queue_pairs_alloc(struct ixl_softc *sc) 2286 1.1 yamaguch { 2287 1.1 yamaguch struct ixl_queue_pair *qp; 2288 1.1 yamaguch unsigned int i; 2289 1.1 yamaguch size_t sz; 2290 1.1 yamaguch 2291 1.1 yamaguch sz = sizeof(sc->sc_qps[0]) * sc->sc_nqueue_pairs_max; 2292 1.1 yamaguch sc->sc_qps = kmem_zalloc(sz, KM_SLEEP); 2293 1.1 yamaguch 2294 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs_max; i++) { 2295 1.1 yamaguch qp = &sc->sc_qps[i]; 2296 1.1 yamaguch 2297 1.1 yamaguch qp->qp_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE, 2298 1.1 yamaguch ixl_handle_queue, qp); 2299 1.6 yamaguch if (qp->qp_si == NULL) 2300 1.6 yamaguch goto free; 2301 1.1 yamaguch 2302 1.1 yamaguch qp->qp_txr = ixl_txr_alloc(sc, i); 2303 1.1 yamaguch if (qp->qp_txr == NULL) 2304 1.1 yamaguch goto free; 2305 1.1 yamaguch 2306 1.1 yamaguch qp->qp_rxr = ixl_rxr_alloc(sc, i); 2307 1.1 yamaguch if (qp->qp_rxr == NULL) 2308 1.1 yamaguch goto free; 2309 1.1 yamaguch 2310 1.1 yamaguch qp->qp_sc = sc; 2311 1.1 yamaguch snprintf(qp->qp_name, sizeof(qp->qp_name), 2312 1.1 yamaguch "%s-TXRX%d", device_xname(sc->sc_dev), i); 2313 1.1 yamaguch } 2314 1.1 yamaguch 2315 1.1 yamaguch return 0; 2316 1.1 yamaguch free: 2317 1.1 yamaguch if (sc->sc_qps != NULL) { 2318 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs_max; i++) { 2319 1.1 yamaguch qp = &sc->sc_qps[i]; 2320 1.1 yamaguch 2321 1.1 yamaguch if (qp->qp_txr != NULL) 2322 1.1 yamaguch ixl_txr_free(sc, qp->qp_txr); 2323 1.1 yamaguch if (qp->qp_rxr != NULL) 2324 1.1 yamaguch ixl_rxr_free(sc, qp->qp_rxr); 2325 1.6 yamaguch if (qp->qp_si != NULL) 2326 1.6 yamaguch softint_disestablish(qp->qp_si); 2327 1.1 yamaguch } 2328 1.1 yamaguch 2329 1.1 yamaguch sz = sizeof(sc->sc_qps[0]) * sc->sc_nqueue_pairs_max; 2330 1.1 yamaguch kmem_free(sc->sc_qps, sz); 2331 1.1 yamaguch sc->sc_qps = NULL; 2332 1.1 yamaguch } 2333 1.1 yamaguch 2334 1.1 yamaguch return -1; 2335 1.1 yamaguch } 2336 1.1 yamaguch 2337 1.1 yamaguch static void 2338 1.1 yamaguch ixl_queue_pairs_free(struct ixl_softc *sc) 2339 1.1 yamaguch { 2340 1.1 yamaguch struct ixl_queue_pair *qp; 2341 1.1 yamaguch unsigned int i; 2342 1.1 yamaguch size_t sz; 2343 1.1 yamaguch 2344 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs_max; i++) { 2345 1.1 yamaguch qp = &sc->sc_qps[i]; 2346 1.1 yamaguch ixl_txr_free(sc, qp->qp_txr); 2347 1.1 yamaguch ixl_rxr_free(sc, qp->qp_rxr); 2348 1.6 yamaguch softint_disestablish(qp->qp_si); 2349 1.1 yamaguch } 2350 1.1 yamaguch 2351 1.1 yamaguch sz = sizeof(sc->sc_qps[0]) * sc->sc_nqueue_pairs_max; 2352 1.1 yamaguch kmem_free(sc->sc_qps, sz); 2353 1.1 yamaguch sc->sc_qps = NULL; 2354 1.1 yamaguch } 2355 1.1 yamaguch 2356 1.1 yamaguch static struct ixl_tx_ring * 2357 1.1 yamaguch ixl_txr_alloc(struct ixl_softc *sc, unsigned int qid) 2358 1.1 yamaguch { 2359 1.1 yamaguch struct ixl_tx_ring *txr = NULL; 2360 1.1 yamaguch struct ixl_tx_map *maps = NULL, *txm; 2361 1.1 yamaguch unsigned int i; 2362 1.1 yamaguch 2363 1.1 yamaguch txr = kmem_zalloc(sizeof(*txr), KM_SLEEP); 2364 1.1 yamaguch maps = kmem_zalloc(sizeof(maps[0]) * sc->sc_tx_ring_ndescs, 2365 1.1 yamaguch KM_SLEEP); 2366 1.1 yamaguch 2367 1.1 yamaguch if (ixl_dmamem_alloc(sc, &txr->txr_mem, 2368 1.1 yamaguch sizeof(struct ixl_tx_desc) * sc->sc_tx_ring_ndescs, 2369 1.1 yamaguch IXL_TX_QUEUE_ALIGN) != 0) 2370 1.1 yamaguch goto free; 2371 1.1 yamaguch 2372 1.1 yamaguch for (i = 0; i < sc->sc_tx_ring_ndescs; i++) { 2373 1.1 yamaguch txm = &maps[i]; 2374 1.1 yamaguch 2375 1.29 yamaguch if (bus_dmamap_create(sc->sc_dmat, IXL_TX_PKT_MAXSIZE, 2376 1.29 yamaguch IXL_TX_PKT_DESCS, IXL_TX_PKT_MAXSIZE, 0, 2377 1.1 yamaguch BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &txm->txm_map) != 0) 2378 1.1 yamaguch goto uncreate; 2379 1.1 yamaguch 2380 1.1 yamaguch txm->txm_eop = -1; 2381 1.1 yamaguch txm->txm_m = NULL; 2382 1.1 yamaguch } 2383 1.1 yamaguch 2384 1.1 yamaguch txr->txr_cons = txr->txr_prod = 0; 2385 1.1 yamaguch txr->txr_maps = maps; 2386 1.1 yamaguch 2387 1.1 yamaguch txr->txr_intrq = pcq_create(sc->sc_tx_ring_ndescs, KM_NOSLEEP); 2388 1.1 yamaguch if (txr->txr_intrq == NULL) 2389 1.1 yamaguch goto uncreate; 2390 1.1 yamaguch 2391 1.1 yamaguch txr->txr_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE, 2392 1.1 yamaguch ixl_deferred_transmit, txr); 2393 1.1 yamaguch if (txr->txr_si == NULL) 2394 1.1 yamaguch goto destroy_pcq; 2395 1.1 yamaguch 2396 1.1 yamaguch txr->txr_tail = I40E_QTX_TAIL(qid); 2397 1.1 yamaguch txr->txr_qid = qid; 2398 1.1 yamaguch txr->txr_sc = sc; 2399 1.1 yamaguch mutex_init(&txr->txr_lock, MUTEX_DEFAULT, IPL_NET); 2400 1.1 yamaguch 2401 1.1 yamaguch return txr; 2402 1.1 yamaguch 2403 1.1 yamaguch destroy_pcq: 2404 1.1 yamaguch pcq_destroy(txr->txr_intrq); 2405 1.1 yamaguch uncreate: 2406 1.1 yamaguch for (i = 0; i < sc->sc_tx_ring_ndescs; i++) { 2407 1.1 yamaguch txm = &maps[i]; 2408 1.1 yamaguch 2409 1.1 yamaguch if (txm->txm_map == NULL) 2410 1.1 yamaguch continue; 2411 1.1 yamaguch 2412 1.1 yamaguch bus_dmamap_destroy(sc->sc_dmat, txm->txm_map); 2413 1.1 yamaguch } 2414 1.1 yamaguch 2415 1.1 yamaguch ixl_dmamem_free(sc, &txr->txr_mem); 2416 1.1 yamaguch free: 2417 1.1 yamaguch kmem_free(maps, sizeof(maps[0]) * sc->sc_tx_ring_ndescs); 2418 1.1 yamaguch kmem_free(txr, sizeof(*txr)); 2419 1.1 yamaguch 2420 1.1 yamaguch return NULL; 2421 1.1 yamaguch } 2422 1.1 yamaguch 2423 1.1 yamaguch static void 2424 1.1 yamaguch ixl_txr_qdis(struct ixl_softc *sc, struct ixl_tx_ring *txr, int enable) 2425 1.1 yamaguch { 2426 1.1 yamaguch unsigned int qid; 2427 1.1 yamaguch bus_size_t reg; 2428 1.1 yamaguch uint32_t r; 2429 1.1 yamaguch 2430 1.1 yamaguch qid = txr->txr_qid + sc->sc_base_queue; 2431 1.1 yamaguch reg = I40E_GLLAN_TXPRE_QDIS(qid / 128); 2432 1.1 yamaguch qid %= 128; 2433 1.1 yamaguch 2434 1.1 yamaguch r = ixl_rd(sc, reg); 2435 1.1 yamaguch CLR(r, I40E_GLLAN_TXPRE_QDIS_QINDX_MASK); 2436 1.1 yamaguch SET(r, qid << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT); 2437 1.1 yamaguch SET(r, enable ? I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_MASK : 2438 1.1 yamaguch I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK); 2439 1.1 yamaguch ixl_wr(sc, reg, r); 2440 1.1 yamaguch } 2441 1.1 yamaguch 2442 1.1 yamaguch static void 2443 1.1 yamaguch ixl_txr_config(struct ixl_softc *sc, struct ixl_tx_ring *txr) 2444 1.1 yamaguch { 2445 1.1 yamaguch struct ixl_hmc_txq txq; 2446 1.1 yamaguch struct ixl_aq_vsi_data *data = IXL_DMA_KVA(&sc->sc_scratch); 2447 1.1 yamaguch void *hmc; 2448 1.1 yamaguch 2449 1.1 yamaguch memset(&txq, 0, sizeof(txq)); 2450 1.1 yamaguch txq.head = htole16(txr->txr_cons); 2451 1.1 yamaguch txq.new_context = 1; 2452 1.1 yamaguch txq.base = htole64(IXL_DMA_DVA(&txr->txr_mem) / IXL_HMC_TXQ_BASE_UNIT); 2453 1.1 yamaguch txq.head_wb_ena = IXL_HMC_TXQ_DESC_WB; 2454 1.1 yamaguch txq.qlen = htole16(sc->sc_tx_ring_ndescs); 2455 1.1 yamaguch txq.tphrdesc_ena = 0; 2456 1.1 yamaguch txq.tphrpacket_ena = 0; 2457 1.1 yamaguch txq.tphwdesc_ena = 0; 2458 1.1 yamaguch txq.rdylist = data->qs_handle[0]; 2459 1.1 yamaguch 2460 1.1 yamaguch hmc = ixl_hmc_kva(sc, IXL_HMC_LAN_TX, txr->txr_qid); 2461 1.1 yamaguch memset(hmc, 0, ixl_hmc_len(sc, IXL_HMC_LAN_TX)); 2462 1.1 yamaguch ixl_hmc_pack(hmc, &txq, ixl_hmc_pack_txq, 2463 1.1 yamaguch __arraycount(ixl_hmc_pack_txq)); 2464 1.1 yamaguch } 2465 1.1 yamaguch 2466 1.1 yamaguch static void 2467 1.1 yamaguch ixl_txr_unconfig(struct ixl_softc *sc, struct ixl_tx_ring *txr) 2468 1.1 yamaguch { 2469 1.1 yamaguch void *hmc; 2470 1.1 yamaguch 2471 1.1 yamaguch hmc = ixl_hmc_kva(sc, IXL_HMC_LAN_TX, txr->txr_qid); 2472 1.1 yamaguch memset(hmc, 0, ixl_hmc_len(sc, IXL_HMC_LAN_TX)); 2473 1.46 yamaguch txr->txr_cons = txr->txr_prod = 0; 2474 1.1 yamaguch } 2475 1.1 yamaguch 2476 1.1 yamaguch static void 2477 1.1 yamaguch ixl_txr_clean(struct ixl_softc *sc, struct ixl_tx_ring *txr) 2478 1.1 yamaguch { 2479 1.1 yamaguch struct ixl_tx_map *maps, *txm; 2480 1.1 yamaguch bus_dmamap_t map; 2481 1.1 yamaguch unsigned int i; 2482 1.1 yamaguch 2483 1.1 yamaguch maps = txr->txr_maps; 2484 1.1 yamaguch for (i = 0; i < sc->sc_tx_ring_ndescs; i++) { 2485 1.1 yamaguch txm = &maps[i]; 2486 1.1 yamaguch 2487 1.1 yamaguch if (txm->txm_m == NULL) 2488 1.1 yamaguch continue; 2489 1.1 yamaguch 2490 1.1 yamaguch map = txm->txm_map; 2491 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 2492 1.1 yamaguch BUS_DMASYNC_POSTWRITE); 2493 1.1 yamaguch bus_dmamap_unload(sc->sc_dmat, map); 2494 1.1 yamaguch 2495 1.1 yamaguch m_freem(txm->txm_m); 2496 1.1 yamaguch txm->txm_m = NULL; 2497 1.1 yamaguch } 2498 1.1 yamaguch } 2499 1.1 yamaguch 2500 1.1 yamaguch static int 2501 1.1 yamaguch ixl_txr_enabled(struct ixl_softc *sc, struct ixl_tx_ring *txr) 2502 1.1 yamaguch { 2503 1.1 yamaguch bus_size_t ena = I40E_QTX_ENA(txr->txr_qid); 2504 1.1 yamaguch uint32_t reg; 2505 1.1 yamaguch int i; 2506 1.1 yamaguch 2507 1.1 yamaguch for (i = 0; i < 10; i++) { 2508 1.1 yamaguch reg = ixl_rd(sc, ena); 2509 1.1 yamaguch if (ISSET(reg, I40E_QTX_ENA_QENA_STAT_MASK)) 2510 1.1 yamaguch return 0; 2511 1.1 yamaguch 2512 1.1 yamaguch delaymsec(10); 2513 1.1 yamaguch } 2514 1.1 yamaguch 2515 1.1 yamaguch return ETIMEDOUT; 2516 1.1 yamaguch } 2517 1.1 yamaguch 2518 1.1 yamaguch static int 2519 1.1 yamaguch ixl_txr_disabled(struct ixl_softc *sc, struct ixl_tx_ring *txr) 2520 1.1 yamaguch { 2521 1.1 yamaguch bus_size_t ena = I40E_QTX_ENA(txr->txr_qid); 2522 1.1 yamaguch uint32_t reg; 2523 1.1 yamaguch int i; 2524 1.1 yamaguch 2525 1.1 yamaguch KASSERT(mutex_owned(&txr->txr_lock)); 2526 1.1 yamaguch 2527 1.53 yamaguch for (i = 0; i < 10; i++) { 2528 1.1 yamaguch reg = ixl_rd(sc, ena); 2529 1.1 yamaguch if (ISSET(reg, I40E_QTX_ENA_QENA_STAT_MASK) == 0) 2530 1.1 yamaguch return 0; 2531 1.1 yamaguch 2532 1.1 yamaguch delaymsec(10); 2533 1.1 yamaguch } 2534 1.1 yamaguch 2535 1.1 yamaguch return ETIMEDOUT; 2536 1.1 yamaguch } 2537 1.1 yamaguch 2538 1.1 yamaguch static void 2539 1.1 yamaguch ixl_txr_free(struct ixl_softc *sc, struct ixl_tx_ring *txr) 2540 1.1 yamaguch { 2541 1.1 yamaguch struct ixl_tx_map *maps, *txm; 2542 1.1 yamaguch struct mbuf *m; 2543 1.1 yamaguch unsigned int i; 2544 1.1 yamaguch 2545 1.1 yamaguch softint_disestablish(txr->txr_si); 2546 1.1 yamaguch 2547 1.1 yamaguch maps = txr->txr_maps; 2548 1.1 yamaguch for (i = 0; i < sc->sc_tx_ring_ndescs; i++) { 2549 1.1 yamaguch txm = &maps[i]; 2550 1.1 yamaguch 2551 1.1 yamaguch bus_dmamap_destroy(sc->sc_dmat, txm->txm_map); 2552 1.1 yamaguch } 2553 1.1 yamaguch 2554 1.83 rin while ((m = pcq_get(txr->txr_intrq)) != NULL) 2555 1.83 rin m_freem(m); 2556 1.83 rin pcq_destroy(txr->txr_intrq); 2557 1.83 rin 2558 1.1 yamaguch ixl_dmamem_free(sc, &txr->txr_mem); 2559 1.1 yamaguch mutex_destroy(&txr->txr_lock); 2560 1.1 yamaguch kmem_free(maps, sizeof(maps[0]) * sc->sc_tx_ring_ndescs); 2561 1.1 yamaguch kmem_free(txr, sizeof(*txr)); 2562 1.1 yamaguch } 2563 1.1 yamaguch 2564 1.1 yamaguch static inline int 2565 1.1 yamaguch ixl_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf **m0, 2566 1.1 yamaguch struct ixl_tx_ring *txr) 2567 1.1 yamaguch { 2568 1.1 yamaguch struct mbuf *m; 2569 1.1 yamaguch int error; 2570 1.1 yamaguch 2571 1.1 yamaguch KASSERT(mutex_owned(&txr->txr_lock)); 2572 1.1 yamaguch 2573 1.1 yamaguch m = *m0; 2574 1.1 yamaguch 2575 1.1 yamaguch error = bus_dmamap_load_mbuf(dmat, map, m, 2576 1.1 yamaguch BUS_DMA_STREAMING | BUS_DMA_WRITE | BUS_DMA_NOWAIT); 2577 1.1 yamaguch if (error != EFBIG) 2578 1.1 yamaguch return error; 2579 1.1 yamaguch 2580 1.1 yamaguch m = m_defrag(m, M_DONTWAIT); 2581 1.1 yamaguch if (m != NULL) { 2582 1.1 yamaguch *m0 = m; 2583 1.1 yamaguch txr->txr_defragged.ev_count++; 2584 1.1 yamaguch 2585 1.1 yamaguch error = bus_dmamap_load_mbuf(dmat, map, m, 2586 1.1 yamaguch BUS_DMA_STREAMING | BUS_DMA_WRITE | BUS_DMA_NOWAIT); 2587 1.1 yamaguch } else { 2588 1.1 yamaguch txr->txr_defrag_failed.ev_count++; 2589 1.1 yamaguch error = ENOBUFS; 2590 1.1 yamaguch } 2591 1.1 yamaguch 2592 1.1 yamaguch return error; 2593 1.1 yamaguch } 2594 1.1 yamaguch 2595 1.28 yamaguch static inline int 2596 1.28 yamaguch ixl_tx_setup_offloads(struct mbuf *m, uint64_t *cmd_txd) 2597 1.28 yamaguch { 2598 1.28 yamaguch struct ether_header *eh; 2599 1.28 yamaguch size_t len; 2600 1.28 yamaguch uint64_t cmd; 2601 1.28 yamaguch 2602 1.28 yamaguch cmd = 0; 2603 1.28 yamaguch 2604 1.28 yamaguch eh = mtod(m, struct ether_header *); 2605 1.28 yamaguch switch (htons(eh->ether_type)) { 2606 1.28 yamaguch case ETHERTYPE_IP: 2607 1.28 yamaguch case ETHERTYPE_IPV6: 2608 1.28 yamaguch len = ETHER_HDR_LEN; 2609 1.28 yamaguch break; 2610 1.28 yamaguch case ETHERTYPE_VLAN: 2611 1.28 yamaguch len = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; 2612 1.28 yamaguch break; 2613 1.28 yamaguch default: 2614 1.28 yamaguch len = 0; 2615 1.28 yamaguch } 2616 1.28 yamaguch cmd |= ((len >> 1) << IXL_TX_DESC_MACLEN_SHIFT); 2617 1.28 yamaguch 2618 1.28 yamaguch if (m->m_pkthdr.csum_flags & 2619 1.28 yamaguch (M_CSUM_TSOv4 | M_CSUM_TCPv4 | M_CSUM_UDPv4)) { 2620 1.28 yamaguch cmd |= IXL_TX_DESC_CMD_IIPT_IPV4; 2621 1.28 yamaguch } 2622 1.28 yamaguch if (m->m_pkthdr.csum_flags & M_CSUM_IPv4) { 2623 1.28 yamaguch cmd |= IXL_TX_DESC_CMD_IIPT_IPV4_CSUM; 2624 1.28 yamaguch } 2625 1.28 yamaguch 2626 1.28 yamaguch if (m->m_pkthdr.csum_flags & 2627 1.28 yamaguch (M_CSUM_TSOv6 | M_CSUM_TCPv6 | M_CSUM_UDPv6)) { 2628 1.28 yamaguch cmd |= IXL_TX_DESC_CMD_IIPT_IPV6; 2629 1.28 yamaguch } 2630 1.28 yamaguch 2631 1.28 yamaguch switch (cmd & IXL_TX_DESC_CMD_IIPT_MASK) { 2632 1.28 yamaguch case IXL_TX_DESC_CMD_IIPT_IPV4: 2633 1.28 yamaguch case IXL_TX_DESC_CMD_IIPT_IPV4_CSUM: 2634 1.28 yamaguch len = M_CSUM_DATA_IPv4_IPHL(m->m_pkthdr.csum_data); 2635 1.28 yamaguch break; 2636 1.28 yamaguch case IXL_TX_DESC_CMD_IIPT_IPV6: 2637 1.28 yamaguch len = M_CSUM_DATA_IPv6_IPHL(m->m_pkthdr.csum_data); 2638 1.28 yamaguch break; 2639 1.28 yamaguch default: 2640 1.28 yamaguch len = 0; 2641 1.28 yamaguch } 2642 1.28 yamaguch cmd |= ((len >> 2) << IXL_TX_DESC_IPLEN_SHIFT); 2643 1.28 yamaguch 2644 1.28 yamaguch if (m->m_pkthdr.csum_flags & 2645 1.28 yamaguch (M_CSUM_TSOv4 | M_CSUM_TSOv6 | M_CSUM_TCPv4 | M_CSUM_TCPv6)) { 2646 1.28 yamaguch len = sizeof(struct tcphdr); 2647 1.28 yamaguch cmd |= IXL_TX_DESC_CMD_L4T_EOFT_TCP; 2648 1.28 yamaguch } else if (m->m_pkthdr.csum_flags & (M_CSUM_UDPv4 | M_CSUM_UDPv6)) { 2649 1.28 yamaguch len = sizeof(struct udphdr); 2650 1.28 yamaguch cmd |= IXL_TX_DESC_CMD_L4T_EOFT_UDP; 2651 1.28 yamaguch } else { 2652 1.28 yamaguch len = 0; 2653 1.28 yamaguch } 2654 1.28 yamaguch cmd |= ((len >> 2) << IXL_TX_DESC_L4LEN_SHIFT); 2655 1.28 yamaguch 2656 1.28 yamaguch *cmd_txd |= cmd; 2657 1.28 yamaguch return 0; 2658 1.28 yamaguch } 2659 1.28 yamaguch 2660 1.1 yamaguch static void 2661 1.1 yamaguch ixl_tx_common_locked(struct ifnet *ifp, struct ixl_tx_ring *txr, 2662 1.1 yamaguch bool is_transmit) 2663 1.1 yamaguch { 2664 1.1 yamaguch struct ixl_softc *sc = ifp->if_softc; 2665 1.1 yamaguch struct ixl_tx_desc *ring, *txd; 2666 1.1 yamaguch struct ixl_tx_map *txm; 2667 1.1 yamaguch bus_dmamap_t map; 2668 1.1 yamaguch struct mbuf *m; 2669 1.28 yamaguch uint64_t cmd, cmd_txd; 2670 1.1 yamaguch unsigned int prod, free, last, i; 2671 1.1 yamaguch unsigned int mask; 2672 1.1 yamaguch int post = 0; 2673 1.1 yamaguch 2674 1.1 yamaguch KASSERT(mutex_owned(&txr->txr_lock)); 2675 1.1 yamaguch 2676 1.60 yamaguch if (!ISSET(ifp->if_flags, IFF_RUNNING) 2677 1.1 yamaguch || (!is_transmit && ISSET(ifp->if_flags, IFF_OACTIVE))) { 2678 1.1 yamaguch if (!is_transmit) 2679 1.1 yamaguch IFQ_PURGE(&ifp->if_snd); 2680 1.1 yamaguch return; 2681 1.1 yamaguch } 2682 1.1 yamaguch 2683 1.1 yamaguch prod = txr->txr_prod; 2684 1.1 yamaguch free = txr->txr_cons; 2685 1.1 yamaguch if (free <= prod) 2686 1.1 yamaguch free += sc->sc_tx_ring_ndescs; 2687 1.1 yamaguch free -= prod; 2688 1.1 yamaguch 2689 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem), 2690 1.1 yamaguch 0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_POSTWRITE); 2691 1.1 yamaguch 2692 1.1 yamaguch ring = IXL_DMA_KVA(&txr->txr_mem); 2693 1.1 yamaguch mask = sc->sc_tx_ring_ndescs - 1; 2694 1.1 yamaguch last = prod; 2695 1.1 yamaguch cmd = 0; 2696 1.1 yamaguch txd = NULL; 2697 1.1 yamaguch 2698 1.1 yamaguch for (;;) { 2699 1.1 yamaguch if (free <= IXL_TX_PKT_DESCS) { 2700 1.1 yamaguch if (!is_transmit) 2701 1.1 yamaguch SET(ifp->if_flags, IFF_OACTIVE); 2702 1.1 yamaguch break; 2703 1.1 yamaguch } 2704 1.1 yamaguch 2705 1.1 yamaguch if (is_transmit) 2706 1.1 yamaguch m = pcq_get(txr->txr_intrq); 2707 1.1 yamaguch else 2708 1.1 yamaguch IFQ_DEQUEUE(&ifp->if_snd, m); 2709 1.1 yamaguch 2710 1.1 yamaguch if (m == NULL) 2711 1.1 yamaguch break; 2712 1.1 yamaguch 2713 1.1 yamaguch txm = &txr->txr_maps[prod]; 2714 1.1 yamaguch map = txm->txm_map; 2715 1.1 yamaguch 2716 1.1 yamaguch if (ixl_load_mbuf(sc->sc_dmat, map, &m, txr) != 0) { 2717 1.35 thorpej if_statinc(ifp, if_oerrors); 2718 1.1 yamaguch m_freem(m); 2719 1.1 yamaguch continue; 2720 1.1 yamaguch } 2721 1.1 yamaguch 2722 1.28 yamaguch cmd_txd = 0; 2723 1.28 yamaguch if (m->m_pkthdr.csum_flags & IXL_CSUM_ALL_OFFLOAD) { 2724 1.28 yamaguch ixl_tx_setup_offloads(m, &cmd_txd); 2725 1.28 yamaguch } 2726 1.28 yamaguch 2727 1.11 yamaguch if (vlan_has_tag(m)) { 2728 1.84 yamaguch uint16_t vtag; 2729 1.84 yamaguch vtag = htole16(vlan_get_tag(m)); 2730 1.84 yamaguch cmd_txd |= (uint64_t)vtag << 2731 1.11 yamaguch IXL_TX_DESC_L2TAG1_SHIFT; 2732 1.28 yamaguch cmd_txd |= IXL_TX_DESC_CMD_IL2TAG1; 2733 1.11 yamaguch } 2734 1.11 yamaguch 2735 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, map, 0, 2736 1.1 yamaguch map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2737 1.1 yamaguch 2738 1.1 yamaguch for (i = 0; i < (unsigned int)map->dm_nsegs; i++) { 2739 1.1 yamaguch txd = &ring[prod]; 2740 1.1 yamaguch 2741 1.1 yamaguch cmd = (uint64_t)map->dm_segs[i].ds_len << 2742 1.1 yamaguch IXL_TX_DESC_BSIZE_SHIFT; 2743 1.1 yamaguch cmd |= IXL_TX_DESC_DTYPE_DATA | IXL_TX_DESC_CMD_ICRC; 2744 1.28 yamaguch cmd |= cmd_txd; 2745 1.1 yamaguch 2746 1.1 yamaguch txd->addr = htole64(map->dm_segs[i].ds_addr); 2747 1.1 yamaguch txd->cmd = htole64(cmd); 2748 1.1 yamaguch 2749 1.1 yamaguch last = prod; 2750 1.1 yamaguch 2751 1.1 yamaguch prod++; 2752 1.1 yamaguch prod &= mask; 2753 1.1 yamaguch } 2754 1.1 yamaguch cmd |= IXL_TX_DESC_CMD_EOP | IXL_TX_DESC_CMD_RS; 2755 1.1 yamaguch txd->cmd = htole64(cmd); 2756 1.1 yamaguch 2757 1.1 yamaguch txm->txm_m = m; 2758 1.1 yamaguch txm->txm_eop = last; 2759 1.1 yamaguch 2760 1.1 yamaguch bpf_mtap(ifp, m, BPF_D_OUT); 2761 1.1 yamaguch 2762 1.1 yamaguch free -= i; 2763 1.1 yamaguch post = 1; 2764 1.1 yamaguch } 2765 1.1 yamaguch 2766 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem), 2767 1.1 yamaguch 0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_PREWRITE); 2768 1.1 yamaguch 2769 1.1 yamaguch if (post) { 2770 1.1 yamaguch txr->txr_prod = prod; 2771 1.1 yamaguch ixl_wr(sc, txr->txr_tail, prod); 2772 1.1 yamaguch } 2773 1.1 yamaguch } 2774 1.1 yamaguch 2775 1.1 yamaguch static int 2776 1.1 yamaguch ixl_txeof(struct ixl_softc *sc, struct ixl_tx_ring *txr, u_int txlimit) 2777 1.1 yamaguch { 2778 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 2779 1.1 yamaguch struct ixl_tx_desc *ring, *txd; 2780 1.1 yamaguch struct ixl_tx_map *txm; 2781 1.1 yamaguch struct mbuf *m; 2782 1.1 yamaguch bus_dmamap_t map; 2783 1.1 yamaguch unsigned int cons, prod, last; 2784 1.1 yamaguch unsigned int mask; 2785 1.1 yamaguch uint64_t dtype; 2786 1.1 yamaguch int done = 0, more = 0; 2787 1.1 yamaguch 2788 1.1 yamaguch KASSERT(mutex_owned(&txr->txr_lock)); 2789 1.1 yamaguch 2790 1.1 yamaguch prod = txr->txr_prod; 2791 1.1 yamaguch cons = txr->txr_cons; 2792 1.1 yamaguch 2793 1.1 yamaguch if (cons == prod) 2794 1.1 yamaguch return 0; 2795 1.1 yamaguch 2796 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem), 2797 1.1 yamaguch 0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_POSTREAD); 2798 1.1 yamaguch 2799 1.1 yamaguch ring = IXL_DMA_KVA(&txr->txr_mem); 2800 1.1 yamaguch mask = sc->sc_tx_ring_ndescs - 1; 2801 1.1 yamaguch 2802 1.35 thorpej net_stat_ref_t nsr = IF_STAT_GETREF(ifp); 2803 1.35 thorpej 2804 1.1 yamaguch do { 2805 1.1 yamaguch if (txlimit-- <= 0) { 2806 1.1 yamaguch more = 1; 2807 1.1 yamaguch break; 2808 1.1 yamaguch } 2809 1.1 yamaguch 2810 1.1 yamaguch txm = &txr->txr_maps[cons]; 2811 1.1 yamaguch last = txm->txm_eop; 2812 1.1 yamaguch txd = &ring[last]; 2813 1.1 yamaguch 2814 1.1 yamaguch dtype = txd->cmd & htole64(IXL_TX_DESC_DTYPE_MASK); 2815 1.1 yamaguch if (dtype != htole64(IXL_TX_DESC_DTYPE_DONE)) 2816 1.1 yamaguch break; 2817 1.1 yamaguch 2818 1.1 yamaguch map = txm->txm_map; 2819 1.1 yamaguch 2820 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 2821 1.1 yamaguch BUS_DMASYNC_POSTWRITE); 2822 1.1 yamaguch bus_dmamap_unload(sc->sc_dmat, map); 2823 1.1 yamaguch 2824 1.1 yamaguch m = txm->txm_m; 2825 1.1 yamaguch if (m != NULL) { 2826 1.99 riastrad if_statinc_ref(ifp, nsr, if_opackets); 2827 1.99 riastrad if_statadd_ref(ifp, nsr, if_obytes, m->m_pkthdr.len); 2828 1.1 yamaguch if (ISSET(m->m_flags, M_MCAST)) 2829 1.99 riastrad if_statinc_ref(ifp, nsr, if_omcasts); 2830 1.1 yamaguch m_freem(m); 2831 1.1 yamaguch } 2832 1.1 yamaguch 2833 1.1 yamaguch txm->txm_m = NULL; 2834 1.1 yamaguch txm->txm_eop = -1; 2835 1.1 yamaguch 2836 1.1 yamaguch cons = last + 1; 2837 1.1 yamaguch cons &= mask; 2838 1.1 yamaguch done = 1; 2839 1.1 yamaguch } while (cons != prod); 2840 1.1 yamaguch 2841 1.35 thorpej IF_STAT_PUTREF(ifp); 2842 1.35 thorpej 2843 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&txr->txr_mem), 2844 1.1 yamaguch 0, IXL_DMA_LEN(&txr->txr_mem), BUS_DMASYNC_PREREAD); 2845 1.1 yamaguch 2846 1.1 yamaguch txr->txr_cons = cons; 2847 1.1 yamaguch 2848 1.1 yamaguch if (done) { 2849 1.1 yamaguch softint_schedule(txr->txr_si); 2850 1.1 yamaguch if (txr->txr_qid == 0) { 2851 1.1 yamaguch CLR(ifp->if_flags, IFF_OACTIVE); 2852 1.1 yamaguch if_schedule_deferred_start(ifp); 2853 1.1 yamaguch } 2854 1.1 yamaguch } 2855 1.1 yamaguch 2856 1.1 yamaguch return more; 2857 1.1 yamaguch } 2858 1.1 yamaguch 2859 1.1 yamaguch static void 2860 1.1 yamaguch ixl_start(struct ifnet *ifp) 2861 1.1 yamaguch { 2862 1.1 yamaguch struct ixl_softc *sc; 2863 1.1 yamaguch struct ixl_tx_ring *txr; 2864 1.1 yamaguch 2865 1.1 yamaguch sc = ifp->if_softc; 2866 1.1 yamaguch txr = sc->sc_qps[0].qp_txr; 2867 1.1 yamaguch 2868 1.1 yamaguch mutex_enter(&txr->txr_lock); 2869 1.1 yamaguch ixl_tx_common_locked(ifp, txr, false); 2870 1.1 yamaguch mutex_exit(&txr->txr_lock); 2871 1.1 yamaguch } 2872 1.1 yamaguch 2873 1.1 yamaguch static inline unsigned int 2874 1.1 yamaguch ixl_select_txqueue(struct ixl_softc *sc, struct mbuf *m) 2875 1.1 yamaguch { 2876 1.1 yamaguch u_int cpuid; 2877 1.1 yamaguch 2878 1.1 yamaguch cpuid = cpu_index(curcpu()); 2879 1.1 yamaguch 2880 1.1 yamaguch return (unsigned int)(cpuid % sc->sc_nqueue_pairs); 2881 1.1 yamaguch } 2882 1.1 yamaguch 2883 1.1 yamaguch static int 2884 1.1 yamaguch ixl_transmit(struct ifnet *ifp, struct mbuf *m) 2885 1.1 yamaguch { 2886 1.1 yamaguch struct ixl_softc *sc; 2887 1.1 yamaguch struct ixl_tx_ring *txr; 2888 1.1 yamaguch unsigned int qid; 2889 1.1 yamaguch 2890 1.1 yamaguch sc = ifp->if_softc; 2891 1.1 yamaguch qid = ixl_select_txqueue(sc, m); 2892 1.1 yamaguch 2893 1.1 yamaguch txr = sc->sc_qps[qid].qp_txr; 2894 1.1 yamaguch 2895 1.1 yamaguch if (__predict_false(!pcq_put(txr->txr_intrq, m))) { 2896 1.1 yamaguch mutex_enter(&txr->txr_lock); 2897 1.1 yamaguch txr->txr_pcqdrop.ev_count++; 2898 1.1 yamaguch mutex_exit(&txr->txr_lock); 2899 1.1 yamaguch 2900 1.1 yamaguch m_freem(m); 2901 1.1 yamaguch return ENOBUFS; 2902 1.1 yamaguch } 2903 1.1 yamaguch 2904 1.88 knakahar #ifdef IXL_ALWAYS_TXDEFER 2905 1.88 knakahar kpreempt_disable(); 2906 1.88 knakahar softint_schedule(txr->txr_si); 2907 1.88 knakahar kpreempt_enable(); 2908 1.88 knakahar #else 2909 1.1 yamaguch if (mutex_tryenter(&txr->txr_lock)) { 2910 1.1 yamaguch ixl_tx_common_locked(ifp, txr, true); 2911 1.1 yamaguch mutex_exit(&txr->txr_lock); 2912 1.1 yamaguch } else { 2913 1.33 yamaguch kpreempt_disable(); 2914 1.1 yamaguch softint_schedule(txr->txr_si); 2915 1.33 yamaguch kpreempt_enable(); 2916 1.1 yamaguch } 2917 1.88 knakahar #endif 2918 1.1 yamaguch 2919 1.1 yamaguch return 0; 2920 1.1 yamaguch } 2921 1.1 yamaguch 2922 1.1 yamaguch static void 2923 1.1 yamaguch ixl_deferred_transmit(void *xtxr) 2924 1.1 yamaguch { 2925 1.1 yamaguch struct ixl_tx_ring *txr = xtxr; 2926 1.1 yamaguch struct ixl_softc *sc = txr->txr_sc; 2927 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 2928 1.1 yamaguch 2929 1.1 yamaguch mutex_enter(&txr->txr_lock); 2930 1.1 yamaguch txr->txr_transmitdef.ev_count++; 2931 1.1 yamaguch if (pcq_peek(txr->txr_intrq) != NULL) 2932 1.1 yamaguch ixl_tx_common_locked(ifp, txr, true); 2933 1.1 yamaguch mutex_exit(&txr->txr_lock); 2934 1.1 yamaguch } 2935 1.1 yamaguch 2936 1.1 yamaguch static struct ixl_rx_ring * 2937 1.1 yamaguch ixl_rxr_alloc(struct ixl_softc *sc, unsigned int qid) 2938 1.1 yamaguch { 2939 1.1 yamaguch struct ixl_rx_ring *rxr = NULL; 2940 1.1 yamaguch struct ixl_rx_map *maps = NULL, *rxm; 2941 1.1 yamaguch unsigned int i; 2942 1.1 yamaguch 2943 1.1 yamaguch rxr = kmem_zalloc(sizeof(*rxr), KM_SLEEP); 2944 1.1 yamaguch maps = kmem_zalloc(sizeof(maps[0]) * sc->sc_rx_ring_ndescs, 2945 1.1 yamaguch KM_SLEEP); 2946 1.1 yamaguch 2947 1.1 yamaguch if (ixl_dmamem_alloc(sc, &rxr->rxr_mem, 2948 1.11 yamaguch sizeof(struct ixl_rx_rd_desc_32) * sc->sc_rx_ring_ndescs, 2949 1.1 yamaguch IXL_RX_QUEUE_ALIGN) != 0) 2950 1.1 yamaguch goto free; 2951 1.1 yamaguch 2952 1.1 yamaguch for (i = 0; i < sc->sc_rx_ring_ndescs; i++) { 2953 1.1 yamaguch rxm = &maps[i]; 2954 1.1 yamaguch 2955 1.1 yamaguch if (bus_dmamap_create(sc->sc_dmat, 2956 1.29 yamaguch IXL_MCLBYTES, 1, IXL_MCLBYTES, 0, 2957 1.1 yamaguch BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &rxm->rxm_map) != 0) 2958 1.1 yamaguch goto uncreate; 2959 1.1 yamaguch 2960 1.1 yamaguch rxm->rxm_m = NULL; 2961 1.1 yamaguch } 2962 1.1 yamaguch 2963 1.1 yamaguch rxr->rxr_cons = rxr->rxr_prod = 0; 2964 1.1 yamaguch rxr->rxr_m_head = NULL; 2965 1.1 yamaguch rxr->rxr_m_tail = &rxr->rxr_m_head; 2966 1.1 yamaguch rxr->rxr_maps = maps; 2967 1.1 yamaguch 2968 1.1 yamaguch rxr->rxr_tail = I40E_QRX_TAIL(qid); 2969 1.1 yamaguch rxr->rxr_qid = qid; 2970 1.1 yamaguch mutex_init(&rxr->rxr_lock, MUTEX_DEFAULT, IPL_NET); 2971 1.1 yamaguch 2972 1.1 yamaguch return rxr; 2973 1.1 yamaguch 2974 1.1 yamaguch uncreate: 2975 1.1 yamaguch for (i = 0; i < sc->sc_rx_ring_ndescs; i++) { 2976 1.1 yamaguch rxm = &maps[i]; 2977 1.1 yamaguch 2978 1.1 yamaguch if (rxm->rxm_map == NULL) 2979 1.1 yamaguch continue; 2980 1.1 yamaguch 2981 1.1 yamaguch bus_dmamap_destroy(sc->sc_dmat, rxm->rxm_map); 2982 1.1 yamaguch } 2983 1.1 yamaguch 2984 1.1 yamaguch ixl_dmamem_free(sc, &rxr->rxr_mem); 2985 1.1 yamaguch free: 2986 1.1 yamaguch kmem_free(maps, sizeof(maps[0]) * sc->sc_rx_ring_ndescs); 2987 1.1 yamaguch kmem_free(rxr, sizeof(*rxr)); 2988 1.1 yamaguch 2989 1.1 yamaguch return NULL; 2990 1.1 yamaguch } 2991 1.1 yamaguch 2992 1.1 yamaguch static void 2993 1.1 yamaguch ixl_rxr_clean(struct ixl_softc *sc, struct ixl_rx_ring *rxr) 2994 1.1 yamaguch { 2995 1.1 yamaguch struct ixl_rx_map *maps, *rxm; 2996 1.1 yamaguch bus_dmamap_t map; 2997 1.1 yamaguch unsigned int i; 2998 1.1 yamaguch 2999 1.1 yamaguch maps = rxr->rxr_maps; 3000 1.1 yamaguch for (i = 0; i < sc->sc_rx_ring_ndescs; i++) { 3001 1.1 yamaguch rxm = &maps[i]; 3002 1.1 yamaguch 3003 1.1 yamaguch if (rxm->rxm_m == NULL) 3004 1.1 yamaguch continue; 3005 1.1 yamaguch 3006 1.1 yamaguch map = rxm->rxm_map; 3007 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 3008 1.1 yamaguch BUS_DMASYNC_POSTWRITE); 3009 1.1 yamaguch bus_dmamap_unload(sc->sc_dmat, map); 3010 1.1 yamaguch 3011 1.1 yamaguch m_freem(rxm->rxm_m); 3012 1.1 yamaguch rxm->rxm_m = NULL; 3013 1.1 yamaguch } 3014 1.1 yamaguch 3015 1.1 yamaguch m_freem(rxr->rxr_m_head); 3016 1.1 yamaguch rxr->rxr_m_head = NULL; 3017 1.1 yamaguch rxr->rxr_m_tail = &rxr->rxr_m_head; 3018 1.1 yamaguch 3019 1.1 yamaguch rxr->rxr_prod = rxr->rxr_cons = 0; 3020 1.1 yamaguch } 3021 1.1 yamaguch 3022 1.1 yamaguch static int 3023 1.1 yamaguch ixl_rxr_enabled(struct ixl_softc *sc, struct ixl_rx_ring *rxr) 3024 1.1 yamaguch { 3025 1.1 yamaguch bus_size_t ena = I40E_QRX_ENA(rxr->rxr_qid); 3026 1.1 yamaguch uint32_t reg; 3027 1.1 yamaguch int i; 3028 1.1 yamaguch 3029 1.1 yamaguch for (i = 0; i < 10; i++) { 3030 1.1 yamaguch reg = ixl_rd(sc, ena); 3031 1.1 yamaguch if (ISSET(reg, I40E_QRX_ENA_QENA_STAT_MASK)) 3032 1.1 yamaguch return 0; 3033 1.1 yamaguch 3034 1.1 yamaguch delaymsec(10); 3035 1.1 yamaguch } 3036 1.1 yamaguch 3037 1.1 yamaguch return ETIMEDOUT; 3038 1.1 yamaguch } 3039 1.1 yamaguch 3040 1.1 yamaguch static int 3041 1.1 yamaguch ixl_rxr_disabled(struct ixl_softc *sc, struct ixl_rx_ring *rxr) 3042 1.1 yamaguch { 3043 1.1 yamaguch bus_size_t ena = I40E_QRX_ENA(rxr->rxr_qid); 3044 1.1 yamaguch uint32_t reg; 3045 1.1 yamaguch int i; 3046 1.1 yamaguch 3047 1.1 yamaguch KASSERT(mutex_owned(&rxr->rxr_lock)); 3048 1.1 yamaguch 3049 1.53 yamaguch for (i = 0; i < 10; i++) { 3050 1.1 yamaguch reg = ixl_rd(sc, ena); 3051 1.1 yamaguch if (ISSET(reg, I40E_QRX_ENA_QENA_STAT_MASK) == 0) 3052 1.1 yamaguch return 0; 3053 1.1 yamaguch 3054 1.1 yamaguch delaymsec(10); 3055 1.1 yamaguch } 3056 1.1 yamaguch 3057 1.1 yamaguch return ETIMEDOUT; 3058 1.1 yamaguch } 3059 1.1 yamaguch 3060 1.1 yamaguch static void 3061 1.1 yamaguch ixl_rxr_config(struct ixl_softc *sc, struct ixl_rx_ring *rxr) 3062 1.1 yamaguch { 3063 1.1 yamaguch struct ixl_hmc_rxq rxq; 3064 1.29 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 3065 1.29 yamaguch uint16_t rxmax; 3066 1.1 yamaguch void *hmc; 3067 1.1 yamaguch 3068 1.1 yamaguch memset(&rxq, 0, sizeof(rxq)); 3069 1.29 yamaguch rxmax = ifp->if_mtu + IXL_MTU_ETHERLEN; 3070 1.95 yamaguch if (!ISSET(sc->sc_ec.ec_capenable, ETHERCAP_VLAN_MTU)) 3071 1.95 yamaguch rxmax -= ETHER_VLAN_ENCAP_LEN; 3072 1.1 yamaguch 3073 1.1 yamaguch rxq.head = htole16(rxr->rxr_cons); 3074 1.1 yamaguch rxq.base = htole64(IXL_DMA_DVA(&rxr->rxr_mem) / IXL_HMC_RXQ_BASE_UNIT); 3075 1.1 yamaguch rxq.qlen = htole16(sc->sc_rx_ring_ndescs); 3076 1.29 yamaguch rxq.dbuff = htole16(IXL_MCLBYTES / IXL_HMC_RXQ_DBUFF_UNIT); 3077 1.1 yamaguch rxq.hbuff = 0; 3078 1.1 yamaguch rxq.dtype = IXL_HMC_RXQ_DTYPE_NOSPLIT; 3079 1.11 yamaguch rxq.dsize = IXL_HMC_RXQ_DSIZE_32; 3080 1.1 yamaguch rxq.crcstrip = 1; 3081 1.11 yamaguch rxq.l2sel = 1; 3082 1.11 yamaguch rxq.showiv = 1; 3083 1.29 yamaguch rxq.rxmax = htole16(rxmax); 3084 1.1 yamaguch rxq.tphrdesc_ena = 0; 3085 1.1 yamaguch rxq.tphwdesc_ena = 0; 3086 1.1 yamaguch rxq.tphdata_ena = 0; 3087 1.1 yamaguch rxq.tphhead_ena = 0; 3088 1.1 yamaguch rxq.lrxqthresh = 0; 3089 1.1 yamaguch rxq.prefena = 1; 3090 1.1 yamaguch 3091 1.1 yamaguch hmc = ixl_hmc_kva(sc, IXL_HMC_LAN_RX, rxr->rxr_qid); 3092 1.1 yamaguch memset(hmc, 0, ixl_hmc_len(sc, IXL_HMC_LAN_RX)); 3093 1.1 yamaguch ixl_hmc_pack(hmc, &rxq, ixl_hmc_pack_rxq, 3094 1.1 yamaguch __arraycount(ixl_hmc_pack_rxq)); 3095 1.1 yamaguch } 3096 1.1 yamaguch 3097 1.1 yamaguch static void 3098 1.1 yamaguch ixl_rxr_unconfig(struct ixl_softc *sc, struct ixl_rx_ring *rxr) 3099 1.1 yamaguch { 3100 1.1 yamaguch void *hmc; 3101 1.1 yamaguch 3102 1.1 yamaguch hmc = ixl_hmc_kva(sc, IXL_HMC_LAN_RX, rxr->rxr_qid); 3103 1.1 yamaguch memset(hmc, 0, ixl_hmc_len(sc, IXL_HMC_LAN_RX)); 3104 1.46 yamaguch rxr->rxr_cons = rxr->rxr_prod = 0; 3105 1.1 yamaguch } 3106 1.1 yamaguch 3107 1.1 yamaguch static void 3108 1.1 yamaguch ixl_rxr_free(struct ixl_softc *sc, struct ixl_rx_ring *rxr) 3109 1.1 yamaguch { 3110 1.1 yamaguch struct ixl_rx_map *maps, *rxm; 3111 1.1 yamaguch unsigned int i; 3112 1.1 yamaguch 3113 1.1 yamaguch maps = rxr->rxr_maps; 3114 1.1 yamaguch for (i = 0; i < sc->sc_rx_ring_ndescs; i++) { 3115 1.1 yamaguch rxm = &maps[i]; 3116 1.1 yamaguch 3117 1.1 yamaguch bus_dmamap_destroy(sc->sc_dmat, rxm->rxm_map); 3118 1.1 yamaguch } 3119 1.1 yamaguch 3120 1.1 yamaguch ixl_dmamem_free(sc, &rxr->rxr_mem); 3121 1.1 yamaguch mutex_destroy(&rxr->rxr_lock); 3122 1.1 yamaguch kmem_free(maps, sizeof(maps[0]) * sc->sc_rx_ring_ndescs); 3123 1.1 yamaguch kmem_free(rxr, sizeof(*rxr)); 3124 1.1 yamaguch } 3125 1.1 yamaguch 3126 1.14 yamaguch static inline void 3127 1.14 yamaguch ixl_rx_csum(struct mbuf *m, uint64_t qword) 3128 1.14 yamaguch { 3129 1.14 yamaguch int flags_mask; 3130 1.14 yamaguch 3131 1.14 yamaguch if (!ISSET(qword, IXL_RX_DESC_L3L4P)) { 3132 1.14 yamaguch /* No L3 or L4 checksum was calculated */ 3133 1.14 yamaguch return; 3134 1.14 yamaguch } 3135 1.14 yamaguch 3136 1.14 yamaguch switch (__SHIFTOUT(qword, IXL_RX_DESC_PTYPE_MASK)) { 3137 1.14 yamaguch case IXL_RX_DESC_PTYPE_IPV4FRAG: 3138 1.14 yamaguch case IXL_RX_DESC_PTYPE_IPV4: 3139 1.14 yamaguch case IXL_RX_DESC_PTYPE_SCTPV4: 3140 1.14 yamaguch case IXL_RX_DESC_PTYPE_ICMPV4: 3141 1.14 yamaguch flags_mask = M_CSUM_IPv4 | M_CSUM_IPv4_BAD; 3142 1.14 yamaguch break; 3143 1.14 yamaguch case IXL_RX_DESC_PTYPE_TCPV4: 3144 1.14 yamaguch flags_mask = M_CSUM_IPv4 | M_CSUM_IPv4_BAD; 3145 1.14 yamaguch flags_mask |= M_CSUM_TCPv4 | M_CSUM_TCP_UDP_BAD; 3146 1.14 yamaguch break; 3147 1.14 yamaguch case IXL_RX_DESC_PTYPE_UDPV4: 3148 1.14 yamaguch flags_mask = M_CSUM_IPv4 | M_CSUM_IPv4_BAD; 3149 1.14 yamaguch flags_mask |= M_CSUM_UDPv4 | M_CSUM_TCP_UDP_BAD; 3150 1.14 yamaguch break; 3151 1.14 yamaguch case IXL_RX_DESC_PTYPE_TCPV6: 3152 1.14 yamaguch flags_mask = M_CSUM_TCPv6 | M_CSUM_TCP_UDP_BAD; 3153 1.14 yamaguch break; 3154 1.14 yamaguch case IXL_RX_DESC_PTYPE_UDPV6: 3155 1.14 yamaguch flags_mask = M_CSUM_UDPv6 | M_CSUM_TCP_UDP_BAD; 3156 1.14 yamaguch break; 3157 1.14 yamaguch default: 3158 1.14 yamaguch flags_mask = 0; 3159 1.14 yamaguch } 3160 1.14 yamaguch 3161 1.14 yamaguch m->m_pkthdr.csum_flags |= (flags_mask & (M_CSUM_IPv4 | 3162 1.14 yamaguch M_CSUM_TCPv4 | M_CSUM_TCPv6 | M_CSUM_UDPv4 | M_CSUM_UDPv6)); 3163 1.14 yamaguch 3164 1.14 yamaguch if (ISSET(qword, IXL_RX_DESC_IPE)) { 3165 1.14 yamaguch m->m_pkthdr.csum_flags |= (flags_mask & M_CSUM_IPv4_BAD); 3166 1.14 yamaguch } 3167 1.14 yamaguch 3168 1.14 yamaguch if (ISSET(qword, IXL_RX_DESC_L4E)) { 3169 1.14 yamaguch m->m_pkthdr.csum_flags |= (flags_mask & M_CSUM_TCP_UDP_BAD); 3170 1.14 yamaguch } 3171 1.14 yamaguch } 3172 1.14 yamaguch 3173 1.1 yamaguch static int 3174 1.1 yamaguch ixl_rxeof(struct ixl_softc *sc, struct ixl_rx_ring *rxr, u_int rxlimit) 3175 1.1 yamaguch { 3176 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 3177 1.11 yamaguch struct ixl_rx_wb_desc_32 *ring, *rxd; 3178 1.1 yamaguch struct ixl_rx_map *rxm; 3179 1.1 yamaguch bus_dmamap_t map; 3180 1.1 yamaguch unsigned int cons, prod; 3181 1.1 yamaguch struct mbuf *m; 3182 1.11 yamaguch uint64_t word, word0; 3183 1.1 yamaguch unsigned int len; 3184 1.1 yamaguch unsigned int mask; 3185 1.1 yamaguch int done = 0, more = 0; 3186 1.1 yamaguch 3187 1.1 yamaguch KASSERT(mutex_owned(&rxr->rxr_lock)); 3188 1.1 yamaguch 3189 1.1 yamaguch if (!ISSET(ifp->if_flags, IFF_RUNNING)) 3190 1.1 yamaguch return 0; 3191 1.1 yamaguch 3192 1.1 yamaguch prod = rxr->rxr_prod; 3193 1.1 yamaguch cons = rxr->rxr_cons; 3194 1.1 yamaguch 3195 1.1 yamaguch if (cons == prod) 3196 1.1 yamaguch return 0; 3197 1.1 yamaguch 3198 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&rxr->rxr_mem), 3199 1.1 yamaguch 0, IXL_DMA_LEN(&rxr->rxr_mem), 3200 1.1 yamaguch BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 3201 1.1 yamaguch 3202 1.1 yamaguch ring = IXL_DMA_KVA(&rxr->rxr_mem); 3203 1.1 yamaguch mask = sc->sc_rx_ring_ndescs - 1; 3204 1.1 yamaguch 3205 1.35 thorpej net_stat_ref_t nsr = IF_STAT_GETREF(ifp); 3206 1.35 thorpej 3207 1.1 yamaguch do { 3208 1.1 yamaguch if (rxlimit-- <= 0) { 3209 1.1 yamaguch more = 1; 3210 1.1 yamaguch break; 3211 1.1 yamaguch } 3212 1.1 yamaguch 3213 1.1 yamaguch rxd = &ring[cons]; 3214 1.1 yamaguch 3215 1.1 yamaguch word = le64toh(rxd->qword1); 3216 1.1 yamaguch 3217 1.1 yamaguch if (!ISSET(word, IXL_RX_DESC_DD)) 3218 1.1 yamaguch break; 3219 1.1 yamaguch 3220 1.1 yamaguch rxm = &rxr->rxr_maps[cons]; 3221 1.1 yamaguch 3222 1.1 yamaguch map = rxm->rxm_map; 3223 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 3224 1.1 yamaguch BUS_DMASYNC_POSTREAD); 3225 1.1 yamaguch bus_dmamap_unload(sc->sc_dmat, map); 3226 1.1 yamaguch 3227 1.1 yamaguch m = rxm->rxm_m; 3228 1.1 yamaguch rxm->rxm_m = NULL; 3229 1.1 yamaguch 3230 1.1 yamaguch KASSERT(m != NULL); 3231 1.1 yamaguch 3232 1.1 yamaguch len = (word & IXL_RX_DESC_PLEN_MASK) >> IXL_RX_DESC_PLEN_SHIFT; 3233 1.1 yamaguch m->m_len = len; 3234 1.1 yamaguch m->m_pkthdr.len = 0; 3235 1.1 yamaguch 3236 1.1 yamaguch m->m_next = NULL; 3237 1.1 yamaguch *rxr->rxr_m_tail = m; 3238 1.1 yamaguch rxr->rxr_m_tail = &m->m_next; 3239 1.1 yamaguch 3240 1.1 yamaguch m = rxr->rxr_m_head; 3241 1.1 yamaguch m->m_pkthdr.len += len; 3242 1.1 yamaguch 3243 1.1 yamaguch if (ISSET(word, IXL_RX_DESC_EOP)) { 3244 1.11 yamaguch word0 = le64toh(rxd->qword0); 3245 1.11 yamaguch 3246 1.11 yamaguch if (ISSET(word, IXL_RX_DESC_L2TAG1P)) { 3247 1.84 yamaguch uint16_t vtag; 3248 1.84 yamaguch vtag = __SHIFTOUT(word0, IXL_RX_DESC_L2TAG1_MASK); 3249 1.84 yamaguch vlan_set_tag(m, le16toh(vtag)); 3250 1.11 yamaguch } 3251 1.11 yamaguch 3252 1.14 yamaguch if ((ifp->if_capenable & IXL_IFCAP_RXCSUM) != 0) 3253 1.14 yamaguch ixl_rx_csum(m, word); 3254 1.14 yamaguch 3255 1.1 yamaguch if (!ISSET(word, 3256 1.1 yamaguch IXL_RX_DESC_RXE | IXL_RX_DESC_OVERSIZE)) { 3257 1.1 yamaguch m_set_rcvif(m, ifp); 3258 1.99 riastrad if_statinc_ref(ifp, nsr, if_ipackets); 3259 1.99 riastrad if_statadd_ref(ifp, nsr, if_ibytes, 3260 1.35 thorpej m->m_pkthdr.len); 3261 1.71 yamaguch if_percpuq_enqueue(sc->sc_ipq, m); 3262 1.1 yamaguch } else { 3263 1.99 riastrad if_statinc_ref(ifp, nsr, if_ierrors); 3264 1.1 yamaguch m_freem(m); 3265 1.1 yamaguch } 3266 1.1 yamaguch 3267 1.1 yamaguch rxr->rxr_m_head = NULL; 3268 1.1 yamaguch rxr->rxr_m_tail = &rxr->rxr_m_head; 3269 1.1 yamaguch } 3270 1.1 yamaguch 3271 1.1 yamaguch cons++; 3272 1.1 yamaguch cons &= mask; 3273 1.1 yamaguch 3274 1.1 yamaguch done = 1; 3275 1.1 yamaguch } while (cons != prod); 3276 1.1 yamaguch 3277 1.1 yamaguch if (done) { 3278 1.1 yamaguch rxr->rxr_cons = cons; 3279 1.1 yamaguch if (ixl_rxfill(sc, rxr) == -1) 3280 1.99 riastrad if_statinc_ref(ifp, nsr, if_iqdrops); 3281 1.1 yamaguch } 3282 1.1 yamaguch 3283 1.35 thorpej IF_STAT_PUTREF(ifp); 3284 1.35 thorpej 3285 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&rxr->rxr_mem), 3286 1.1 yamaguch 0, IXL_DMA_LEN(&rxr->rxr_mem), 3287 1.1 yamaguch BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 3288 1.1 yamaguch 3289 1.1 yamaguch return more; 3290 1.1 yamaguch } 3291 1.1 yamaguch 3292 1.1 yamaguch static int 3293 1.1 yamaguch ixl_rxfill(struct ixl_softc *sc, struct ixl_rx_ring *rxr) 3294 1.1 yamaguch { 3295 1.11 yamaguch struct ixl_rx_rd_desc_32 *ring, *rxd; 3296 1.1 yamaguch struct ixl_rx_map *rxm; 3297 1.1 yamaguch bus_dmamap_t map; 3298 1.1 yamaguch struct mbuf *m; 3299 1.1 yamaguch unsigned int prod; 3300 1.1 yamaguch unsigned int slots; 3301 1.1 yamaguch unsigned int mask; 3302 1.1 yamaguch int post = 0, error = 0; 3303 1.1 yamaguch 3304 1.1 yamaguch KASSERT(mutex_owned(&rxr->rxr_lock)); 3305 1.1 yamaguch 3306 1.1 yamaguch prod = rxr->rxr_prod; 3307 1.1 yamaguch slots = ixl_rxr_unrefreshed(rxr->rxr_prod, rxr->rxr_cons, 3308 1.1 yamaguch sc->sc_rx_ring_ndescs); 3309 1.1 yamaguch 3310 1.1 yamaguch ring = IXL_DMA_KVA(&rxr->rxr_mem); 3311 1.1 yamaguch mask = sc->sc_rx_ring_ndescs - 1; 3312 1.1 yamaguch 3313 1.1 yamaguch if (__predict_false(slots <= 0)) 3314 1.1 yamaguch return -1; 3315 1.1 yamaguch 3316 1.1 yamaguch do { 3317 1.1 yamaguch rxm = &rxr->rxr_maps[prod]; 3318 1.1 yamaguch 3319 1.1 yamaguch MGETHDR(m, M_DONTWAIT, MT_DATA); 3320 1.1 yamaguch if (m == NULL) { 3321 1.1 yamaguch rxr->rxr_mgethdr_failed.ev_count++; 3322 1.1 yamaguch error = -1; 3323 1.1 yamaguch break; 3324 1.1 yamaguch } 3325 1.1 yamaguch 3326 1.1 yamaguch MCLGET(m, M_DONTWAIT); 3327 1.1 yamaguch if (!ISSET(m->m_flags, M_EXT)) { 3328 1.1 yamaguch rxr->rxr_mgetcl_failed.ev_count++; 3329 1.1 yamaguch error = -1; 3330 1.1 yamaguch m_freem(m); 3331 1.1 yamaguch break; 3332 1.1 yamaguch } 3333 1.1 yamaguch 3334 1.29 yamaguch m->m_len = m->m_pkthdr.len = MCLBYTES; 3335 1.1 yamaguch m_adj(m, ETHER_ALIGN); 3336 1.1 yamaguch 3337 1.1 yamaguch map = rxm->rxm_map; 3338 1.1 yamaguch 3339 1.1 yamaguch if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, 3340 1.1 yamaguch BUS_DMA_READ | BUS_DMA_NOWAIT) != 0) { 3341 1.1 yamaguch rxr->rxr_mbuf_load_failed.ev_count++; 3342 1.1 yamaguch error = -1; 3343 1.1 yamaguch m_freem(m); 3344 1.1 yamaguch break; 3345 1.1 yamaguch } 3346 1.1 yamaguch 3347 1.1 yamaguch rxm->rxm_m = m; 3348 1.1 yamaguch 3349 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 3350 1.1 yamaguch BUS_DMASYNC_PREREAD); 3351 1.1 yamaguch 3352 1.1 yamaguch rxd = &ring[prod]; 3353 1.1 yamaguch 3354 1.1 yamaguch rxd->paddr = htole64(map->dm_segs[0].ds_addr); 3355 1.1 yamaguch rxd->haddr = htole64(0); 3356 1.1 yamaguch 3357 1.1 yamaguch prod++; 3358 1.1 yamaguch prod &= mask; 3359 1.1 yamaguch 3360 1.1 yamaguch post = 1; 3361 1.1 yamaguch 3362 1.1 yamaguch } while (--slots); 3363 1.1 yamaguch 3364 1.1 yamaguch if (post) { 3365 1.1 yamaguch rxr->rxr_prod = prod; 3366 1.1 yamaguch ixl_wr(sc, rxr->rxr_tail, prod); 3367 1.1 yamaguch } 3368 1.1 yamaguch 3369 1.1 yamaguch return error; 3370 1.1 yamaguch } 3371 1.1 yamaguch 3372 1.1 yamaguch static inline int 3373 1.1 yamaguch ixl_handle_queue_common(struct ixl_softc *sc, struct ixl_queue_pair *qp, 3374 1.1 yamaguch u_int txlimit, struct evcnt *txevcnt, 3375 1.1 yamaguch u_int rxlimit, struct evcnt *rxevcnt) 3376 1.1 yamaguch { 3377 1.1 yamaguch struct ixl_tx_ring *txr = qp->qp_txr; 3378 1.1 yamaguch struct ixl_rx_ring *rxr = qp->qp_rxr; 3379 1.1 yamaguch int txmore, rxmore; 3380 1.1 yamaguch int rv; 3381 1.1 yamaguch 3382 1.1 yamaguch mutex_enter(&txr->txr_lock); 3383 1.1 yamaguch txevcnt->ev_count++; 3384 1.1 yamaguch txmore = ixl_txeof(sc, txr, txlimit); 3385 1.1 yamaguch mutex_exit(&txr->txr_lock); 3386 1.1 yamaguch 3387 1.1 yamaguch mutex_enter(&rxr->rxr_lock); 3388 1.1 yamaguch rxevcnt->ev_count++; 3389 1.1 yamaguch rxmore = ixl_rxeof(sc, rxr, rxlimit); 3390 1.1 yamaguch mutex_exit(&rxr->rxr_lock); 3391 1.1 yamaguch 3392 1.1 yamaguch rv = txmore | (rxmore << 1); 3393 1.1 yamaguch 3394 1.1 yamaguch return rv; 3395 1.1 yamaguch } 3396 1.1 yamaguch 3397 1.1 yamaguch static void 3398 1.1 yamaguch ixl_sched_handle_queue(struct ixl_softc *sc, struct ixl_queue_pair *qp) 3399 1.1 yamaguch { 3400 1.1 yamaguch 3401 1.1 yamaguch if (qp->qp_workqueue) 3402 1.45 yamaguch workqueue_enqueue(sc->sc_workq_txrx, &qp->qp_work, NULL); 3403 1.1 yamaguch else 3404 1.1 yamaguch softint_schedule(qp->qp_si); 3405 1.1 yamaguch } 3406 1.1 yamaguch 3407 1.1 yamaguch static int 3408 1.1 yamaguch ixl_intr(void *xsc) 3409 1.1 yamaguch { 3410 1.1 yamaguch struct ixl_softc *sc = xsc; 3411 1.1 yamaguch struct ixl_tx_ring *txr; 3412 1.1 yamaguch struct ixl_rx_ring *rxr; 3413 1.1 yamaguch uint32_t icr, rxintr, txintr; 3414 1.1 yamaguch int rv = 0; 3415 1.1 yamaguch unsigned int i; 3416 1.1 yamaguch 3417 1.1 yamaguch KASSERT(sc != NULL); 3418 1.1 yamaguch 3419 1.1 yamaguch ixl_enable_other_intr(sc); 3420 1.1 yamaguch icr = ixl_rd(sc, I40E_PFINT_ICR0); 3421 1.1 yamaguch 3422 1.1 yamaguch if (ISSET(icr, I40E_PFINT_ICR0_ADMINQ_MASK)) { 3423 1.1 yamaguch atomic_inc_64(&sc->sc_event_atq.ev_count); 3424 1.1 yamaguch ixl_atq_done(sc); 3425 1.1 yamaguch ixl_work_add(sc->sc_workq, &sc->sc_arq_task); 3426 1.1 yamaguch rv = 1; 3427 1.1 yamaguch } 3428 1.1 yamaguch 3429 1.1 yamaguch if (ISSET(icr, I40E_PFINT_ICR0_LINK_STAT_CHANGE_MASK)) { 3430 1.1 yamaguch atomic_inc_64(&sc->sc_event_link.ev_count); 3431 1.1 yamaguch ixl_work_add(sc->sc_workq, &sc->sc_link_state_task); 3432 1.1 yamaguch rv = 1; 3433 1.1 yamaguch } 3434 1.1 yamaguch 3435 1.1 yamaguch rxintr = icr & I40E_INTR_NOTX_RX_MASK; 3436 1.1 yamaguch txintr = icr & I40E_INTR_NOTX_TX_MASK; 3437 1.1 yamaguch 3438 1.1 yamaguch if (txintr || rxintr) { 3439 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 3440 1.1 yamaguch txr = sc->sc_qps[i].qp_txr; 3441 1.1 yamaguch rxr = sc->sc_qps[i].qp_rxr; 3442 1.1 yamaguch 3443 1.1 yamaguch ixl_handle_queue_common(sc, &sc->sc_qps[i], 3444 1.1 yamaguch IXL_TXRX_PROCESS_UNLIMIT, &txr->txr_intr, 3445 1.1 yamaguch IXL_TXRX_PROCESS_UNLIMIT, &rxr->rxr_intr); 3446 1.1 yamaguch } 3447 1.1 yamaguch rv = 1; 3448 1.1 yamaguch } 3449 1.1 yamaguch 3450 1.1 yamaguch return rv; 3451 1.1 yamaguch } 3452 1.1 yamaguch 3453 1.1 yamaguch static int 3454 1.1 yamaguch ixl_queue_intr(void *xqp) 3455 1.1 yamaguch { 3456 1.1 yamaguch struct ixl_queue_pair *qp = xqp; 3457 1.1 yamaguch struct ixl_tx_ring *txr = qp->qp_txr; 3458 1.1 yamaguch struct ixl_rx_ring *rxr = qp->qp_rxr; 3459 1.1 yamaguch struct ixl_softc *sc = qp->qp_sc; 3460 1.1 yamaguch u_int txlimit, rxlimit; 3461 1.1 yamaguch int more; 3462 1.1 yamaguch 3463 1.1 yamaguch txlimit = sc->sc_tx_intr_process_limit; 3464 1.1 yamaguch rxlimit = sc->sc_rx_intr_process_limit; 3465 1.1 yamaguch qp->qp_workqueue = sc->sc_txrx_workqueue; 3466 1.1 yamaguch 3467 1.1 yamaguch more = ixl_handle_queue_common(sc, qp, 3468 1.1 yamaguch txlimit, &txr->txr_intr, rxlimit, &rxr->rxr_intr); 3469 1.1 yamaguch 3470 1.1 yamaguch if (more != 0) { 3471 1.1 yamaguch ixl_sched_handle_queue(sc, qp); 3472 1.1 yamaguch } else { 3473 1.1 yamaguch /* for ALTQ */ 3474 1.1 yamaguch if (txr->txr_qid == 0) 3475 1.1 yamaguch if_schedule_deferred_start(&sc->sc_ec.ec_if); 3476 1.1 yamaguch softint_schedule(txr->txr_si); 3477 1.1 yamaguch 3478 1.1 yamaguch ixl_enable_queue_intr(sc, qp); 3479 1.1 yamaguch } 3480 1.1 yamaguch 3481 1.1 yamaguch return 1; 3482 1.1 yamaguch } 3483 1.1 yamaguch 3484 1.1 yamaguch static void 3485 1.45 yamaguch ixl_handle_queue_wk(struct work *wk, void *xsc) 3486 1.45 yamaguch { 3487 1.45 yamaguch struct ixl_queue_pair *qp; 3488 1.45 yamaguch 3489 1.45 yamaguch qp = container_of(wk, struct ixl_queue_pair, qp_work); 3490 1.45 yamaguch ixl_handle_queue(qp); 3491 1.45 yamaguch } 3492 1.45 yamaguch 3493 1.45 yamaguch static void 3494 1.1 yamaguch ixl_handle_queue(void *xqp) 3495 1.1 yamaguch { 3496 1.1 yamaguch struct ixl_queue_pair *qp = xqp; 3497 1.1 yamaguch struct ixl_softc *sc = qp->qp_sc; 3498 1.1 yamaguch struct ixl_tx_ring *txr = qp->qp_txr; 3499 1.1 yamaguch struct ixl_rx_ring *rxr = qp->qp_rxr; 3500 1.1 yamaguch u_int txlimit, rxlimit; 3501 1.1 yamaguch int more; 3502 1.1 yamaguch 3503 1.1 yamaguch txlimit = sc->sc_tx_process_limit; 3504 1.1 yamaguch rxlimit = sc->sc_rx_process_limit; 3505 1.1 yamaguch 3506 1.1 yamaguch more = ixl_handle_queue_common(sc, qp, 3507 1.1 yamaguch txlimit, &txr->txr_defer, rxlimit, &rxr->rxr_defer); 3508 1.1 yamaguch 3509 1.1 yamaguch if (more != 0) 3510 1.1 yamaguch ixl_sched_handle_queue(sc, qp); 3511 1.1 yamaguch else 3512 1.1 yamaguch ixl_enable_queue_intr(sc, qp); 3513 1.1 yamaguch } 3514 1.1 yamaguch 3515 1.1 yamaguch static inline void 3516 1.1 yamaguch ixl_print_hmc_error(struct ixl_softc *sc, uint32_t reg) 3517 1.1 yamaguch { 3518 1.1 yamaguch uint32_t hmc_idx, hmc_isvf; 3519 1.1 yamaguch uint32_t hmc_errtype, hmc_objtype, hmc_data; 3520 1.1 yamaguch 3521 1.1 yamaguch hmc_idx = reg & I40E_PFHMC_ERRORINFO_PMF_INDEX_MASK; 3522 1.1 yamaguch hmc_idx = hmc_idx >> I40E_PFHMC_ERRORINFO_PMF_INDEX_SHIFT; 3523 1.1 yamaguch hmc_isvf = reg & I40E_PFHMC_ERRORINFO_PMF_ISVF_MASK; 3524 1.1 yamaguch hmc_isvf = hmc_isvf >> I40E_PFHMC_ERRORINFO_PMF_ISVF_SHIFT; 3525 1.1 yamaguch hmc_errtype = reg & I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_MASK; 3526 1.1 yamaguch hmc_errtype = hmc_errtype >> I40E_PFHMC_ERRORINFO_HMC_ERROR_TYPE_SHIFT; 3527 1.1 yamaguch hmc_objtype = reg & I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_MASK; 3528 1.1 yamaguch hmc_objtype = hmc_objtype >> I40E_PFHMC_ERRORINFO_HMC_OBJECT_TYPE_SHIFT; 3529 1.1 yamaguch hmc_data = ixl_rd(sc, I40E_PFHMC_ERRORDATA); 3530 1.1 yamaguch 3531 1.1 yamaguch device_printf(sc->sc_dev, 3532 1.1 yamaguch "HMC Error (idx=0x%x, isvf=0x%x, err=0x%x, obj=0x%x, data=0x%x)\n", 3533 1.1 yamaguch hmc_idx, hmc_isvf, hmc_errtype, hmc_objtype, hmc_data); 3534 1.1 yamaguch } 3535 1.1 yamaguch 3536 1.1 yamaguch static int 3537 1.1 yamaguch ixl_other_intr(void *xsc) 3538 1.1 yamaguch { 3539 1.1 yamaguch struct ixl_softc *sc = xsc; 3540 1.1 yamaguch uint32_t icr, mask, reg; 3541 1.100 christos int rv = 0; 3542 1.1 yamaguch 3543 1.1 yamaguch icr = ixl_rd(sc, I40E_PFINT_ICR0); 3544 1.1 yamaguch mask = ixl_rd(sc, I40E_PFINT_ICR0_ENA); 3545 1.1 yamaguch 3546 1.1 yamaguch if (ISSET(icr, I40E_PFINT_ICR0_ADMINQ_MASK)) { 3547 1.1 yamaguch atomic_inc_64(&sc->sc_event_atq.ev_count); 3548 1.1 yamaguch ixl_atq_done(sc); 3549 1.1 yamaguch ixl_work_add(sc->sc_workq, &sc->sc_arq_task); 3550 1.1 yamaguch rv = 1; 3551 1.1 yamaguch } 3552 1.1 yamaguch 3553 1.1 yamaguch if (ISSET(icr, I40E_PFINT_ICR0_LINK_STAT_CHANGE_MASK)) { 3554 1.1 yamaguch if (ISSET(sc->sc_ec.ec_if.if_flags, IFF_DEBUG)) 3555 1.1 yamaguch device_printf(sc->sc_dev, "link stat changed\n"); 3556 1.1 yamaguch 3557 1.1 yamaguch atomic_inc_64(&sc->sc_event_link.ev_count); 3558 1.1 yamaguch ixl_work_add(sc->sc_workq, &sc->sc_link_state_task); 3559 1.1 yamaguch rv = 1; 3560 1.1 yamaguch } 3561 1.1 yamaguch 3562 1.1 yamaguch if (ISSET(icr, I40E_PFINT_ICR0_GRST_MASK)) { 3563 1.1 yamaguch CLR(mask, I40E_PFINT_ICR0_ENA_GRST_MASK); 3564 1.1 yamaguch reg = ixl_rd(sc, I40E_GLGEN_RSTAT); 3565 1.1 yamaguch reg = reg & I40E_GLGEN_RSTAT_RESET_TYPE_MASK; 3566 1.1 yamaguch reg = reg >> I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT; 3567 1.1 yamaguch 3568 1.1 yamaguch device_printf(sc->sc_dev, "GRST: %s\n", 3569 1.1 yamaguch reg == I40E_RESET_CORER ? "CORER" : 3570 1.1 yamaguch reg == I40E_RESET_GLOBR ? "GLOBR" : 3571 1.1 yamaguch reg == I40E_RESET_EMPR ? "EMPR" : 3572 1.1 yamaguch "POR"); 3573 1.1 yamaguch } 3574 1.1 yamaguch 3575 1.1 yamaguch if (ISSET(icr, I40E_PFINT_ICR0_ECC_ERR_MASK)) 3576 1.1 yamaguch atomic_inc_64(&sc->sc_event_ecc_err.ev_count); 3577 1.1 yamaguch if (ISSET(icr, I40E_PFINT_ICR0_PCI_EXCEPTION_MASK)) 3578 1.1 yamaguch atomic_inc_64(&sc->sc_event_pci_exception.ev_count); 3579 1.1 yamaguch if (ISSET(icr, I40E_PFINT_ICR0_PE_CRITERR_MASK)) 3580 1.1 yamaguch atomic_inc_64(&sc->sc_event_crit_err.ev_count); 3581 1.1 yamaguch 3582 1.1 yamaguch if (ISSET(icr, IXL_ICR0_CRIT_ERR_MASK)) { 3583 1.1 yamaguch CLR(mask, IXL_ICR0_CRIT_ERR_MASK); 3584 1.1 yamaguch device_printf(sc->sc_dev, "critical error\n"); 3585 1.1 yamaguch } 3586 1.1 yamaguch 3587 1.1 yamaguch if (ISSET(icr, I40E_PFINT_ICR0_HMC_ERR_MASK)) { 3588 1.1 yamaguch reg = ixl_rd(sc, I40E_PFHMC_ERRORINFO); 3589 1.1 yamaguch if (ISSET(reg, I40E_PFHMC_ERRORINFO_ERROR_DETECTED_MASK)) 3590 1.1 yamaguch ixl_print_hmc_error(sc, reg); 3591 1.1 yamaguch ixl_wr(sc, I40E_PFHMC_ERRORINFO, 0); 3592 1.1 yamaguch } 3593 1.1 yamaguch 3594 1.1 yamaguch ixl_wr(sc, I40E_PFINT_ICR0_ENA, mask); 3595 1.1 yamaguch ixl_flush(sc); 3596 1.1 yamaguch ixl_enable_other_intr(sc); 3597 1.1 yamaguch return rv; 3598 1.1 yamaguch } 3599 1.1 yamaguch 3600 1.1 yamaguch static void 3601 1.92 yamaguch ixl_get_link_status_done_work(void *xsc) 3602 1.1 yamaguch { 3603 1.92 yamaguch struct ixl_softc *sc = xsc; 3604 1.92 yamaguch struct ixl_aq_desc *iaq, iaq_buf; 3605 1.1 yamaguch 3606 1.92 yamaguch mutex_enter(&sc->sc_atq_lock); 3607 1.92 yamaguch iaq = &sc->sc_link_state_atq.iatq_desc; 3608 1.92 yamaguch iaq_buf = *iaq; 3609 1.92 yamaguch mutex_exit(&sc->sc_atq_lock); 3610 1.62 yamaguch 3611 1.62 yamaguch ixl_link_state_update(sc, &iaq_buf); 3612 1.92 yamaguch 3613 1.62 yamaguch mutex_enter(&sc->sc_atq_lock); 3614 1.92 yamaguch CLR(iaq->iaq_flags, htole16(IXL_AQ_DD)); 3615 1.92 yamaguch ixl_wakeup(sc, iaq); 3616 1.92 yamaguch mutex_exit(&sc->sc_atq_lock); 3617 1.1 yamaguch } 3618 1.1 yamaguch 3619 1.1 yamaguch static void 3620 1.92 yamaguch ixl_get_link_status_done(struct ixl_softc *sc, 3621 1.92 yamaguch const struct ixl_aq_desc *iaq) 3622 1.92 yamaguch { 3623 1.92 yamaguch 3624 1.92 yamaguch ixl_work_add(sc->sc_workq, &sc->sc_link_state_done_task); 3625 1.92 yamaguch } 3626 1.92 yamaguch 3627 1.92 yamaguch static int 3628 1.92 yamaguch ixl_get_link_status(struct ixl_softc *sc, enum ixl_link_flags flags) 3629 1.1 yamaguch { 3630 1.92 yamaguch struct ixl_atq *iatq; 3631 1.1 yamaguch struct ixl_aq_desc *iaq; 3632 1.1 yamaguch struct ixl_aq_link_param *param; 3633 1.59 yamaguch int error; 3634 1.1 yamaguch 3635 1.57 yamaguch mutex_enter(&sc->sc_atq_lock); 3636 1.57 yamaguch 3637 1.92 yamaguch iatq = &sc->sc_link_state_atq; 3638 1.92 yamaguch iaq = &iatq->iatq_desc; 3639 1.90 yamaguch 3640 1.92 yamaguch if (!sc->sc_link_state_atq.iatq_inuse && 3641 1.92 yamaguch !ISSET(iaq->iaq_flags, htole16(IXL_AQ_DD))) { 3642 1.92 yamaguch memset(iaq, 0, sizeof(*iaq)); 3643 1.92 yamaguch iaq->iaq_opcode = htole16(IXL_AQ_OP_PHY_LINK_STATUS); 3644 1.92 yamaguch param = (struct ixl_aq_link_param *)iaq->iaq_param; 3645 1.92 yamaguch param->notify = IXL_AQ_LINK_NOTIFY; 3646 1.1 yamaguch 3647 1.92 yamaguch KASSERT(iatq->iatq_fn == ixl_get_link_status_done); 3648 1.92 yamaguch error = ixl_atq_post_locked(sc, iatq); 3649 1.92 yamaguch if (error != 0) 3650 1.92 yamaguch goto out; 3651 1.92 yamaguch } else { 3652 1.92 yamaguch /* the previous command is not completed */ 3653 1.92 yamaguch error = EBUSY; 3654 1.92 yamaguch } 3655 1.62 yamaguch 3656 1.92 yamaguch if (ISSET(flags, IXL_LINK_FLAG_WAITDONE)) { 3657 1.92 yamaguch do { 3658 1.92 yamaguch error = cv_timedwait(&sc->sc_atq_cv, &sc->sc_atq_lock, 3659 1.92 yamaguch IXL_ATQ_EXEC_TIMEOUT); 3660 1.92 yamaguch if (error == EWOULDBLOCK) 3661 1.92 yamaguch break; 3662 1.92 yamaguch } while (iatq->iatq_inuse || 3663 1.92 yamaguch ISSET(iaq->iaq_flags, htole16(IXL_AQ_DD))); 3664 1.59 yamaguch } 3665 1.59 yamaguch 3666 1.92 yamaguch out: 3667 1.57 yamaguch mutex_exit(&sc->sc_atq_lock); 3668 1.92 yamaguch 3669 1.92 yamaguch return error; 3670 1.92 yamaguch } 3671 1.92 yamaguch 3672 1.92 yamaguch static void 3673 1.92 yamaguch ixl_get_link_status_work(void *xsc) 3674 1.92 yamaguch { 3675 1.92 yamaguch struct ixl_softc *sc = xsc; 3676 1.92 yamaguch 3677 1.92 yamaguch /* 3678 1.92 yamaguch * IXL_LINK_FLAG_WAITDONE causes deadlock 3679 1.92 yamaguch * because of doing ixl_gt_link_status_done_work() 3680 1.92 yamaguch * in the same workqueue. 3681 1.92 yamaguch */ 3682 1.92 yamaguch (void)ixl_get_link_status(sc, IXL_LINK_NOFLAGS); 3683 1.1 yamaguch } 3684 1.1 yamaguch 3685 1.1 yamaguch static void 3686 1.4 yamaguch ixl_link_state_update(struct ixl_softc *sc, const struct ixl_aq_desc *iaq) 3687 1.1 yamaguch { 3688 1.1 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 3689 1.1 yamaguch int link_state; 3690 1.1 yamaguch 3691 1.62 yamaguch mutex_enter(&sc->sc_cfg_lock); 3692 1.62 yamaguch link_state = ixl_set_link_status_locked(sc, iaq); 3693 1.62 yamaguch mutex_exit(&sc->sc_cfg_lock); 3694 1.1 yamaguch 3695 1.1 yamaguch if (ifp->if_link_state != link_state) 3696 1.1 yamaguch if_link_state_change(ifp, link_state); 3697 1.1 yamaguch 3698 1.1 yamaguch if (link_state != LINK_STATE_DOWN) { 3699 1.62 yamaguch kpreempt_disable(); 3700 1.1 yamaguch if_schedule_deferred_start(ifp); 3701 1.62 yamaguch kpreempt_enable(); 3702 1.1 yamaguch } 3703 1.1 yamaguch } 3704 1.1 yamaguch 3705 1.1 yamaguch static void 3706 1.4 yamaguch ixl_aq_dump(const struct ixl_softc *sc, const struct ixl_aq_desc *iaq, 3707 1.4 yamaguch const char *msg) 3708 1.1 yamaguch { 3709 1.1 yamaguch char buf[512]; 3710 1.1 yamaguch size_t len; 3711 1.1 yamaguch 3712 1.1 yamaguch len = sizeof(buf); 3713 1.1 yamaguch buf[--len] = '\0'; 3714 1.1 yamaguch 3715 1.4 yamaguch device_printf(sc->sc_dev, "%s\n", msg); 3716 1.1 yamaguch snprintb(buf, len, IXL_AQ_FLAGS_FMT, le16toh(iaq->iaq_flags)); 3717 1.1 yamaguch device_printf(sc->sc_dev, "flags %s opcode %04x\n", 3718 1.1 yamaguch buf, le16toh(iaq->iaq_opcode)); 3719 1.1 yamaguch device_printf(sc->sc_dev, "datalen %u retval %u\n", 3720 1.1 yamaguch le16toh(iaq->iaq_datalen), le16toh(iaq->iaq_retval)); 3721 1.1 yamaguch device_printf(sc->sc_dev, "cookie %016" PRIx64 "\n", iaq->iaq_cookie); 3722 1.1 yamaguch device_printf(sc->sc_dev, "%08x %08x %08x %08x\n", 3723 1.1 yamaguch le32toh(iaq->iaq_param[0]), le32toh(iaq->iaq_param[1]), 3724 1.1 yamaguch le32toh(iaq->iaq_param[2]), le32toh(iaq->iaq_param[3])); 3725 1.1 yamaguch } 3726 1.1 yamaguch 3727 1.1 yamaguch static void 3728 1.1 yamaguch ixl_arq(void *xsc) 3729 1.1 yamaguch { 3730 1.1 yamaguch struct ixl_softc *sc = xsc; 3731 1.1 yamaguch struct ixl_aq_desc *arq, *iaq; 3732 1.1 yamaguch struct ixl_aq_buf *aqb; 3733 1.1 yamaguch unsigned int cons = sc->sc_arq_cons; 3734 1.1 yamaguch unsigned int prod; 3735 1.1 yamaguch int done = 0; 3736 1.1 yamaguch 3737 1.1 yamaguch prod = ixl_rd(sc, sc->sc_aq_regs->arq_head) & 3738 1.1 yamaguch sc->sc_aq_regs->arq_head_mask; 3739 1.1 yamaguch 3740 1.1 yamaguch if (cons == prod) 3741 1.1 yamaguch goto done; 3742 1.1 yamaguch 3743 1.1 yamaguch arq = IXL_DMA_KVA(&sc->sc_arq); 3744 1.1 yamaguch 3745 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq), 3746 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_arq), 3747 1.1 yamaguch BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 3748 1.1 yamaguch 3749 1.1 yamaguch do { 3750 1.1 yamaguch iaq = &arq[cons]; 3751 1.1 yamaguch aqb = sc->sc_arq_live[cons]; 3752 1.1 yamaguch 3753 1.1 yamaguch KASSERT(aqb != NULL); 3754 1.1 yamaguch 3755 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0, IXL_AQ_BUFLEN, 3756 1.1 yamaguch BUS_DMASYNC_POSTREAD); 3757 1.1 yamaguch 3758 1.1 yamaguch if (ISSET(sc->sc_ec.ec_if.if_flags, IFF_DEBUG)) 3759 1.4 yamaguch ixl_aq_dump(sc, iaq, "arq event"); 3760 1.1 yamaguch 3761 1.1 yamaguch switch (iaq->iaq_opcode) { 3762 1.1 yamaguch case htole16(IXL_AQ_OP_PHY_LINK_STATUS): 3763 1.4 yamaguch ixl_link_state_update(sc, iaq); 3764 1.1 yamaguch break; 3765 1.1 yamaguch } 3766 1.1 yamaguch 3767 1.1 yamaguch memset(iaq, 0, sizeof(*iaq)); 3768 1.1 yamaguch sc->sc_arq_live[cons] = NULL; 3769 1.1 yamaguch SIMPLEQ_INSERT_TAIL(&sc->sc_arq_idle, aqb, aqb_entry); 3770 1.1 yamaguch 3771 1.1 yamaguch cons++; 3772 1.1 yamaguch cons &= IXL_AQ_MASK; 3773 1.1 yamaguch 3774 1.1 yamaguch done = 1; 3775 1.1 yamaguch } while (cons != prod); 3776 1.1 yamaguch 3777 1.1 yamaguch if (done) { 3778 1.1 yamaguch sc->sc_arq_cons = cons; 3779 1.1 yamaguch ixl_arq_fill(sc); 3780 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_arq), 3781 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_arq), 3782 1.1 yamaguch BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 3783 1.1 yamaguch } 3784 1.1 yamaguch 3785 1.1 yamaguch done: 3786 1.1 yamaguch ixl_enable_other_intr(sc); 3787 1.1 yamaguch } 3788 1.1 yamaguch 3789 1.1 yamaguch static void 3790 1.4 yamaguch ixl_atq_set(struct ixl_atq *iatq, 3791 1.4 yamaguch void (*fn)(struct ixl_softc *, const struct ixl_aq_desc *)) 3792 1.1 yamaguch { 3793 1.4 yamaguch 3794 1.1 yamaguch iatq->iatq_fn = fn; 3795 1.1 yamaguch } 3796 1.1 yamaguch 3797 1.1 yamaguch static int 3798 1.1 yamaguch ixl_atq_post_locked(struct ixl_softc *sc, struct ixl_atq *iatq) 3799 1.1 yamaguch { 3800 1.1 yamaguch struct ixl_aq_desc *atq, *slot; 3801 1.1 yamaguch unsigned int prod, cons, prod_next; 3802 1.1 yamaguch 3803 1.1 yamaguch /* assert locked */ 3804 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_atq_lock)); 3805 1.1 yamaguch 3806 1.1 yamaguch atq = IXL_DMA_KVA(&sc->sc_atq); 3807 1.1 yamaguch prod = sc->sc_atq_prod; 3808 1.1 yamaguch cons = sc->sc_atq_cons; 3809 1.1 yamaguch prod_next = (prod +1) & IXL_AQ_MASK; 3810 1.1 yamaguch 3811 1.1 yamaguch if (cons == prod_next) 3812 1.1 yamaguch return ENOMEM; 3813 1.1 yamaguch 3814 1.1 yamaguch slot = &atq[prod]; 3815 1.1 yamaguch 3816 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 3817 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_POSTWRITE); 3818 1.1 yamaguch 3819 1.58 yamaguch KASSERT(iatq->iatq_fn != NULL); 3820 1.1 yamaguch *slot = iatq->iatq_desc; 3821 1.1 yamaguch slot->iaq_cookie = (uint64_t)((intptr_t)iatq); 3822 1.1 yamaguch 3823 1.1 yamaguch if (ISSET(sc->sc_ec.ec_if.if_flags, IFF_DEBUG)) 3824 1.4 yamaguch ixl_aq_dump(sc, slot, "atq command"); 3825 1.1 yamaguch 3826 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 3827 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_PREWRITE); 3828 1.1 yamaguch 3829 1.1 yamaguch sc->sc_atq_prod = prod_next; 3830 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_tail, sc->sc_atq_prod); 3831 1.90 yamaguch iatq->iatq_inuse = true; 3832 1.1 yamaguch 3833 1.1 yamaguch return 0; 3834 1.1 yamaguch } 3835 1.1 yamaguch 3836 1.1 yamaguch static void 3837 1.1 yamaguch ixl_atq_done_locked(struct ixl_softc *sc) 3838 1.1 yamaguch { 3839 1.1 yamaguch struct ixl_aq_desc *atq, *slot; 3840 1.1 yamaguch struct ixl_atq *iatq; 3841 1.1 yamaguch unsigned int cons; 3842 1.1 yamaguch unsigned int prod; 3843 1.1 yamaguch 3844 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_atq_lock)); 3845 1.1 yamaguch 3846 1.1 yamaguch prod = sc->sc_atq_prod; 3847 1.1 yamaguch cons = sc->sc_atq_cons; 3848 1.1 yamaguch 3849 1.1 yamaguch if (prod == cons) 3850 1.1 yamaguch return; 3851 1.1 yamaguch 3852 1.1 yamaguch atq = IXL_DMA_KVA(&sc->sc_atq); 3853 1.1 yamaguch 3854 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 3855 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), 3856 1.1 yamaguch BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 3857 1.1 yamaguch 3858 1.1 yamaguch do { 3859 1.1 yamaguch slot = &atq[cons]; 3860 1.1 yamaguch if (!ISSET(slot->iaq_flags, htole16(IXL_AQ_DD))) 3861 1.1 yamaguch break; 3862 1.1 yamaguch 3863 1.1 yamaguch iatq = (struct ixl_atq *)((intptr_t)slot->iaq_cookie); 3864 1.1 yamaguch iatq->iatq_desc = *slot; 3865 1.90 yamaguch iatq->iatq_inuse = false; 3866 1.1 yamaguch 3867 1.1 yamaguch memset(slot, 0, sizeof(*slot)); 3868 1.1 yamaguch 3869 1.4 yamaguch if (ISSET(sc->sc_ec.ec_if.if_flags, IFF_DEBUG)) 3870 1.4 yamaguch ixl_aq_dump(sc, &iatq->iatq_desc, "atq response"); 3871 1.4 yamaguch 3872 1.4 yamaguch (*iatq->iatq_fn)(sc, &iatq->iatq_desc); 3873 1.1 yamaguch 3874 1.1 yamaguch cons++; 3875 1.1 yamaguch cons &= IXL_AQ_MASK; 3876 1.1 yamaguch } while (cons != prod); 3877 1.1 yamaguch 3878 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 3879 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), 3880 1.1 yamaguch BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 3881 1.1 yamaguch 3882 1.1 yamaguch sc->sc_atq_cons = cons; 3883 1.1 yamaguch } 3884 1.1 yamaguch 3885 1.1 yamaguch static void 3886 1.1 yamaguch ixl_atq_done(struct ixl_softc *sc) 3887 1.1 yamaguch { 3888 1.1 yamaguch 3889 1.1 yamaguch mutex_enter(&sc->sc_atq_lock); 3890 1.1 yamaguch ixl_atq_done_locked(sc); 3891 1.1 yamaguch mutex_exit(&sc->sc_atq_lock); 3892 1.1 yamaguch } 3893 1.1 yamaguch 3894 1.1 yamaguch static void 3895 1.4 yamaguch ixl_wakeup(struct ixl_softc *sc, const struct ixl_aq_desc *iaq) 3896 1.1 yamaguch { 3897 1.1 yamaguch 3898 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_atq_lock)); 3899 1.1 yamaguch 3900 1.91 yamaguch cv_broadcast(&sc->sc_atq_cv); 3901 1.1 yamaguch } 3902 1.1 yamaguch 3903 1.1 yamaguch static int 3904 1.1 yamaguch ixl_atq_exec(struct ixl_softc *sc, struct ixl_atq *iatq) 3905 1.1 yamaguch { 3906 1.1 yamaguch int error; 3907 1.1 yamaguch 3908 1.59 yamaguch mutex_enter(&sc->sc_atq_lock); 3909 1.59 yamaguch error = ixl_atq_exec_locked(sc, iatq); 3910 1.59 yamaguch mutex_exit(&sc->sc_atq_lock); 3911 1.59 yamaguch 3912 1.59 yamaguch return error; 3913 1.59 yamaguch } 3914 1.59 yamaguch 3915 1.59 yamaguch static int 3916 1.59 yamaguch ixl_atq_exec_locked(struct ixl_softc *sc, struct ixl_atq *iatq) 3917 1.59 yamaguch { 3918 1.59 yamaguch int error; 3919 1.59 yamaguch 3920 1.59 yamaguch KASSERT(mutex_owned(&sc->sc_atq_lock)); 3921 1.1 yamaguch KASSERT(iatq->iatq_desc.iaq_cookie == 0); 3922 1.1 yamaguch 3923 1.1 yamaguch ixl_atq_set(iatq, ixl_wakeup); 3924 1.1 yamaguch 3925 1.1 yamaguch error = ixl_atq_post_locked(sc, iatq); 3926 1.59 yamaguch if (error) 3927 1.1 yamaguch return error; 3928 1.1 yamaguch 3929 1.91 yamaguch do { 3930 1.91 yamaguch error = cv_timedwait(&sc->sc_atq_cv, &sc->sc_atq_lock, 3931 1.91 yamaguch IXL_ATQ_EXEC_TIMEOUT); 3932 1.91 yamaguch if (error == EWOULDBLOCK) 3933 1.91 yamaguch break; 3934 1.91 yamaguch } while (iatq->iatq_inuse); 3935 1.1 yamaguch 3936 1.1 yamaguch return error; 3937 1.1 yamaguch } 3938 1.1 yamaguch 3939 1.1 yamaguch static int 3940 1.1 yamaguch ixl_atq_poll(struct ixl_softc *sc, struct ixl_aq_desc *iaq, unsigned int tm) 3941 1.1 yamaguch { 3942 1.1 yamaguch struct ixl_aq_desc *atq, *slot; 3943 1.1 yamaguch unsigned int prod; 3944 1.1 yamaguch unsigned int t = 0; 3945 1.1 yamaguch 3946 1.9 yamaguch mutex_enter(&sc->sc_atq_lock); 3947 1.9 yamaguch 3948 1.1 yamaguch atq = IXL_DMA_KVA(&sc->sc_atq); 3949 1.1 yamaguch prod = sc->sc_atq_prod; 3950 1.1 yamaguch slot = atq + prod; 3951 1.1 yamaguch 3952 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 3953 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_POSTWRITE); 3954 1.1 yamaguch 3955 1.1 yamaguch *slot = *iaq; 3956 1.1 yamaguch slot->iaq_flags |= htole16(IXL_AQ_SI); 3957 1.1 yamaguch 3958 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 3959 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_PREWRITE); 3960 1.1 yamaguch 3961 1.1 yamaguch prod++; 3962 1.1 yamaguch prod &= IXL_AQ_MASK; 3963 1.1 yamaguch sc->sc_atq_prod = prod; 3964 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->atq_tail, prod); 3965 1.1 yamaguch 3966 1.1 yamaguch while (ixl_rd(sc, sc->sc_aq_regs->atq_head) != prod) { 3967 1.1 yamaguch delaymsec(1); 3968 1.1 yamaguch 3969 1.9 yamaguch if (t++ > tm) { 3970 1.9 yamaguch mutex_exit(&sc->sc_atq_lock); 3971 1.1 yamaguch return ETIMEDOUT; 3972 1.9 yamaguch } 3973 1.1 yamaguch } 3974 1.1 yamaguch 3975 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 3976 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_POSTREAD); 3977 1.1 yamaguch *iaq = *slot; 3978 1.1 yamaguch memset(slot, 0, sizeof(*slot)); 3979 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 3980 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_PREREAD); 3981 1.1 yamaguch 3982 1.1 yamaguch sc->sc_atq_cons = prod; 3983 1.1 yamaguch 3984 1.9 yamaguch mutex_exit(&sc->sc_atq_lock); 3985 1.9 yamaguch 3986 1.1 yamaguch return 0; 3987 1.1 yamaguch } 3988 1.1 yamaguch 3989 1.1 yamaguch static int 3990 1.1 yamaguch ixl_get_version(struct ixl_softc *sc) 3991 1.1 yamaguch { 3992 1.1 yamaguch struct ixl_aq_desc iaq; 3993 1.1 yamaguch uint32_t fwbuild, fwver, apiver; 3994 1.1 yamaguch uint16_t api_maj_ver, api_min_ver; 3995 1.1 yamaguch 3996 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 3997 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_GET_VERSION); 3998 1.1 yamaguch 3999 1.1 yamaguch iaq.iaq_retval = le16toh(23); 4000 1.1 yamaguch 4001 1.1 yamaguch if (ixl_atq_poll(sc, &iaq, 2000) != 0) 4002 1.1 yamaguch return ETIMEDOUT; 4003 1.1 yamaguch if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK)) 4004 1.1 yamaguch return EIO; 4005 1.1 yamaguch 4006 1.1 yamaguch fwbuild = le32toh(iaq.iaq_param[1]); 4007 1.1 yamaguch fwver = le32toh(iaq.iaq_param[2]); 4008 1.1 yamaguch apiver = le32toh(iaq.iaq_param[3]); 4009 1.1 yamaguch 4010 1.1 yamaguch api_maj_ver = (uint16_t)apiver; 4011 1.1 yamaguch api_min_ver = (uint16_t)(apiver >> 16); 4012 1.1 yamaguch 4013 1.1 yamaguch aprint_normal(", FW %hu.%hu.%05u API %hu.%hu", (uint16_t)fwver, 4014 1.1 yamaguch (uint16_t)(fwver >> 16), fwbuild, api_maj_ver, api_min_ver); 4015 1.1 yamaguch 4016 1.26 yamaguch if (sc->sc_mac_type == I40E_MAC_X722) { 4017 1.26 yamaguch SET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_NVMLOCK | 4018 1.26 yamaguch IXL_SC_AQ_FLAG_NVMREAD); 4019 1.40 yamaguch SET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_RXCTL); 4020 1.41 yamaguch SET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_RSS); 4021 1.26 yamaguch } 4022 1.26 yamaguch 4023 1.25 yamaguch #define IXL_API_VER(maj, min) (((uint32_t)(maj) << 16) | (min)) 4024 1.25 yamaguch if (IXL_API_VER(api_maj_ver, api_min_ver) >= IXL_API_VER(1, 5)) { 4025 1.40 yamaguch SET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_RXCTL); 4026 1.26 yamaguch SET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_NVMLOCK); 4027 1.1 yamaguch } 4028 1.25 yamaguch #undef IXL_API_VER 4029 1.1 yamaguch 4030 1.1 yamaguch return 0; 4031 1.1 yamaguch } 4032 1.1 yamaguch 4033 1.1 yamaguch static int 4034 1.26 yamaguch ixl_get_nvm_version(struct ixl_softc *sc) 4035 1.26 yamaguch { 4036 1.26 yamaguch uint16_t nvmver, cfg_ptr, eetrack_hi, eetrack_lo, oem_hi, oem_lo; 4037 1.26 yamaguch uint32_t eetrack, oem; 4038 1.26 yamaguch uint16_t nvm_maj_ver, nvm_min_ver, oem_build; 4039 1.26 yamaguch uint8_t oem_ver, oem_patch; 4040 1.26 yamaguch 4041 1.26 yamaguch nvmver = cfg_ptr = eetrack_hi = eetrack_lo = oem_hi = oem_lo = 0; 4042 1.26 yamaguch ixl_rd16_nvm(sc, I40E_SR_NVM_DEV_STARTER_VERSION, &nvmver); 4043 1.26 yamaguch ixl_rd16_nvm(sc, I40E_SR_NVM_EETRACK_HI, &eetrack_hi); 4044 1.26 yamaguch ixl_rd16_nvm(sc, I40E_SR_NVM_EETRACK_LO, &eetrack_lo); 4045 1.26 yamaguch ixl_rd16_nvm(sc, I40E_SR_BOOT_CONFIG_PTR, &cfg_ptr); 4046 1.26 yamaguch ixl_rd16_nvm(sc, cfg_ptr + I40E_NVM_OEM_VER_OFF, &oem_hi); 4047 1.26 yamaguch ixl_rd16_nvm(sc, cfg_ptr + I40E_NVM_OEM_VER_OFF + 1, &oem_lo); 4048 1.26 yamaguch 4049 1.26 yamaguch nvm_maj_ver = (uint16_t)__SHIFTOUT(nvmver, IXL_NVM_VERSION_HI_MASK); 4050 1.26 yamaguch nvm_min_ver = (uint16_t)__SHIFTOUT(nvmver, IXL_NVM_VERSION_LO_MASK); 4051 1.26 yamaguch eetrack = ((uint32_t)eetrack_hi << 16) | eetrack_lo; 4052 1.26 yamaguch oem = ((uint32_t)oem_hi << 16) | oem_lo; 4053 1.26 yamaguch oem_ver = __SHIFTOUT(oem, IXL_NVM_OEMVERSION_MASK); 4054 1.26 yamaguch oem_build = __SHIFTOUT(oem, IXL_NVM_OEMBUILD_MASK); 4055 1.26 yamaguch oem_patch = __SHIFTOUT(oem, IXL_NVM_OEMPATCH_MASK); 4056 1.26 yamaguch 4057 1.26 yamaguch aprint_normal(" nvm %x.%02x etid %08x oem %d.%d.%d", 4058 1.26 yamaguch nvm_maj_ver, nvm_min_ver, eetrack, 4059 1.26 yamaguch oem_ver, oem_build, oem_patch); 4060 1.26 yamaguch 4061 1.26 yamaguch return 0; 4062 1.26 yamaguch } 4063 1.26 yamaguch 4064 1.26 yamaguch static int 4065 1.1 yamaguch ixl_pxe_clear(struct ixl_softc *sc) 4066 1.1 yamaguch { 4067 1.1 yamaguch struct ixl_aq_desc iaq; 4068 1.1 yamaguch int rv; 4069 1.1 yamaguch 4070 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4071 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_CLEAR_PXE_MODE); 4072 1.1 yamaguch iaq.iaq_param[0] = htole32(0x2); 4073 1.1 yamaguch 4074 1.1 yamaguch rv = ixl_atq_poll(sc, &iaq, 250); 4075 1.1 yamaguch 4076 1.1 yamaguch ixl_wr(sc, I40E_GLLAN_RCTL_0, 0x1); 4077 1.1 yamaguch 4078 1.1 yamaguch if (rv != 0) 4079 1.1 yamaguch return ETIMEDOUT; 4080 1.1 yamaguch 4081 1.1 yamaguch switch (iaq.iaq_retval) { 4082 1.1 yamaguch case htole16(IXL_AQ_RC_OK): 4083 1.1 yamaguch case htole16(IXL_AQ_RC_EEXIST): 4084 1.1 yamaguch break; 4085 1.1 yamaguch default: 4086 1.1 yamaguch return EIO; 4087 1.1 yamaguch } 4088 1.1 yamaguch 4089 1.1 yamaguch return 0; 4090 1.1 yamaguch } 4091 1.1 yamaguch 4092 1.1 yamaguch static int 4093 1.1 yamaguch ixl_lldp_shut(struct ixl_softc *sc) 4094 1.1 yamaguch { 4095 1.1 yamaguch struct ixl_aq_desc iaq; 4096 1.1 yamaguch 4097 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4098 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_LLDP_STOP_AGENT); 4099 1.1 yamaguch iaq.iaq_param[0] = htole32(IXL_LLDP_SHUTDOWN); 4100 1.1 yamaguch 4101 1.1 yamaguch if (ixl_atq_poll(sc, &iaq, 250) != 0) { 4102 1.1 yamaguch aprint_error_dev(sc->sc_dev, "STOP LLDP AGENT timeout\n"); 4103 1.1 yamaguch return -1; 4104 1.1 yamaguch } 4105 1.1 yamaguch 4106 1.1 yamaguch switch (iaq.iaq_retval) { 4107 1.1 yamaguch case htole16(IXL_AQ_RC_EMODE): 4108 1.1 yamaguch case htole16(IXL_AQ_RC_EPERM): 4109 1.1 yamaguch /* ignore silently */ 4110 1.1 yamaguch default: 4111 1.1 yamaguch break; 4112 1.1 yamaguch } 4113 1.1 yamaguch 4114 1.1 yamaguch return 0; 4115 1.1 yamaguch } 4116 1.1 yamaguch 4117 1.1 yamaguch static void 4118 1.1 yamaguch ixl_parse_hw_capability(struct ixl_softc *sc, struct ixl_aq_capability *cap) 4119 1.1 yamaguch { 4120 1.1 yamaguch uint16_t id; 4121 1.1 yamaguch uint32_t number, logical_id; 4122 1.1 yamaguch 4123 1.1 yamaguch id = le16toh(cap->cap_id); 4124 1.1 yamaguch number = le32toh(cap->number); 4125 1.1 yamaguch logical_id = le32toh(cap->logical_id); 4126 1.1 yamaguch 4127 1.1 yamaguch switch (id) { 4128 1.1 yamaguch case IXL_AQ_CAP_RSS: 4129 1.1 yamaguch sc->sc_rss_table_size = number; 4130 1.1 yamaguch sc->sc_rss_table_entry_width = logical_id; 4131 1.1 yamaguch break; 4132 1.1 yamaguch case IXL_AQ_CAP_RXQ: 4133 1.1 yamaguch case IXL_AQ_CAP_TXQ: 4134 1.1 yamaguch sc->sc_nqueue_pairs_device = MIN(number, 4135 1.1 yamaguch sc->sc_nqueue_pairs_device); 4136 1.1 yamaguch break; 4137 1.1 yamaguch } 4138 1.1 yamaguch } 4139 1.1 yamaguch 4140 1.1 yamaguch static int 4141 1.1 yamaguch ixl_get_hw_capabilities(struct ixl_softc *sc) 4142 1.1 yamaguch { 4143 1.1 yamaguch struct ixl_dmamem idm; 4144 1.1 yamaguch struct ixl_aq_desc iaq; 4145 1.1 yamaguch struct ixl_aq_capability *caps; 4146 1.1 yamaguch size_t i, ncaps; 4147 1.1 yamaguch bus_size_t caps_size; 4148 1.1 yamaguch uint16_t status; 4149 1.1 yamaguch int rv; 4150 1.1 yamaguch 4151 1.1 yamaguch caps_size = sizeof(caps[0]) * 40; 4152 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4153 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_LIST_FUNC_CAP); 4154 1.1 yamaguch 4155 1.1 yamaguch do { 4156 1.1 yamaguch if (ixl_dmamem_alloc(sc, &idm, caps_size, 0) != 0) { 4157 1.1 yamaguch return -1; 4158 1.1 yamaguch } 4159 1.1 yamaguch 4160 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | 4161 1.1 yamaguch (caps_size > I40E_AQ_LARGE_BUF ? IXL_AQ_LB : 0)); 4162 1.1 yamaguch iaq.iaq_datalen = htole16(caps_size); 4163 1.1 yamaguch ixl_aq_dva(&iaq, IXL_DMA_DVA(&idm)); 4164 1.1 yamaguch 4165 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&idm), 0, 4166 1.1 yamaguch IXL_DMA_LEN(&idm), BUS_DMASYNC_PREREAD); 4167 1.1 yamaguch 4168 1.1 yamaguch rv = ixl_atq_poll(sc, &iaq, 250); 4169 1.1 yamaguch 4170 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&idm), 0, 4171 1.1 yamaguch IXL_DMA_LEN(&idm), BUS_DMASYNC_POSTREAD); 4172 1.1 yamaguch 4173 1.1 yamaguch if (rv != 0) { 4174 1.1 yamaguch aprint_error(", HW capabilities timeout\n"); 4175 1.1 yamaguch goto done; 4176 1.1 yamaguch } 4177 1.1 yamaguch 4178 1.1 yamaguch status = le16toh(iaq.iaq_retval); 4179 1.1 yamaguch 4180 1.1 yamaguch if (status == IXL_AQ_RC_ENOMEM) { 4181 1.1 yamaguch caps_size = le16toh(iaq.iaq_datalen); 4182 1.1 yamaguch ixl_dmamem_free(sc, &idm); 4183 1.1 yamaguch } 4184 1.1 yamaguch } while (status == IXL_AQ_RC_ENOMEM); 4185 1.1 yamaguch 4186 1.1 yamaguch if (status != IXL_AQ_RC_OK) { 4187 1.1 yamaguch aprint_error(", HW capabilities error\n"); 4188 1.1 yamaguch goto done; 4189 1.1 yamaguch } 4190 1.1 yamaguch 4191 1.1 yamaguch caps = IXL_DMA_KVA(&idm); 4192 1.1 yamaguch ncaps = le16toh(iaq.iaq_param[1]); 4193 1.1 yamaguch 4194 1.1 yamaguch for (i = 0; i < ncaps; i++) { 4195 1.1 yamaguch ixl_parse_hw_capability(sc, &caps[i]); 4196 1.1 yamaguch } 4197 1.1 yamaguch 4198 1.1 yamaguch done: 4199 1.1 yamaguch ixl_dmamem_free(sc, &idm); 4200 1.1 yamaguch return rv; 4201 1.1 yamaguch } 4202 1.1 yamaguch 4203 1.1 yamaguch static int 4204 1.1 yamaguch ixl_get_mac(struct ixl_softc *sc) 4205 1.1 yamaguch { 4206 1.1 yamaguch struct ixl_dmamem idm; 4207 1.1 yamaguch struct ixl_aq_desc iaq; 4208 1.1 yamaguch struct ixl_aq_mac_addresses *addrs; 4209 1.1 yamaguch int rv; 4210 1.1 yamaguch 4211 1.1 yamaguch if (ixl_dmamem_alloc(sc, &idm, sizeof(*addrs), 0) != 0) { 4212 1.1 yamaguch aprint_error(", unable to allocate mac addresses\n"); 4213 1.1 yamaguch return -1; 4214 1.1 yamaguch } 4215 1.1 yamaguch 4216 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4217 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF); 4218 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_MAC_ADDRESS_READ); 4219 1.1 yamaguch iaq.iaq_datalen = htole16(sizeof(*addrs)); 4220 1.1 yamaguch ixl_aq_dva(&iaq, IXL_DMA_DVA(&idm)); 4221 1.1 yamaguch 4222 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&idm), 0, IXL_DMA_LEN(&idm), 4223 1.1 yamaguch BUS_DMASYNC_PREREAD); 4224 1.1 yamaguch 4225 1.1 yamaguch rv = ixl_atq_poll(sc, &iaq, 250); 4226 1.1 yamaguch 4227 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&idm), 0, IXL_DMA_LEN(&idm), 4228 1.1 yamaguch BUS_DMASYNC_POSTREAD); 4229 1.1 yamaguch 4230 1.1 yamaguch if (rv != 0) { 4231 1.1 yamaguch aprint_error(", MAC ADDRESS READ timeout\n"); 4232 1.1 yamaguch rv = -1; 4233 1.1 yamaguch goto done; 4234 1.1 yamaguch } 4235 1.1 yamaguch if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK)) { 4236 1.1 yamaguch aprint_error(", MAC ADDRESS READ error\n"); 4237 1.1 yamaguch rv = -1; 4238 1.1 yamaguch goto done; 4239 1.1 yamaguch } 4240 1.1 yamaguch 4241 1.1 yamaguch addrs = IXL_DMA_KVA(&idm); 4242 1.1 yamaguch if (!ISSET(iaq.iaq_param[0], htole32(IXL_AQ_MAC_PORT_VALID))) { 4243 1.1 yamaguch printf(", port address is not valid\n"); 4244 1.1 yamaguch goto done; 4245 1.1 yamaguch } 4246 1.1 yamaguch 4247 1.1 yamaguch memcpy(sc->sc_enaddr, addrs->port, ETHER_ADDR_LEN); 4248 1.1 yamaguch rv = 0; 4249 1.1 yamaguch 4250 1.1 yamaguch done: 4251 1.1 yamaguch ixl_dmamem_free(sc, &idm); 4252 1.1 yamaguch return rv; 4253 1.1 yamaguch } 4254 1.1 yamaguch 4255 1.1 yamaguch static int 4256 1.1 yamaguch ixl_get_switch_config(struct ixl_softc *sc) 4257 1.1 yamaguch { 4258 1.1 yamaguch struct ixl_dmamem idm; 4259 1.1 yamaguch struct ixl_aq_desc iaq; 4260 1.1 yamaguch struct ixl_aq_switch_config *hdr; 4261 1.1 yamaguch struct ixl_aq_switch_config_element *elms, *elm; 4262 1.1 yamaguch unsigned int nelm, i; 4263 1.1 yamaguch int rv; 4264 1.1 yamaguch 4265 1.1 yamaguch if (ixl_dmamem_alloc(sc, &idm, IXL_AQ_BUFLEN, 0) != 0) { 4266 1.1 yamaguch aprint_error_dev(sc->sc_dev, 4267 1.1 yamaguch "unable to allocate switch config buffer\n"); 4268 1.1 yamaguch return -1; 4269 1.1 yamaguch } 4270 1.1 yamaguch 4271 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4272 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | 4273 1.1 yamaguch (IXL_AQ_BUFLEN > I40E_AQ_LARGE_BUF ? IXL_AQ_LB : 0)); 4274 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_SWITCH_GET_CONFIG); 4275 1.1 yamaguch iaq.iaq_datalen = htole16(IXL_AQ_BUFLEN); 4276 1.1 yamaguch ixl_aq_dva(&iaq, IXL_DMA_DVA(&idm)); 4277 1.1 yamaguch 4278 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&idm), 0, IXL_DMA_LEN(&idm), 4279 1.1 yamaguch BUS_DMASYNC_PREREAD); 4280 1.1 yamaguch 4281 1.1 yamaguch rv = ixl_atq_poll(sc, &iaq, 250); 4282 1.1 yamaguch 4283 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&idm), 0, IXL_DMA_LEN(&idm), 4284 1.1 yamaguch BUS_DMASYNC_POSTREAD); 4285 1.1 yamaguch 4286 1.1 yamaguch if (rv != 0) { 4287 1.1 yamaguch aprint_error_dev(sc->sc_dev, "GET SWITCH CONFIG timeout\n"); 4288 1.1 yamaguch rv = -1; 4289 1.1 yamaguch goto done; 4290 1.1 yamaguch } 4291 1.1 yamaguch if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK)) { 4292 1.1 yamaguch aprint_error_dev(sc->sc_dev, "GET SWITCH CONFIG error\n"); 4293 1.1 yamaguch rv = -1; 4294 1.1 yamaguch goto done; 4295 1.1 yamaguch } 4296 1.1 yamaguch 4297 1.1 yamaguch hdr = IXL_DMA_KVA(&idm); 4298 1.1 yamaguch elms = (struct ixl_aq_switch_config_element *)(hdr + 1); 4299 1.1 yamaguch 4300 1.1 yamaguch nelm = le16toh(hdr->num_reported); 4301 1.1 yamaguch if (nelm < 1) { 4302 1.1 yamaguch aprint_error_dev(sc->sc_dev, "no switch config available\n"); 4303 1.1 yamaguch rv = -1; 4304 1.1 yamaguch goto done; 4305 1.1 yamaguch } 4306 1.1 yamaguch 4307 1.1 yamaguch for (i = 0; i < nelm; i++) { 4308 1.1 yamaguch elm = &elms[i]; 4309 1.1 yamaguch 4310 1.1 yamaguch aprint_debug_dev(sc->sc_dev, 4311 1.1 yamaguch "type %x revision %u seid %04x\n", 4312 1.1 yamaguch elm->type, elm->revision, le16toh(elm->seid)); 4313 1.1 yamaguch aprint_debug_dev(sc->sc_dev, 4314 1.1 yamaguch "uplink %04x downlink %04x\n", 4315 1.1 yamaguch le16toh(elm->uplink_seid), 4316 1.1 yamaguch le16toh(elm->downlink_seid)); 4317 1.1 yamaguch aprint_debug_dev(sc->sc_dev, 4318 1.1 yamaguch "conntype %x scheduler %04x extra %04x\n", 4319 1.1 yamaguch elm->connection_type, 4320 1.1 yamaguch le16toh(elm->scheduler_id), 4321 1.1 yamaguch le16toh(elm->element_info)); 4322 1.1 yamaguch } 4323 1.1 yamaguch 4324 1.1 yamaguch elm = &elms[0]; 4325 1.1 yamaguch 4326 1.1 yamaguch sc->sc_uplink_seid = elm->uplink_seid; 4327 1.1 yamaguch sc->sc_downlink_seid = elm->downlink_seid; 4328 1.1 yamaguch sc->sc_seid = elm->seid; 4329 1.1 yamaguch 4330 1.1 yamaguch if ((sc->sc_uplink_seid == htole16(0)) != 4331 1.1 yamaguch (sc->sc_downlink_seid == htole16(0))) { 4332 1.1 yamaguch aprint_error_dev(sc->sc_dev, "SEIDs are misconfigured\n"); 4333 1.1 yamaguch rv = -1; 4334 1.1 yamaguch goto done; 4335 1.1 yamaguch } 4336 1.1 yamaguch 4337 1.1 yamaguch done: 4338 1.1 yamaguch ixl_dmamem_free(sc, &idm); 4339 1.1 yamaguch return rv; 4340 1.1 yamaguch } 4341 1.1 yamaguch 4342 1.1 yamaguch static int 4343 1.1 yamaguch ixl_phy_mask_ints(struct ixl_softc *sc) 4344 1.1 yamaguch { 4345 1.1 yamaguch struct ixl_aq_desc iaq; 4346 1.1 yamaguch 4347 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4348 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_PHY_SET_EVENT_MASK); 4349 1.1 yamaguch iaq.iaq_param[2] = htole32(IXL_AQ_PHY_EV_MASK & 4350 1.1 yamaguch ~(IXL_AQ_PHY_EV_LINK_UPDOWN | IXL_AQ_PHY_EV_MODULE_QUAL_FAIL | 4351 1.1 yamaguch IXL_AQ_PHY_EV_MEDIA_NA)); 4352 1.1 yamaguch 4353 1.1 yamaguch if (ixl_atq_poll(sc, &iaq, 250) != 0) { 4354 1.1 yamaguch aprint_error_dev(sc->sc_dev, "SET PHY EVENT MASK timeout\n"); 4355 1.1 yamaguch return -1; 4356 1.1 yamaguch } 4357 1.1 yamaguch if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK)) { 4358 1.1 yamaguch aprint_error_dev(sc->sc_dev, "SET PHY EVENT MASK error\n"); 4359 1.1 yamaguch return -1; 4360 1.1 yamaguch } 4361 1.1 yamaguch 4362 1.1 yamaguch return 0; 4363 1.1 yamaguch } 4364 1.1 yamaguch 4365 1.1 yamaguch static int 4366 1.72 yamaguch ixl_get_phy_abilities(struct ixl_softc *sc, struct ixl_dmamem *idm) 4367 1.1 yamaguch { 4368 1.1 yamaguch struct ixl_aq_desc iaq; 4369 1.1 yamaguch int rv; 4370 1.1 yamaguch 4371 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4372 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | 4373 1.1 yamaguch (IXL_DMA_LEN(idm) > I40E_AQ_LARGE_BUF ? IXL_AQ_LB : 0)); 4374 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_PHY_GET_ABILITIES); 4375 1.1 yamaguch iaq.iaq_datalen = htole16(IXL_DMA_LEN(idm)); 4376 1.1 yamaguch iaq.iaq_param[0] = htole32(IXL_AQ_PHY_REPORT_INIT); 4377 1.1 yamaguch ixl_aq_dva(&iaq, IXL_DMA_DVA(idm)); 4378 1.1 yamaguch 4379 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(idm), 0, IXL_DMA_LEN(idm), 4380 1.1 yamaguch BUS_DMASYNC_PREREAD); 4381 1.1 yamaguch 4382 1.1 yamaguch rv = ixl_atq_poll(sc, &iaq, 250); 4383 1.1 yamaguch 4384 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(idm), 0, IXL_DMA_LEN(idm), 4385 1.1 yamaguch BUS_DMASYNC_POSTREAD); 4386 1.1 yamaguch 4387 1.1 yamaguch if (rv != 0) 4388 1.1 yamaguch return -1; 4389 1.1 yamaguch 4390 1.1 yamaguch return le16toh(iaq.iaq_retval); 4391 1.1 yamaguch } 4392 1.1 yamaguch 4393 1.1 yamaguch static int 4394 1.31 yamaguch ixl_get_phy_info(struct ixl_softc *sc) 4395 1.1 yamaguch { 4396 1.1 yamaguch struct ixl_dmamem idm; 4397 1.1 yamaguch struct ixl_aq_phy_abilities *phy; 4398 1.1 yamaguch int rv; 4399 1.1 yamaguch 4400 1.1 yamaguch if (ixl_dmamem_alloc(sc, &idm, IXL_AQ_BUFLEN, 0) != 0) { 4401 1.1 yamaguch aprint_error_dev(sc->sc_dev, 4402 1.39 yamaguch "unable to allocate phy abilities buffer\n"); 4403 1.1 yamaguch return -1; 4404 1.1 yamaguch } 4405 1.1 yamaguch 4406 1.1 yamaguch rv = ixl_get_phy_abilities(sc, &idm); 4407 1.1 yamaguch switch (rv) { 4408 1.1 yamaguch case -1: 4409 1.1 yamaguch aprint_error_dev(sc->sc_dev, "GET PHY ABILITIES timeout\n"); 4410 1.1 yamaguch goto done; 4411 1.1 yamaguch case IXL_AQ_RC_OK: 4412 1.1 yamaguch break; 4413 1.1 yamaguch case IXL_AQ_RC_EIO: 4414 1.1 yamaguch aprint_error_dev(sc->sc_dev,"unable to query phy types\n"); 4415 1.30 yamaguch goto done; 4416 1.1 yamaguch default: 4417 1.1 yamaguch aprint_error_dev(sc->sc_dev, 4418 1.98 andvar "GET PHY ABILITIES error %u\n", rv); 4419 1.1 yamaguch goto done; 4420 1.1 yamaguch } 4421 1.1 yamaguch 4422 1.1 yamaguch phy = IXL_DMA_KVA(&idm); 4423 1.1 yamaguch 4424 1.31 yamaguch sc->sc_phy_types = le32toh(phy->phy_type); 4425 1.31 yamaguch sc->sc_phy_types |= (uint64_t)le32toh(phy->phy_type_ext) << 32; 4426 1.1 yamaguch 4427 1.31 yamaguch sc->sc_phy_abilities = phy->abilities; 4428 1.31 yamaguch sc->sc_phy_linkspeed = phy->link_speed; 4429 1.31 yamaguch sc->sc_phy_fec_cfg = phy->fec_cfg_curr_mod_ext_info & 4430 1.31 yamaguch (IXL_AQ_ENABLE_FEC_KR | IXL_AQ_ENABLE_FEC_RS | 4431 1.31 yamaguch IXL_AQ_REQUEST_FEC_KR | IXL_AQ_REQUEST_FEC_RS); 4432 1.31 yamaguch sc->sc_eee_cap = phy->eee_capability; 4433 1.31 yamaguch sc->sc_eeer_val = phy->eeer_val; 4434 1.31 yamaguch sc->sc_d3_lpan = phy->d3_lpan; 4435 1.1 yamaguch 4436 1.1 yamaguch rv = 0; 4437 1.1 yamaguch 4438 1.1 yamaguch done: 4439 1.1 yamaguch ixl_dmamem_free(sc, &idm); 4440 1.1 yamaguch return rv; 4441 1.1 yamaguch } 4442 1.1 yamaguch 4443 1.1 yamaguch static int 4444 1.31 yamaguch ixl_set_phy_config(struct ixl_softc *sc, 4445 1.31 yamaguch uint8_t link_speed, uint8_t abilities, bool polling) 4446 1.31 yamaguch { 4447 1.31 yamaguch struct ixl_aq_phy_param *param; 4448 1.31 yamaguch struct ixl_atq iatq; 4449 1.31 yamaguch struct ixl_aq_desc *iaq; 4450 1.31 yamaguch int error; 4451 1.31 yamaguch 4452 1.31 yamaguch memset(&iatq, 0, sizeof(iatq)); 4453 1.31 yamaguch 4454 1.31 yamaguch iaq = &iatq.iatq_desc; 4455 1.31 yamaguch iaq->iaq_opcode = htole16(IXL_AQ_OP_PHY_SET_CONFIG); 4456 1.31 yamaguch param = (struct ixl_aq_phy_param *)&iaq->iaq_param; 4457 1.31 yamaguch param->phy_types = htole32((uint32_t)sc->sc_phy_types); 4458 1.31 yamaguch param->phy_type_ext = (uint8_t)(sc->sc_phy_types >> 32); 4459 1.31 yamaguch param->link_speed = link_speed; 4460 1.31 yamaguch param->abilities = abilities | IXL_AQ_PHY_ABILITY_AUTO_LINK; 4461 1.31 yamaguch param->fec_cfg = sc->sc_phy_fec_cfg; 4462 1.31 yamaguch param->eee_capability = sc->sc_eee_cap; 4463 1.31 yamaguch param->eeer_val = sc->sc_eeer_val; 4464 1.31 yamaguch param->d3_lpan = sc->sc_d3_lpan; 4465 1.31 yamaguch 4466 1.31 yamaguch if (polling) 4467 1.31 yamaguch error = ixl_atq_poll(sc, iaq, 250); 4468 1.31 yamaguch else 4469 1.31 yamaguch error = ixl_atq_exec(sc, &iatq); 4470 1.31 yamaguch 4471 1.31 yamaguch if (error != 0) 4472 1.31 yamaguch return error; 4473 1.31 yamaguch 4474 1.31 yamaguch switch (le16toh(iaq->iaq_retval)) { 4475 1.31 yamaguch case IXL_AQ_RC_OK: 4476 1.31 yamaguch break; 4477 1.31 yamaguch case IXL_AQ_RC_EPERM: 4478 1.31 yamaguch return EPERM; 4479 1.31 yamaguch default: 4480 1.31 yamaguch return EIO; 4481 1.31 yamaguch } 4482 1.31 yamaguch 4483 1.31 yamaguch return 0; 4484 1.31 yamaguch } 4485 1.31 yamaguch 4486 1.31 yamaguch static int 4487 1.31 yamaguch ixl_set_phy_autoselect(struct ixl_softc *sc) 4488 1.31 yamaguch { 4489 1.31 yamaguch uint8_t link_speed, abilities; 4490 1.31 yamaguch 4491 1.31 yamaguch link_speed = sc->sc_phy_linkspeed; 4492 1.31 yamaguch abilities = IXL_PHY_ABILITY_LINKUP | IXL_PHY_ABILITY_AUTONEGO; 4493 1.31 yamaguch 4494 1.31 yamaguch return ixl_set_phy_config(sc, link_speed, abilities, true); 4495 1.31 yamaguch } 4496 1.31 yamaguch 4497 1.31 yamaguch static int 4498 1.37 yamaguch ixl_get_link_status_poll(struct ixl_softc *sc, int *l) 4499 1.1 yamaguch { 4500 1.1 yamaguch struct ixl_aq_desc iaq; 4501 1.1 yamaguch struct ixl_aq_link_param *param; 4502 1.1 yamaguch int link; 4503 1.1 yamaguch 4504 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4505 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_PHY_LINK_STATUS); 4506 1.1 yamaguch param = (struct ixl_aq_link_param *)iaq.iaq_param; 4507 1.1 yamaguch param->notify = IXL_AQ_LINK_NOTIFY; 4508 1.1 yamaguch 4509 1.1 yamaguch if (ixl_atq_poll(sc, &iaq, 250) != 0) { 4510 1.1 yamaguch return ETIMEDOUT; 4511 1.1 yamaguch } 4512 1.1 yamaguch if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK)) { 4513 1.1 yamaguch return EIO; 4514 1.1 yamaguch } 4515 1.1 yamaguch 4516 1.97 andvar /* It is unnecessary to hold lock */ 4517 1.62 yamaguch link = ixl_set_link_status_locked(sc, &iaq); 4518 1.37 yamaguch 4519 1.37 yamaguch if (l != NULL) 4520 1.37 yamaguch *l = link; 4521 1.1 yamaguch 4522 1.1 yamaguch return 0; 4523 1.1 yamaguch } 4524 1.1 yamaguch 4525 1.1 yamaguch static int 4526 1.1 yamaguch ixl_get_vsi(struct ixl_softc *sc) 4527 1.1 yamaguch { 4528 1.1 yamaguch struct ixl_dmamem *vsi = &sc->sc_scratch; 4529 1.1 yamaguch struct ixl_aq_desc iaq; 4530 1.1 yamaguch struct ixl_aq_vsi_param *param; 4531 1.1 yamaguch struct ixl_aq_vsi_reply *reply; 4532 1.18 yamaguch struct ixl_aq_vsi_data *data; 4533 1.1 yamaguch int rv; 4534 1.1 yamaguch 4535 1.1 yamaguch /* grumble, vsi info isn't "known" at compile time */ 4536 1.1 yamaguch 4537 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4538 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | 4539 1.1 yamaguch (IXL_DMA_LEN(vsi) > I40E_AQ_LARGE_BUF ? IXL_AQ_LB : 0)); 4540 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_GET_VSI_PARAMS); 4541 1.1 yamaguch iaq.iaq_datalen = htole16(IXL_DMA_LEN(vsi)); 4542 1.1 yamaguch ixl_aq_dva(&iaq, IXL_DMA_DVA(vsi)); 4543 1.1 yamaguch 4544 1.1 yamaguch param = (struct ixl_aq_vsi_param *)iaq.iaq_param; 4545 1.1 yamaguch param->uplink_seid = sc->sc_seid; 4546 1.1 yamaguch 4547 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(vsi), 0, IXL_DMA_LEN(vsi), 4548 1.1 yamaguch BUS_DMASYNC_PREREAD); 4549 1.1 yamaguch 4550 1.1 yamaguch rv = ixl_atq_poll(sc, &iaq, 250); 4551 1.1 yamaguch 4552 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(vsi), 0, IXL_DMA_LEN(vsi), 4553 1.1 yamaguch BUS_DMASYNC_POSTREAD); 4554 1.1 yamaguch 4555 1.1 yamaguch if (rv != 0) { 4556 1.11 yamaguch return ETIMEDOUT; 4557 1.1 yamaguch } 4558 1.1 yamaguch 4559 1.12 yamaguch switch (le16toh(iaq.iaq_retval)) { 4560 1.12 yamaguch case IXL_AQ_RC_OK: 4561 1.12 yamaguch break; 4562 1.12 yamaguch case IXL_AQ_RC_ENOENT: 4563 1.12 yamaguch return ENOENT; 4564 1.12 yamaguch case IXL_AQ_RC_EACCES: 4565 1.12 yamaguch return EACCES; 4566 1.12 yamaguch default: 4567 1.11 yamaguch return EIO; 4568 1.1 yamaguch } 4569 1.1 yamaguch 4570 1.1 yamaguch reply = (struct ixl_aq_vsi_reply *)iaq.iaq_param; 4571 1.41 yamaguch sc->sc_vsi_number = le16toh(reply->vsi_number); 4572 1.18 yamaguch data = IXL_DMA_KVA(vsi); 4573 1.18 yamaguch sc->sc_vsi_stat_counter_idx = le16toh(data->stat_counter_idx); 4574 1.1 yamaguch 4575 1.1 yamaguch return 0; 4576 1.1 yamaguch } 4577 1.1 yamaguch 4578 1.1 yamaguch static int 4579 1.1 yamaguch ixl_set_vsi(struct ixl_softc *sc) 4580 1.1 yamaguch { 4581 1.1 yamaguch struct ixl_dmamem *vsi = &sc->sc_scratch; 4582 1.1 yamaguch struct ixl_aq_desc iaq; 4583 1.1 yamaguch struct ixl_aq_vsi_param *param; 4584 1.1 yamaguch struct ixl_aq_vsi_data *data = IXL_DMA_KVA(vsi); 4585 1.1 yamaguch unsigned int qnum; 4586 1.11 yamaguch uint16_t val; 4587 1.1 yamaguch int rv; 4588 1.1 yamaguch 4589 1.1 yamaguch qnum = sc->sc_nqueue_pairs - 1; 4590 1.1 yamaguch 4591 1.1 yamaguch data->valid_sections = htole16(IXL_AQ_VSI_VALID_QUEUE_MAP | 4592 1.1 yamaguch IXL_AQ_VSI_VALID_VLAN); 4593 1.1 yamaguch 4594 1.1 yamaguch CLR(data->mapping_flags, htole16(IXL_AQ_VSI_QUE_MAP_MASK)); 4595 1.1 yamaguch SET(data->mapping_flags, htole16(IXL_AQ_VSI_QUE_MAP_CONTIG)); 4596 1.1 yamaguch data->queue_mapping[0] = htole16(0); 4597 1.1 yamaguch data->tc_mapping[0] = htole16((0 << IXL_AQ_VSI_TC_Q_OFFSET_SHIFT) | 4598 1.1 yamaguch (qnum << IXL_AQ_VSI_TC_Q_NUMBER_SHIFT)); 4599 1.1 yamaguch 4600 1.11 yamaguch val = le16toh(data->port_vlan_flags); 4601 1.11 yamaguch CLR(val, IXL_AQ_VSI_PVLAN_MODE_MASK | IXL_AQ_VSI_PVLAN_EMOD_MASK); 4602 1.11 yamaguch SET(val, IXL_AQ_VSI_PVLAN_MODE_ALL); 4603 1.11 yamaguch 4604 1.11 yamaguch if (ISSET(sc->sc_cur_ec_capenable, ETHERCAP_VLAN_HWTAGGING)) { 4605 1.11 yamaguch SET(val, IXL_AQ_VSI_PVLAN_EMOD_STR_BOTH); 4606 1.11 yamaguch } else { 4607 1.11 yamaguch SET(val, IXL_AQ_VSI_PVLAN_EMOD_NOTHING); 4608 1.11 yamaguch } 4609 1.11 yamaguch 4610 1.11 yamaguch data->port_vlan_flags = htole16(val); 4611 1.1 yamaguch 4612 1.1 yamaguch /* grumble, vsi info isn't "known" at compile time */ 4613 1.1 yamaguch 4614 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4615 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD | 4616 1.1 yamaguch (IXL_DMA_LEN(vsi) > I40E_AQ_LARGE_BUF ? IXL_AQ_LB : 0)); 4617 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_UPD_VSI_PARAMS); 4618 1.1 yamaguch iaq.iaq_datalen = htole16(IXL_DMA_LEN(vsi)); 4619 1.1 yamaguch ixl_aq_dva(&iaq, IXL_DMA_DVA(vsi)); 4620 1.1 yamaguch 4621 1.1 yamaguch param = (struct ixl_aq_vsi_param *)iaq.iaq_param; 4622 1.1 yamaguch param->uplink_seid = sc->sc_seid; 4623 1.1 yamaguch 4624 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(vsi), 0, IXL_DMA_LEN(vsi), 4625 1.1 yamaguch BUS_DMASYNC_PREWRITE); 4626 1.1 yamaguch 4627 1.1 yamaguch rv = ixl_atq_poll(sc, &iaq, 250); 4628 1.1 yamaguch 4629 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(vsi), 0, IXL_DMA_LEN(vsi), 4630 1.1 yamaguch BUS_DMASYNC_POSTWRITE); 4631 1.1 yamaguch 4632 1.1 yamaguch if (rv != 0) { 4633 1.11 yamaguch return ETIMEDOUT; 4634 1.1 yamaguch } 4635 1.1 yamaguch 4636 1.12 yamaguch switch (le16toh(iaq.iaq_retval)) { 4637 1.12 yamaguch case IXL_AQ_RC_OK: 4638 1.12 yamaguch break; 4639 1.12 yamaguch case IXL_AQ_RC_ENOENT: 4640 1.12 yamaguch return ENOENT; 4641 1.12 yamaguch case IXL_AQ_RC_EACCES: 4642 1.12 yamaguch return EACCES; 4643 1.12 yamaguch default: 4644 1.11 yamaguch return EIO; 4645 1.1 yamaguch } 4646 1.1 yamaguch 4647 1.1 yamaguch return 0; 4648 1.1 yamaguch } 4649 1.1 yamaguch 4650 1.1 yamaguch static void 4651 1.1 yamaguch ixl_set_filter_control(struct ixl_softc *sc) 4652 1.1 yamaguch { 4653 1.1 yamaguch uint32_t reg; 4654 1.1 yamaguch 4655 1.1 yamaguch reg = ixl_rd_rx_csr(sc, I40E_PFQF_CTL_0); 4656 1.1 yamaguch 4657 1.1 yamaguch CLR(reg, I40E_PFQF_CTL_0_HASHLUTSIZE_MASK); 4658 1.1 yamaguch SET(reg, I40E_HASH_LUT_SIZE_128 << I40E_PFQF_CTL_0_HASHLUTSIZE_SHIFT); 4659 1.1 yamaguch 4660 1.1 yamaguch SET(reg, I40E_PFQF_CTL_0_FD_ENA_MASK); 4661 1.1 yamaguch SET(reg, I40E_PFQF_CTL_0_ETYPE_ENA_MASK); 4662 1.1 yamaguch SET(reg, I40E_PFQF_CTL_0_MACVLAN_ENA_MASK); 4663 1.1 yamaguch 4664 1.1 yamaguch ixl_wr_rx_csr(sc, I40E_PFQF_CTL_0, reg); 4665 1.1 yamaguch } 4666 1.1 yamaguch 4667 1.1 yamaguch static inline void 4668 1.1 yamaguch ixl_get_default_rss_key(uint32_t *buf, size_t len) 4669 1.1 yamaguch { 4670 1.1 yamaguch size_t cplen; 4671 1.1 yamaguch uint8_t rss_seed[RSS_KEYSIZE]; 4672 1.1 yamaguch 4673 1.1 yamaguch rss_getkey(rss_seed); 4674 1.1 yamaguch memset(buf, 0, len); 4675 1.1 yamaguch 4676 1.1 yamaguch cplen = MIN(len, sizeof(rss_seed)); 4677 1.1 yamaguch memcpy(buf, rss_seed, cplen); 4678 1.1 yamaguch } 4679 1.1 yamaguch 4680 1.41 yamaguch static int 4681 1.41 yamaguch ixl_set_rss_key(struct ixl_softc *sc, uint8_t *key, size_t keylen) 4682 1.41 yamaguch { 4683 1.41 yamaguch struct ixl_dmamem *idm; 4684 1.41 yamaguch struct ixl_atq iatq; 4685 1.41 yamaguch struct ixl_aq_desc *iaq; 4686 1.41 yamaguch struct ixl_aq_rss_key_param *param; 4687 1.41 yamaguch struct ixl_aq_rss_key_data *data; 4688 1.41 yamaguch size_t len, datalen, stdlen, extlen; 4689 1.41 yamaguch uint16_t vsi_id; 4690 1.41 yamaguch int rv; 4691 1.41 yamaguch 4692 1.41 yamaguch memset(&iatq, 0, sizeof(iatq)); 4693 1.41 yamaguch iaq = &iatq.iatq_desc; 4694 1.41 yamaguch idm = &sc->sc_aqbuf; 4695 1.41 yamaguch 4696 1.41 yamaguch datalen = sizeof(*data); 4697 1.41 yamaguch 4698 1.41 yamaguch /*XXX The buf size has to be less than the size of the register */ 4699 1.41 yamaguch datalen = MIN(IXL_RSS_KEY_SIZE_REG * sizeof(uint32_t), datalen); 4700 1.41 yamaguch 4701 1.41 yamaguch iaq->iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD | 4702 1.41 yamaguch (datalen > I40E_AQ_LARGE_BUF ? IXL_AQ_LB : 0)); 4703 1.41 yamaguch iaq->iaq_opcode = htole16(IXL_AQ_OP_RSS_SET_KEY); 4704 1.41 yamaguch iaq->iaq_datalen = htole16(datalen); 4705 1.41 yamaguch 4706 1.41 yamaguch param = (struct ixl_aq_rss_key_param *)iaq->iaq_param; 4707 1.41 yamaguch vsi_id = (sc->sc_vsi_number << IXL_AQ_RSSKEY_VSI_ID_SHIFT) | 4708 1.41 yamaguch IXL_AQ_RSSKEY_VSI_VALID; 4709 1.41 yamaguch param->vsi_id = htole16(vsi_id); 4710 1.41 yamaguch 4711 1.41 yamaguch memset(IXL_DMA_KVA(idm), 0, IXL_DMA_LEN(idm)); 4712 1.41 yamaguch data = IXL_DMA_KVA(idm); 4713 1.41 yamaguch 4714 1.41 yamaguch len = MIN(keylen, datalen); 4715 1.41 yamaguch stdlen = MIN(sizeof(data->standard_rss_key), len); 4716 1.41 yamaguch memcpy(data->standard_rss_key, key, stdlen); 4717 1.41 yamaguch len = (len > stdlen) ? (len - stdlen) : 0; 4718 1.41 yamaguch 4719 1.41 yamaguch extlen = MIN(sizeof(data->extended_hash_key), len); 4720 1.41 yamaguch extlen = (stdlen < keylen) ? 0 : keylen - stdlen; 4721 1.41 yamaguch memcpy(data->extended_hash_key, key + stdlen, extlen); 4722 1.41 yamaguch 4723 1.41 yamaguch ixl_aq_dva(iaq, IXL_DMA_DVA(idm)); 4724 1.41 yamaguch 4725 1.41 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(idm), 0, 4726 1.41 yamaguch IXL_DMA_LEN(idm), BUS_DMASYNC_PREWRITE); 4727 1.41 yamaguch 4728 1.41 yamaguch rv = ixl_atq_exec(sc, &iatq); 4729 1.41 yamaguch 4730 1.41 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(idm), 0, 4731 1.41 yamaguch IXL_DMA_LEN(idm), BUS_DMASYNC_POSTWRITE); 4732 1.41 yamaguch 4733 1.41 yamaguch if (rv != 0) { 4734 1.41 yamaguch return ETIMEDOUT; 4735 1.41 yamaguch } 4736 1.41 yamaguch 4737 1.41 yamaguch if (iaq->iaq_retval != htole16(IXL_AQ_RC_OK)) { 4738 1.41 yamaguch return EIO; 4739 1.41 yamaguch } 4740 1.41 yamaguch 4741 1.41 yamaguch return 0; 4742 1.41 yamaguch } 4743 1.41 yamaguch 4744 1.41 yamaguch static int 4745 1.41 yamaguch ixl_set_rss_lut(struct ixl_softc *sc, uint8_t *lut, size_t lutlen) 4746 1.41 yamaguch { 4747 1.41 yamaguch struct ixl_dmamem *idm; 4748 1.41 yamaguch struct ixl_atq iatq; 4749 1.41 yamaguch struct ixl_aq_desc *iaq; 4750 1.41 yamaguch struct ixl_aq_rss_lut_param *param; 4751 1.41 yamaguch uint16_t vsi_id; 4752 1.41 yamaguch uint8_t *data; 4753 1.41 yamaguch size_t dmalen; 4754 1.41 yamaguch int rv; 4755 1.41 yamaguch 4756 1.41 yamaguch memset(&iatq, 0, sizeof(iatq)); 4757 1.41 yamaguch iaq = &iatq.iatq_desc; 4758 1.41 yamaguch idm = &sc->sc_aqbuf; 4759 1.41 yamaguch 4760 1.41 yamaguch dmalen = MIN(lutlen, IXL_DMA_LEN(idm)); 4761 1.41 yamaguch 4762 1.41 yamaguch iaq->iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD | 4763 1.41 yamaguch (dmalen > I40E_AQ_LARGE_BUF ? IXL_AQ_LB : 0)); 4764 1.41 yamaguch iaq->iaq_opcode = htole16(IXL_AQ_OP_RSS_SET_LUT); 4765 1.41 yamaguch iaq->iaq_datalen = htole16(dmalen); 4766 1.41 yamaguch 4767 1.41 yamaguch memset(IXL_DMA_KVA(idm), 0, IXL_DMA_LEN(idm)); 4768 1.41 yamaguch data = IXL_DMA_KVA(idm); 4769 1.41 yamaguch memcpy(data, lut, dmalen); 4770 1.41 yamaguch ixl_aq_dva(iaq, IXL_DMA_DVA(idm)); 4771 1.41 yamaguch 4772 1.41 yamaguch param = (struct ixl_aq_rss_lut_param *)iaq->iaq_param; 4773 1.41 yamaguch vsi_id = (sc->sc_vsi_number << IXL_AQ_RSSLUT_VSI_ID_SHIFT) | 4774 1.41 yamaguch IXL_AQ_RSSLUT_VSI_VALID; 4775 1.41 yamaguch param->vsi_id = htole16(vsi_id); 4776 1.41 yamaguch param->flags = htole16(IXL_AQ_RSSLUT_TABLE_TYPE_PF << 4777 1.41 yamaguch IXL_AQ_RSSLUT_TABLE_TYPE_SHIFT); 4778 1.41 yamaguch 4779 1.41 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(idm), 0, 4780 1.41 yamaguch IXL_DMA_LEN(idm), BUS_DMASYNC_PREWRITE); 4781 1.41 yamaguch 4782 1.41 yamaguch rv = ixl_atq_exec(sc, &iatq); 4783 1.41 yamaguch 4784 1.41 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(idm), 0, 4785 1.41 yamaguch IXL_DMA_LEN(idm), BUS_DMASYNC_POSTWRITE); 4786 1.41 yamaguch 4787 1.41 yamaguch if (rv != 0) { 4788 1.41 yamaguch return ETIMEDOUT; 4789 1.41 yamaguch } 4790 1.41 yamaguch 4791 1.41 yamaguch if (iaq->iaq_retval != htole16(IXL_AQ_RC_OK)) { 4792 1.41 yamaguch return EIO; 4793 1.41 yamaguch } 4794 1.41 yamaguch 4795 1.41 yamaguch return 0; 4796 1.41 yamaguch } 4797 1.41 yamaguch 4798 1.41 yamaguch static int 4799 1.41 yamaguch ixl_register_rss_key(struct ixl_softc *sc) 4800 1.1 yamaguch { 4801 1.1 yamaguch uint32_t rss_seed[IXL_RSS_KEY_SIZE_REG]; 4802 1.41 yamaguch int rv; 4803 1.1 yamaguch size_t i; 4804 1.1 yamaguch 4805 1.1 yamaguch ixl_get_default_rss_key(rss_seed, sizeof(rss_seed)); 4806 1.1 yamaguch 4807 1.72 yamaguch if (ISSET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_RSS)) { 4808 1.41 yamaguch rv = ixl_set_rss_key(sc, (uint8_t*)rss_seed, 4809 1.41 yamaguch sizeof(rss_seed)); 4810 1.41 yamaguch } else { 4811 1.41 yamaguch rv = 0; 4812 1.41 yamaguch for (i = 0; i < IXL_RSS_KEY_SIZE_REG; i++) { 4813 1.41 yamaguch ixl_wr_rx_csr(sc, I40E_PFQF_HKEY(i), rss_seed[i]); 4814 1.41 yamaguch } 4815 1.1 yamaguch } 4816 1.41 yamaguch 4817 1.41 yamaguch return rv; 4818 1.1 yamaguch } 4819 1.1 yamaguch 4820 1.1 yamaguch static void 4821 1.41 yamaguch ixl_register_rss_pctype(struct ixl_softc *sc) 4822 1.1 yamaguch { 4823 1.1 yamaguch uint64_t set_hena = 0; 4824 1.1 yamaguch uint32_t hena0, hena1; 4825 1.1 yamaguch 4826 1.56 yamaguch /* 4827 1.56 yamaguch * We use TCP/UDP with IPv4/IPv6 by default. 4828 1.56 yamaguch * Note: the device can not use just IP header in each 4829 1.56 yamaguch * TCP/UDP packets for the RSS hash calculation. 4830 1.56 yamaguch */ 4831 1.1 yamaguch if (sc->sc_mac_type == I40E_MAC_X722) 4832 1.1 yamaguch set_hena = IXL_RSS_HENA_DEFAULT_X722; 4833 1.1 yamaguch else 4834 1.1 yamaguch set_hena = IXL_RSS_HENA_DEFAULT_XL710; 4835 1.1 yamaguch 4836 1.1 yamaguch hena0 = ixl_rd_rx_csr(sc, I40E_PFQF_HENA(0)); 4837 1.1 yamaguch hena1 = ixl_rd_rx_csr(sc, I40E_PFQF_HENA(1)); 4838 1.1 yamaguch 4839 1.1 yamaguch SET(hena0, set_hena); 4840 1.1 yamaguch SET(hena1, set_hena >> 32); 4841 1.1 yamaguch 4842 1.1 yamaguch ixl_wr_rx_csr(sc, I40E_PFQF_HENA(0), hena0); 4843 1.1 yamaguch ixl_wr_rx_csr(sc, I40E_PFQF_HENA(1), hena1); 4844 1.1 yamaguch } 4845 1.1 yamaguch 4846 1.41 yamaguch static int 4847 1.41 yamaguch ixl_register_rss_hlut(struct ixl_softc *sc) 4848 1.1 yamaguch { 4849 1.1 yamaguch unsigned int qid; 4850 1.1 yamaguch uint8_t hlut_buf[512], lut_mask; 4851 1.1 yamaguch uint32_t *hluts; 4852 1.1 yamaguch size_t i, hluts_num; 4853 1.41 yamaguch int rv; 4854 1.1 yamaguch 4855 1.1 yamaguch lut_mask = (0x01 << sc->sc_rss_table_entry_width) - 1; 4856 1.1 yamaguch 4857 1.1 yamaguch for (i = 0; i < sc->sc_rss_table_size; i++) { 4858 1.1 yamaguch qid = i % sc->sc_nqueue_pairs; 4859 1.1 yamaguch hlut_buf[i] = qid & lut_mask; 4860 1.1 yamaguch } 4861 1.1 yamaguch 4862 1.41 yamaguch if (ISSET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_RSS)) { 4863 1.41 yamaguch rv = ixl_set_rss_lut(sc, hlut_buf, sizeof(hlut_buf)); 4864 1.41 yamaguch } else { 4865 1.41 yamaguch rv = 0; 4866 1.41 yamaguch hluts = (uint32_t *)hlut_buf; 4867 1.41 yamaguch hluts_num = sc->sc_rss_table_size >> 2; 4868 1.41 yamaguch for (i = 0; i < hluts_num; i++) { 4869 1.41 yamaguch ixl_wr(sc, I40E_PFQF_HLUT(i), hluts[i]); 4870 1.41 yamaguch } 4871 1.41 yamaguch ixl_flush(sc); 4872 1.1 yamaguch } 4873 1.41 yamaguch 4874 1.41 yamaguch return rv; 4875 1.1 yamaguch } 4876 1.1 yamaguch 4877 1.1 yamaguch static void 4878 1.1 yamaguch ixl_config_rss(struct ixl_softc *sc) 4879 1.1 yamaguch { 4880 1.1 yamaguch 4881 1.1 yamaguch KASSERT(mutex_owned(&sc->sc_cfg_lock)); 4882 1.1 yamaguch 4883 1.41 yamaguch ixl_register_rss_key(sc); 4884 1.41 yamaguch ixl_register_rss_pctype(sc); 4885 1.41 yamaguch ixl_register_rss_hlut(sc); 4886 1.1 yamaguch } 4887 1.1 yamaguch 4888 1.1 yamaguch static const struct ixl_phy_type * 4889 1.1 yamaguch ixl_search_phy_type(uint8_t phy_type) 4890 1.1 yamaguch { 4891 1.1 yamaguch const struct ixl_phy_type *itype; 4892 1.1 yamaguch uint64_t mask; 4893 1.1 yamaguch unsigned int i; 4894 1.1 yamaguch 4895 1.1 yamaguch if (phy_type >= 64) 4896 1.1 yamaguch return NULL; 4897 1.1 yamaguch 4898 1.1 yamaguch mask = 1ULL << phy_type; 4899 1.1 yamaguch 4900 1.1 yamaguch for (i = 0; i < __arraycount(ixl_phy_type_map); i++) { 4901 1.1 yamaguch itype = &ixl_phy_type_map[i]; 4902 1.1 yamaguch 4903 1.1 yamaguch if (ISSET(itype->phy_type, mask)) 4904 1.1 yamaguch return itype; 4905 1.1 yamaguch } 4906 1.1 yamaguch 4907 1.1 yamaguch return NULL; 4908 1.1 yamaguch } 4909 1.1 yamaguch 4910 1.1 yamaguch static uint64_t 4911 1.1 yamaguch ixl_search_link_speed(uint8_t link_speed) 4912 1.1 yamaguch { 4913 1.1 yamaguch const struct ixl_speed_type *type; 4914 1.1 yamaguch unsigned int i; 4915 1.1 yamaguch 4916 1.1 yamaguch for (i = 0; i < __arraycount(ixl_speed_type_map); i++) { 4917 1.1 yamaguch type = &ixl_speed_type_map[i]; 4918 1.1 yamaguch 4919 1.1 yamaguch if (ISSET(type->dev_speed, link_speed)) 4920 1.1 yamaguch return type->net_speed; 4921 1.1 yamaguch } 4922 1.1 yamaguch 4923 1.1 yamaguch return 0; 4924 1.1 yamaguch } 4925 1.1 yamaguch 4926 1.31 yamaguch static uint8_t 4927 1.31 yamaguch ixl_search_baudrate(uint64_t baudrate) 4928 1.31 yamaguch { 4929 1.31 yamaguch const struct ixl_speed_type *type; 4930 1.31 yamaguch unsigned int i; 4931 1.31 yamaguch 4932 1.31 yamaguch for (i = 0; i < __arraycount(ixl_speed_type_map); i++) { 4933 1.31 yamaguch type = &ixl_speed_type_map[i]; 4934 1.31 yamaguch 4935 1.31 yamaguch if (type->net_speed == baudrate) { 4936 1.31 yamaguch return type->dev_speed; 4937 1.31 yamaguch } 4938 1.31 yamaguch } 4939 1.31 yamaguch 4940 1.31 yamaguch return 0; 4941 1.31 yamaguch } 4942 1.31 yamaguch 4943 1.1 yamaguch static int 4944 1.1 yamaguch ixl_restart_an(struct ixl_softc *sc) 4945 1.1 yamaguch { 4946 1.1 yamaguch struct ixl_aq_desc iaq; 4947 1.1 yamaguch 4948 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4949 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_PHY_RESTART_AN); 4950 1.1 yamaguch iaq.iaq_param[0] = 4951 1.1 yamaguch htole32(IXL_AQ_PHY_RESTART_AN | IXL_AQ_PHY_LINK_ENABLE); 4952 1.1 yamaguch 4953 1.1 yamaguch if (ixl_atq_poll(sc, &iaq, 250) != 0) { 4954 1.1 yamaguch aprint_error_dev(sc->sc_dev, "RESTART AN timeout\n"); 4955 1.1 yamaguch return -1; 4956 1.1 yamaguch } 4957 1.1 yamaguch if (iaq.iaq_retval != htole16(IXL_AQ_RC_OK)) { 4958 1.1 yamaguch aprint_error_dev(sc->sc_dev, "RESTART AN error\n"); 4959 1.1 yamaguch return -1; 4960 1.1 yamaguch } 4961 1.1 yamaguch 4962 1.1 yamaguch return 0; 4963 1.1 yamaguch } 4964 1.1 yamaguch 4965 1.1 yamaguch static int 4966 1.1 yamaguch ixl_add_macvlan(struct ixl_softc *sc, const uint8_t *macaddr, 4967 1.1 yamaguch uint16_t vlan, uint16_t flags) 4968 1.1 yamaguch { 4969 1.1 yamaguch struct ixl_aq_desc iaq; 4970 1.1 yamaguch struct ixl_aq_add_macvlan *param; 4971 1.1 yamaguch struct ixl_aq_add_macvlan_elem *elem; 4972 1.1 yamaguch 4973 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 4974 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD); 4975 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_ADD_MACVLAN); 4976 1.1 yamaguch iaq.iaq_datalen = htole16(sizeof(*elem)); 4977 1.1 yamaguch ixl_aq_dva(&iaq, IXL_DMA_DVA(&sc->sc_scratch)); 4978 1.1 yamaguch 4979 1.1 yamaguch param = (struct ixl_aq_add_macvlan *)&iaq.iaq_param; 4980 1.1 yamaguch param->num_addrs = htole16(1); 4981 1.1 yamaguch param->seid0 = htole16(0x8000) | sc->sc_seid; 4982 1.1 yamaguch param->seid1 = 0; 4983 1.1 yamaguch param->seid2 = 0; 4984 1.1 yamaguch 4985 1.1 yamaguch elem = IXL_DMA_KVA(&sc->sc_scratch); 4986 1.1 yamaguch memset(elem, 0, sizeof(*elem)); 4987 1.1 yamaguch memcpy(elem->macaddr, macaddr, ETHER_ADDR_LEN); 4988 1.1 yamaguch elem->flags = htole16(IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH | flags); 4989 1.1 yamaguch elem->vlan = htole16(vlan); 4990 1.1 yamaguch 4991 1.1 yamaguch if (ixl_atq_poll(sc, &iaq, 250) != 0) { 4992 1.1 yamaguch return IXL_AQ_RC_EINVAL; 4993 1.1 yamaguch } 4994 1.1 yamaguch 4995 1.7 yamaguch switch (le16toh(iaq.iaq_retval)) { 4996 1.7 yamaguch case IXL_AQ_RC_OK: 4997 1.7 yamaguch break; 4998 1.7 yamaguch case IXL_AQ_RC_ENOSPC: 4999 1.7 yamaguch return ENOSPC; 5000 1.7 yamaguch case IXL_AQ_RC_ENOENT: 5001 1.7 yamaguch return ENOENT; 5002 1.7 yamaguch case IXL_AQ_RC_EACCES: 5003 1.7 yamaguch return EACCES; 5004 1.7 yamaguch case IXL_AQ_RC_EEXIST: 5005 1.7 yamaguch return EEXIST; 5006 1.7 yamaguch case IXL_AQ_RC_EINVAL: 5007 1.7 yamaguch return EINVAL; 5008 1.7 yamaguch default: 5009 1.7 yamaguch return EIO; 5010 1.7 yamaguch } 5011 1.7 yamaguch 5012 1.7 yamaguch return 0; 5013 1.1 yamaguch } 5014 1.1 yamaguch 5015 1.1 yamaguch static int 5016 1.12 yamaguch ixl_remove_macvlan(struct ixl_softc *sc, const uint8_t *macaddr, 5017 1.1 yamaguch uint16_t vlan, uint16_t flags) 5018 1.1 yamaguch { 5019 1.1 yamaguch struct ixl_aq_desc iaq; 5020 1.1 yamaguch struct ixl_aq_remove_macvlan *param; 5021 1.1 yamaguch struct ixl_aq_remove_macvlan_elem *elem; 5022 1.1 yamaguch 5023 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 5024 1.1 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | IXL_AQ_RD); 5025 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_REMOVE_MACVLAN); 5026 1.1 yamaguch iaq.iaq_datalen = htole16(sizeof(*elem)); 5027 1.1 yamaguch ixl_aq_dva(&iaq, IXL_DMA_DVA(&sc->sc_scratch)); 5028 1.1 yamaguch 5029 1.1 yamaguch param = (struct ixl_aq_remove_macvlan *)&iaq.iaq_param; 5030 1.1 yamaguch param->num_addrs = htole16(1); 5031 1.1 yamaguch param->seid0 = htole16(0x8000) | sc->sc_seid; 5032 1.1 yamaguch param->seid1 = 0; 5033 1.1 yamaguch param->seid2 = 0; 5034 1.1 yamaguch 5035 1.1 yamaguch elem = IXL_DMA_KVA(&sc->sc_scratch); 5036 1.1 yamaguch memset(elem, 0, sizeof(*elem)); 5037 1.1 yamaguch memcpy(elem->macaddr, macaddr, ETHER_ADDR_LEN); 5038 1.1 yamaguch elem->flags = htole16(IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH | flags); 5039 1.1 yamaguch elem->vlan = htole16(vlan); 5040 1.1 yamaguch 5041 1.1 yamaguch if (ixl_atq_poll(sc, &iaq, 250) != 0) { 5042 1.7 yamaguch return EINVAL; 5043 1.7 yamaguch } 5044 1.7 yamaguch 5045 1.7 yamaguch switch (le16toh(iaq.iaq_retval)) { 5046 1.7 yamaguch case IXL_AQ_RC_OK: 5047 1.7 yamaguch break; 5048 1.7 yamaguch case IXL_AQ_RC_ENOENT: 5049 1.7 yamaguch return ENOENT; 5050 1.7 yamaguch case IXL_AQ_RC_EACCES: 5051 1.7 yamaguch return EACCES; 5052 1.7 yamaguch case IXL_AQ_RC_EINVAL: 5053 1.7 yamaguch return EINVAL; 5054 1.7 yamaguch default: 5055 1.7 yamaguch return EIO; 5056 1.1 yamaguch } 5057 1.1 yamaguch 5058 1.7 yamaguch return 0; 5059 1.1 yamaguch } 5060 1.1 yamaguch 5061 1.1 yamaguch static int 5062 1.1 yamaguch ixl_hmc(struct ixl_softc *sc) 5063 1.1 yamaguch { 5064 1.1 yamaguch struct { 5065 1.1 yamaguch uint32_t count; 5066 1.1 yamaguch uint32_t minsize; 5067 1.1 yamaguch bus_size_t objsiz; 5068 1.1 yamaguch bus_size_t setoff; 5069 1.1 yamaguch bus_size_t setcnt; 5070 1.1 yamaguch } regs[] = { 5071 1.1 yamaguch { 5072 1.1 yamaguch 0, 5073 1.1 yamaguch IXL_HMC_TXQ_MINSIZE, 5074 1.1 yamaguch I40E_GLHMC_LANTXOBJSZ, 5075 1.1 yamaguch I40E_GLHMC_LANTXBASE(sc->sc_pf_id), 5076 1.1 yamaguch I40E_GLHMC_LANTXCNT(sc->sc_pf_id), 5077 1.1 yamaguch }, 5078 1.1 yamaguch { 5079 1.1 yamaguch 0, 5080 1.1 yamaguch IXL_HMC_RXQ_MINSIZE, 5081 1.1 yamaguch I40E_GLHMC_LANRXOBJSZ, 5082 1.1 yamaguch I40E_GLHMC_LANRXBASE(sc->sc_pf_id), 5083 1.1 yamaguch I40E_GLHMC_LANRXCNT(sc->sc_pf_id), 5084 1.1 yamaguch }, 5085 1.1 yamaguch { 5086 1.1 yamaguch 0, 5087 1.1 yamaguch 0, 5088 1.1 yamaguch I40E_GLHMC_FCOEDDPOBJSZ, 5089 1.1 yamaguch I40E_GLHMC_FCOEDDPBASE(sc->sc_pf_id), 5090 1.1 yamaguch I40E_GLHMC_FCOEDDPCNT(sc->sc_pf_id), 5091 1.1 yamaguch }, 5092 1.1 yamaguch { 5093 1.1 yamaguch 0, 5094 1.1 yamaguch 0, 5095 1.1 yamaguch I40E_GLHMC_FCOEFOBJSZ, 5096 1.1 yamaguch I40E_GLHMC_FCOEFBASE(sc->sc_pf_id), 5097 1.1 yamaguch I40E_GLHMC_FCOEFCNT(sc->sc_pf_id), 5098 1.1 yamaguch }, 5099 1.1 yamaguch }; 5100 1.1 yamaguch struct ixl_hmc_entry *e; 5101 1.1 yamaguch uint64_t size, dva; 5102 1.1 yamaguch uint8_t *kva; 5103 1.1 yamaguch uint64_t *sdpage; 5104 1.1 yamaguch unsigned int i; 5105 1.1 yamaguch int npages, tables; 5106 1.1 yamaguch uint32_t reg; 5107 1.1 yamaguch 5108 1.1 yamaguch CTASSERT(__arraycount(regs) <= __arraycount(sc->sc_hmc_entries)); 5109 1.1 yamaguch 5110 1.1 yamaguch regs[IXL_HMC_LAN_TX].count = regs[IXL_HMC_LAN_RX].count = 5111 1.1 yamaguch ixl_rd(sc, I40E_GLHMC_LANQMAX); 5112 1.1 yamaguch 5113 1.1 yamaguch size = 0; 5114 1.1 yamaguch for (i = 0; i < __arraycount(regs); i++) { 5115 1.1 yamaguch e = &sc->sc_hmc_entries[i]; 5116 1.1 yamaguch 5117 1.1 yamaguch e->hmc_count = regs[i].count; 5118 1.1 yamaguch reg = ixl_rd(sc, regs[i].objsiz); 5119 1.75 yamaguch e->hmc_size = IXL_BIT_ULL(0x3F & reg); 5120 1.1 yamaguch e->hmc_base = size; 5121 1.1 yamaguch 5122 1.1 yamaguch if ((e->hmc_size * 8) < regs[i].minsize) { 5123 1.1 yamaguch aprint_error_dev(sc->sc_dev, 5124 1.1 yamaguch "kernel hmc entry is too big\n"); 5125 1.1 yamaguch return -1; 5126 1.1 yamaguch } 5127 1.1 yamaguch 5128 1.1 yamaguch size += roundup(e->hmc_size * e->hmc_count, IXL_HMC_ROUNDUP); 5129 1.1 yamaguch } 5130 1.1 yamaguch size = roundup(size, IXL_HMC_PGSIZE); 5131 1.1 yamaguch npages = size / IXL_HMC_PGSIZE; 5132 1.1 yamaguch 5133 1.1 yamaguch tables = roundup(size, IXL_HMC_L2SZ) / IXL_HMC_L2SZ; 5134 1.1 yamaguch 5135 1.1 yamaguch if (ixl_dmamem_alloc(sc, &sc->sc_hmc_pd, size, IXL_HMC_PGSIZE) != 0) { 5136 1.1 yamaguch aprint_error_dev(sc->sc_dev, 5137 1.1 yamaguch "unable to allocate hmc pd memory\n"); 5138 1.1 yamaguch return -1; 5139 1.1 yamaguch } 5140 1.1 yamaguch 5141 1.1 yamaguch if (ixl_dmamem_alloc(sc, &sc->sc_hmc_sd, tables * IXL_HMC_PGSIZE, 5142 1.1 yamaguch IXL_HMC_PGSIZE) != 0) { 5143 1.1 yamaguch aprint_error_dev(sc->sc_dev, 5144 1.1 yamaguch "unable to allocate hmc sd memory\n"); 5145 1.1 yamaguch ixl_dmamem_free(sc, &sc->sc_hmc_pd); 5146 1.1 yamaguch return -1; 5147 1.1 yamaguch } 5148 1.1 yamaguch 5149 1.1 yamaguch kva = IXL_DMA_KVA(&sc->sc_hmc_pd); 5150 1.1 yamaguch memset(kva, 0, IXL_DMA_LEN(&sc->sc_hmc_pd)); 5151 1.1 yamaguch 5152 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_hmc_pd), 5153 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_hmc_pd), 5154 1.1 yamaguch BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 5155 1.1 yamaguch 5156 1.1 yamaguch dva = IXL_DMA_DVA(&sc->sc_hmc_pd); 5157 1.1 yamaguch sdpage = IXL_DMA_KVA(&sc->sc_hmc_sd); 5158 1.1 yamaguch memset(sdpage, 0, IXL_DMA_LEN(&sc->sc_hmc_sd)); 5159 1.1 yamaguch 5160 1.1 yamaguch for (i = 0; (int)i < npages; i++) { 5161 1.1 yamaguch *sdpage = htole64(dva | IXL_HMC_PDVALID); 5162 1.1 yamaguch sdpage++; 5163 1.1 yamaguch 5164 1.1 yamaguch dva += IXL_HMC_PGSIZE; 5165 1.1 yamaguch } 5166 1.1 yamaguch 5167 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_hmc_sd), 5168 1.1 yamaguch 0, IXL_DMA_LEN(&sc->sc_hmc_sd), 5169 1.1 yamaguch BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 5170 1.1 yamaguch 5171 1.1 yamaguch dva = IXL_DMA_DVA(&sc->sc_hmc_sd); 5172 1.1 yamaguch for (i = 0; (int)i < tables; i++) { 5173 1.1 yamaguch uint32_t count; 5174 1.1 yamaguch 5175 1.1 yamaguch KASSERT(npages >= 0); 5176 1.1 yamaguch 5177 1.1 yamaguch count = ((unsigned int)npages > IXL_HMC_PGS) ? 5178 1.1 yamaguch IXL_HMC_PGS : (unsigned int)npages; 5179 1.1 yamaguch 5180 1.1 yamaguch ixl_wr(sc, I40E_PFHMC_SDDATAHIGH, dva >> 32); 5181 1.1 yamaguch ixl_wr(sc, I40E_PFHMC_SDDATALOW, dva | 5182 1.1 yamaguch (count << I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT) | 5183 1.1 yamaguch (1U << I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT)); 5184 1.1 yamaguch ixl_barrier(sc, 0, sc->sc_mems, BUS_SPACE_BARRIER_WRITE); 5185 1.1 yamaguch ixl_wr(sc, I40E_PFHMC_SDCMD, 5186 1.1 yamaguch (1U << I40E_PFHMC_SDCMD_PMSDWR_SHIFT) | i); 5187 1.1 yamaguch 5188 1.1 yamaguch npages -= IXL_HMC_PGS; 5189 1.1 yamaguch dva += IXL_HMC_PGSIZE; 5190 1.1 yamaguch } 5191 1.1 yamaguch 5192 1.1 yamaguch for (i = 0; i < __arraycount(regs); i++) { 5193 1.1 yamaguch e = &sc->sc_hmc_entries[i]; 5194 1.1 yamaguch 5195 1.1 yamaguch ixl_wr(sc, regs[i].setoff, e->hmc_base / IXL_HMC_ROUNDUP); 5196 1.1 yamaguch ixl_wr(sc, regs[i].setcnt, e->hmc_count); 5197 1.1 yamaguch } 5198 1.1 yamaguch 5199 1.1 yamaguch return 0; 5200 1.1 yamaguch } 5201 1.1 yamaguch 5202 1.1 yamaguch static void 5203 1.1 yamaguch ixl_hmc_free(struct ixl_softc *sc) 5204 1.1 yamaguch { 5205 1.1 yamaguch ixl_dmamem_free(sc, &sc->sc_hmc_sd); 5206 1.1 yamaguch ixl_dmamem_free(sc, &sc->sc_hmc_pd); 5207 1.1 yamaguch } 5208 1.1 yamaguch 5209 1.1 yamaguch static void 5210 1.1 yamaguch ixl_hmc_pack(void *d, const void *s, const struct ixl_hmc_pack *packing, 5211 1.1 yamaguch unsigned int npacking) 5212 1.1 yamaguch { 5213 1.1 yamaguch uint8_t *dst = d; 5214 1.1 yamaguch const uint8_t *src = s; 5215 1.1 yamaguch unsigned int i; 5216 1.1 yamaguch 5217 1.1 yamaguch for (i = 0; i < npacking; i++) { 5218 1.1 yamaguch const struct ixl_hmc_pack *pack = &packing[i]; 5219 1.1 yamaguch unsigned int offset = pack->lsb / 8; 5220 1.1 yamaguch unsigned int align = pack->lsb % 8; 5221 1.1 yamaguch const uint8_t *in = src + pack->offset; 5222 1.1 yamaguch uint8_t *out = dst + offset; 5223 1.1 yamaguch int width = pack->width; 5224 1.1 yamaguch unsigned int inbits = 0; 5225 1.1 yamaguch 5226 1.1 yamaguch if (align) { 5227 1.1 yamaguch inbits = (*in++) << align; 5228 1.1 yamaguch *out++ |= (inbits & 0xff); 5229 1.1 yamaguch inbits >>= 8; 5230 1.1 yamaguch 5231 1.1 yamaguch width -= 8 - align; 5232 1.1 yamaguch } 5233 1.1 yamaguch 5234 1.1 yamaguch while (width >= 8) { 5235 1.1 yamaguch inbits |= (*in++) << align; 5236 1.1 yamaguch *out++ = (inbits & 0xff); 5237 1.1 yamaguch inbits >>= 8; 5238 1.1 yamaguch 5239 1.1 yamaguch width -= 8; 5240 1.1 yamaguch } 5241 1.1 yamaguch 5242 1.1 yamaguch if (width > 0) { 5243 1.1 yamaguch inbits |= (*in) << align; 5244 1.1 yamaguch *out |= (inbits & ((1 << width) - 1)); 5245 1.1 yamaguch } 5246 1.1 yamaguch } 5247 1.1 yamaguch } 5248 1.1 yamaguch 5249 1.1 yamaguch static struct ixl_aq_buf * 5250 1.1 yamaguch ixl_aqb_alloc(struct ixl_softc *sc) 5251 1.1 yamaguch { 5252 1.1 yamaguch struct ixl_aq_buf *aqb; 5253 1.1 yamaguch 5254 1.54 yamaguch aqb = kmem_alloc(sizeof(*aqb), KM_SLEEP); 5255 1.1 yamaguch 5256 1.1 yamaguch aqb->aqb_size = IXL_AQ_BUFLEN; 5257 1.1 yamaguch 5258 1.1 yamaguch if (bus_dmamap_create(sc->sc_dmat, aqb->aqb_size, 1, 5259 1.1 yamaguch aqb->aqb_size, 0, 5260 1.1 yamaguch BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &aqb->aqb_map) != 0) 5261 1.1 yamaguch goto free; 5262 1.1 yamaguch if (bus_dmamem_alloc(sc->sc_dmat, aqb->aqb_size, 5263 1.1 yamaguch IXL_AQ_ALIGN, 0, &aqb->aqb_seg, 1, &aqb->aqb_nsegs, 5264 1.1 yamaguch BUS_DMA_WAITOK) != 0) 5265 1.1 yamaguch goto destroy; 5266 1.1 yamaguch if (bus_dmamem_map(sc->sc_dmat, &aqb->aqb_seg, aqb->aqb_nsegs, 5267 1.1 yamaguch aqb->aqb_size, &aqb->aqb_data, BUS_DMA_WAITOK) != 0) 5268 1.1 yamaguch goto dma_free; 5269 1.1 yamaguch if (bus_dmamap_load(sc->sc_dmat, aqb->aqb_map, aqb->aqb_data, 5270 1.1 yamaguch aqb->aqb_size, NULL, BUS_DMA_WAITOK) != 0) 5271 1.1 yamaguch goto unmap; 5272 1.1 yamaguch 5273 1.1 yamaguch return aqb; 5274 1.1 yamaguch unmap: 5275 1.1 yamaguch bus_dmamem_unmap(sc->sc_dmat, aqb->aqb_data, aqb->aqb_size); 5276 1.1 yamaguch dma_free: 5277 1.1 yamaguch bus_dmamem_free(sc->sc_dmat, &aqb->aqb_seg, 1); 5278 1.1 yamaguch destroy: 5279 1.1 yamaguch bus_dmamap_destroy(sc->sc_dmat, aqb->aqb_map); 5280 1.1 yamaguch free: 5281 1.54 yamaguch kmem_free(aqb, sizeof(*aqb)); 5282 1.1 yamaguch 5283 1.1 yamaguch return NULL; 5284 1.1 yamaguch } 5285 1.1 yamaguch 5286 1.1 yamaguch static void 5287 1.1 yamaguch ixl_aqb_free(struct ixl_softc *sc, struct ixl_aq_buf *aqb) 5288 1.1 yamaguch { 5289 1.54 yamaguch 5290 1.1 yamaguch bus_dmamap_unload(sc->sc_dmat, aqb->aqb_map); 5291 1.1 yamaguch bus_dmamem_unmap(sc->sc_dmat, aqb->aqb_data, aqb->aqb_size); 5292 1.1 yamaguch bus_dmamem_free(sc->sc_dmat, &aqb->aqb_seg, 1); 5293 1.1 yamaguch bus_dmamap_destroy(sc->sc_dmat, aqb->aqb_map); 5294 1.54 yamaguch kmem_free(aqb, sizeof(*aqb)); 5295 1.1 yamaguch } 5296 1.1 yamaguch 5297 1.1 yamaguch static int 5298 1.1 yamaguch ixl_arq_fill(struct ixl_softc *sc) 5299 1.1 yamaguch { 5300 1.1 yamaguch struct ixl_aq_buf *aqb; 5301 1.1 yamaguch struct ixl_aq_desc *arq, *iaq; 5302 1.1 yamaguch unsigned int prod = sc->sc_arq_prod; 5303 1.1 yamaguch unsigned int n; 5304 1.1 yamaguch int post = 0; 5305 1.1 yamaguch 5306 1.1 yamaguch n = ixl_rxr_unrefreshed(sc->sc_arq_prod, sc->sc_arq_cons, 5307 1.1 yamaguch IXL_AQ_NUM); 5308 1.1 yamaguch arq = IXL_DMA_KVA(&sc->sc_arq); 5309 1.1 yamaguch 5310 1.1 yamaguch if (__predict_false(n <= 0)) 5311 1.1 yamaguch return 0; 5312 1.1 yamaguch 5313 1.1 yamaguch do { 5314 1.1 yamaguch aqb = sc->sc_arq_live[prod]; 5315 1.1 yamaguch iaq = &arq[prod]; 5316 1.1 yamaguch 5317 1.1 yamaguch if (aqb == NULL) { 5318 1.1 yamaguch aqb = SIMPLEQ_FIRST(&sc->sc_arq_idle); 5319 1.1 yamaguch if (aqb != NULL) { 5320 1.1 yamaguch SIMPLEQ_REMOVE(&sc->sc_arq_idle, aqb, 5321 1.1 yamaguch ixl_aq_buf, aqb_entry); 5322 1.1 yamaguch } else if ((aqb = ixl_aqb_alloc(sc)) == NULL) { 5323 1.1 yamaguch break; 5324 1.1 yamaguch } 5325 1.1 yamaguch 5326 1.1 yamaguch sc->sc_arq_live[prod] = aqb; 5327 1.1 yamaguch memset(aqb->aqb_data, 0, aqb->aqb_size); 5328 1.1 yamaguch 5329 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0, 5330 1.1 yamaguch aqb->aqb_size, BUS_DMASYNC_PREREAD); 5331 1.1 yamaguch 5332 1.1 yamaguch iaq->iaq_flags = htole16(IXL_AQ_BUF | 5333 1.1 yamaguch (IXL_AQ_BUFLEN > I40E_AQ_LARGE_BUF ? 5334 1.1 yamaguch IXL_AQ_LB : 0)); 5335 1.1 yamaguch iaq->iaq_opcode = 0; 5336 1.1 yamaguch iaq->iaq_datalen = htole16(aqb->aqb_size); 5337 1.1 yamaguch iaq->iaq_retval = 0; 5338 1.1 yamaguch iaq->iaq_cookie = 0; 5339 1.1 yamaguch iaq->iaq_param[0] = 0; 5340 1.1 yamaguch iaq->iaq_param[1] = 0; 5341 1.1 yamaguch ixl_aq_dva(iaq, aqb->aqb_map->dm_segs[0].ds_addr); 5342 1.1 yamaguch } 5343 1.1 yamaguch 5344 1.1 yamaguch prod++; 5345 1.1 yamaguch prod &= IXL_AQ_MASK; 5346 1.1 yamaguch 5347 1.1 yamaguch post = 1; 5348 1.1 yamaguch 5349 1.1 yamaguch } while (--n); 5350 1.1 yamaguch 5351 1.1 yamaguch if (post) { 5352 1.1 yamaguch sc->sc_arq_prod = prod; 5353 1.1 yamaguch ixl_wr(sc, sc->sc_aq_regs->arq_tail, sc->sc_arq_prod); 5354 1.1 yamaguch } 5355 1.1 yamaguch 5356 1.1 yamaguch return post; 5357 1.1 yamaguch } 5358 1.1 yamaguch 5359 1.1 yamaguch static void 5360 1.1 yamaguch ixl_arq_unfill(struct ixl_softc *sc) 5361 1.1 yamaguch { 5362 1.1 yamaguch struct ixl_aq_buf *aqb; 5363 1.1 yamaguch unsigned int i; 5364 1.1 yamaguch 5365 1.1 yamaguch for (i = 0; i < __arraycount(sc->sc_arq_live); i++) { 5366 1.1 yamaguch aqb = sc->sc_arq_live[i]; 5367 1.1 yamaguch if (aqb == NULL) 5368 1.1 yamaguch continue; 5369 1.1 yamaguch 5370 1.1 yamaguch sc->sc_arq_live[i] = NULL; 5371 1.1 yamaguch bus_dmamap_sync(sc->sc_dmat, aqb->aqb_map, 0, aqb->aqb_size, 5372 1.1 yamaguch BUS_DMASYNC_POSTREAD); 5373 1.1 yamaguch ixl_aqb_free(sc, aqb); 5374 1.1 yamaguch } 5375 1.1 yamaguch 5376 1.1 yamaguch while ((aqb = SIMPLEQ_FIRST(&sc->sc_arq_idle)) != NULL) { 5377 1.1 yamaguch SIMPLEQ_REMOVE(&sc->sc_arq_idle, aqb, 5378 1.1 yamaguch ixl_aq_buf, aqb_entry); 5379 1.1 yamaguch ixl_aqb_free(sc, aqb); 5380 1.1 yamaguch } 5381 1.1 yamaguch } 5382 1.1 yamaguch 5383 1.1 yamaguch static void 5384 1.1 yamaguch ixl_clear_hw(struct ixl_softc *sc) 5385 1.1 yamaguch { 5386 1.1 yamaguch uint32_t num_queues, base_queue; 5387 1.1 yamaguch uint32_t num_pf_int; 5388 1.1 yamaguch uint32_t num_vf_int; 5389 1.1 yamaguch uint32_t num_vfs; 5390 1.1 yamaguch uint32_t i, j; 5391 1.1 yamaguch uint32_t val; 5392 1.1 yamaguch uint32_t eol = 0x7ff; 5393 1.1 yamaguch 5394 1.1 yamaguch /* get number of interrupts, queues, and vfs */ 5395 1.1 yamaguch val = ixl_rd(sc, I40E_GLPCI_CNF2); 5396 1.1 yamaguch num_pf_int = (val & I40E_GLPCI_CNF2_MSI_X_PF_N_MASK) >> 5397 1.1 yamaguch I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT; 5398 1.1 yamaguch num_vf_int = (val & I40E_GLPCI_CNF2_MSI_X_VF_N_MASK) >> 5399 1.1 yamaguch I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT; 5400 1.1 yamaguch 5401 1.1 yamaguch val = ixl_rd(sc, I40E_PFLAN_QALLOC); 5402 1.1 yamaguch base_queue = (val & I40E_PFLAN_QALLOC_FIRSTQ_MASK) >> 5403 1.1 yamaguch I40E_PFLAN_QALLOC_FIRSTQ_SHIFT; 5404 1.1 yamaguch j = (val & I40E_PFLAN_QALLOC_LASTQ_MASK) >> 5405 1.1 yamaguch I40E_PFLAN_QALLOC_LASTQ_SHIFT; 5406 1.1 yamaguch if (val & I40E_PFLAN_QALLOC_VALID_MASK) 5407 1.1 yamaguch num_queues = (j - base_queue) + 1; 5408 1.1 yamaguch else 5409 1.1 yamaguch num_queues = 0; 5410 1.1 yamaguch 5411 1.1 yamaguch val = ixl_rd(sc, I40E_PF_VT_PFALLOC); 5412 1.1 yamaguch i = (val & I40E_PF_VT_PFALLOC_FIRSTVF_MASK) >> 5413 1.1 yamaguch I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT; 5414 1.1 yamaguch j = (val & I40E_PF_VT_PFALLOC_LASTVF_MASK) >> 5415 1.1 yamaguch I40E_PF_VT_PFALLOC_LASTVF_SHIFT; 5416 1.1 yamaguch if (val & I40E_PF_VT_PFALLOC_VALID_MASK) 5417 1.1 yamaguch num_vfs = (j - i) + 1; 5418 1.1 yamaguch else 5419 1.1 yamaguch num_vfs = 0; 5420 1.1 yamaguch 5421 1.1 yamaguch /* stop all the interrupts */ 5422 1.1 yamaguch ixl_wr(sc, I40E_PFINT_ICR0_ENA, 0); 5423 1.1 yamaguch ixl_flush(sc); 5424 1.1 yamaguch val = 0x3 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT; 5425 1.1 yamaguch for (i = 0; i < num_pf_int - 2; i++) 5426 1.1 yamaguch ixl_wr(sc, I40E_PFINT_DYN_CTLN(i), val); 5427 1.1 yamaguch ixl_flush(sc); 5428 1.1 yamaguch 5429 1.1 yamaguch /* Set the FIRSTQ_INDX field to 0x7FF in PFINT_LNKLSTx */ 5430 1.1 yamaguch val = eol << I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT; 5431 1.1 yamaguch ixl_wr(sc, I40E_PFINT_LNKLST0, val); 5432 1.1 yamaguch for (i = 0; i < num_pf_int - 2; i++) 5433 1.1 yamaguch ixl_wr(sc, I40E_PFINT_LNKLSTN(i), val); 5434 1.1 yamaguch val = eol << I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT; 5435 1.1 yamaguch for (i = 0; i < num_vfs; i++) 5436 1.1 yamaguch ixl_wr(sc, I40E_VPINT_LNKLST0(i), val); 5437 1.1 yamaguch for (i = 0; i < num_vf_int - 2; i++) 5438 1.1 yamaguch ixl_wr(sc, I40E_VPINT_LNKLSTN(i), val); 5439 1.1 yamaguch 5440 1.1 yamaguch /* warn the HW of the coming Tx disables */ 5441 1.1 yamaguch for (i = 0; i < num_queues; i++) { 5442 1.1 yamaguch uint32_t abs_queue_idx = base_queue + i; 5443 1.1 yamaguch uint32_t reg_block = 0; 5444 1.1 yamaguch 5445 1.1 yamaguch if (abs_queue_idx >= 128) { 5446 1.1 yamaguch reg_block = abs_queue_idx / 128; 5447 1.1 yamaguch abs_queue_idx %= 128; 5448 1.1 yamaguch } 5449 1.1 yamaguch 5450 1.1 yamaguch val = ixl_rd(sc, I40E_GLLAN_TXPRE_QDIS(reg_block)); 5451 1.1 yamaguch val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK; 5452 1.1 yamaguch val |= (abs_queue_idx << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT); 5453 1.1 yamaguch val |= I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK; 5454 1.1 yamaguch 5455 1.1 yamaguch ixl_wr(sc, I40E_GLLAN_TXPRE_QDIS(reg_block), val); 5456 1.1 yamaguch } 5457 1.1 yamaguch delaymsec(400); 5458 1.1 yamaguch 5459 1.1 yamaguch /* stop all the queues */ 5460 1.1 yamaguch for (i = 0; i < num_queues; i++) { 5461 1.1 yamaguch ixl_wr(sc, I40E_QINT_TQCTL(i), 0); 5462 1.1 yamaguch ixl_wr(sc, I40E_QTX_ENA(i), 0); 5463 1.1 yamaguch ixl_wr(sc, I40E_QINT_RQCTL(i), 0); 5464 1.1 yamaguch ixl_wr(sc, I40E_QRX_ENA(i), 0); 5465 1.1 yamaguch } 5466 1.1 yamaguch 5467 1.1 yamaguch /* short wait for all queue disables to settle */ 5468 1.1 yamaguch delaymsec(50); 5469 1.1 yamaguch } 5470 1.1 yamaguch 5471 1.1 yamaguch static int 5472 1.1 yamaguch ixl_pf_reset(struct ixl_softc *sc) 5473 1.1 yamaguch { 5474 1.1 yamaguch uint32_t cnt = 0; 5475 1.1 yamaguch uint32_t cnt1 = 0; 5476 1.1 yamaguch uint32_t reg = 0, reg0 = 0; 5477 1.1 yamaguch uint32_t grst_del; 5478 1.1 yamaguch 5479 1.1 yamaguch /* 5480 1.1 yamaguch * Poll for Global Reset steady state in case of recent GRST. 5481 1.1 yamaguch * The grst delay value is in 100ms units, and we'll wait a 5482 1.1 yamaguch * couple counts longer to be sure we don't just miss the end. 5483 1.1 yamaguch */ 5484 1.1 yamaguch grst_del = ixl_rd(sc, I40E_GLGEN_RSTCTL); 5485 1.1 yamaguch grst_del &= I40E_GLGEN_RSTCTL_GRSTDEL_MASK; 5486 1.1 yamaguch grst_del >>= I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT; 5487 1.1 yamaguch 5488 1.1 yamaguch grst_del = grst_del * 20; 5489 1.1 yamaguch 5490 1.1 yamaguch for (cnt = 0; cnt < grst_del; cnt++) { 5491 1.1 yamaguch reg = ixl_rd(sc, I40E_GLGEN_RSTAT); 5492 1.1 yamaguch if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK)) 5493 1.1 yamaguch break; 5494 1.1 yamaguch delaymsec(100); 5495 1.1 yamaguch } 5496 1.1 yamaguch if (reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK) { 5497 1.1 yamaguch aprint_error(", Global reset polling failed to complete\n"); 5498 1.1 yamaguch return -1; 5499 1.1 yamaguch } 5500 1.1 yamaguch 5501 1.1 yamaguch /* Now Wait for the FW to be ready */ 5502 1.1 yamaguch for (cnt1 = 0; cnt1 < I40E_PF_RESET_WAIT_COUNT; cnt1++) { 5503 1.1 yamaguch reg = ixl_rd(sc, I40E_GLNVM_ULD); 5504 1.1 yamaguch reg &= (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK | 5505 1.1 yamaguch I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK); 5506 1.1 yamaguch if (reg == (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK | 5507 1.1 yamaguch I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK)) 5508 1.1 yamaguch break; 5509 1.1 yamaguch 5510 1.1 yamaguch delaymsec(10); 5511 1.1 yamaguch } 5512 1.1 yamaguch if (!(reg & (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK | 5513 1.1 yamaguch I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK))) { 5514 1.1 yamaguch aprint_error(", wait for FW Reset complete timed out " 5515 1.1 yamaguch "(I40E_GLNVM_ULD = 0x%x)\n", reg); 5516 1.1 yamaguch return -1; 5517 1.1 yamaguch } 5518 1.1 yamaguch 5519 1.1 yamaguch /* 5520 1.1 yamaguch * If there was a Global Reset in progress when we got here, 5521 1.1 yamaguch * we don't need to do the PF Reset 5522 1.1 yamaguch */ 5523 1.1 yamaguch if (cnt == 0) { 5524 1.1 yamaguch reg = ixl_rd(sc, I40E_PFGEN_CTRL); 5525 1.1 yamaguch ixl_wr(sc, I40E_PFGEN_CTRL, reg | I40E_PFGEN_CTRL_PFSWR_MASK); 5526 1.1 yamaguch for (cnt = 0; cnt < I40E_PF_RESET_WAIT_COUNT; cnt++) { 5527 1.1 yamaguch reg = ixl_rd(sc, I40E_PFGEN_CTRL); 5528 1.1 yamaguch if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK)) 5529 1.1 yamaguch break; 5530 1.1 yamaguch delaymsec(1); 5531 1.1 yamaguch 5532 1.1 yamaguch reg0 = ixl_rd(sc, I40E_GLGEN_RSTAT); 5533 1.1 yamaguch if (reg0 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) { 5534 1.1 yamaguch aprint_error(", Core reset upcoming." 5535 1.1 yamaguch " Skipping PF reset reset request\n"); 5536 1.1 yamaguch return -1; 5537 1.1 yamaguch } 5538 1.1 yamaguch } 5539 1.1 yamaguch if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) { 5540 1.1 yamaguch aprint_error(", PF reset polling failed to complete" 5541 1.1 yamaguch "(I40E_PFGEN_CTRL= 0x%x)\n", reg); 5542 1.1 yamaguch return -1; 5543 1.1 yamaguch } 5544 1.1 yamaguch } 5545 1.1 yamaguch 5546 1.1 yamaguch return 0; 5547 1.1 yamaguch } 5548 1.1 yamaguch 5549 1.1 yamaguch static int 5550 1.1 yamaguch ixl_dmamem_alloc(struct ixl_softc *sc, struct ixl_dmamem *ixm, 5551 1.1 yamaguch bus_size_t size, bus_size_t align) 5552 1.1 yamaguch { 5553 1.1 yamaguch ixm->ixm_size = size; 5554 1.1 yamaguch 5555 1.1 yamaguch if (bus_dmamap_create(sc->sc_dmat, ixm->ixm_size, 1, 5556 1.1 yamaguch ixm->ixm_size, 0, 5557 1.1 yamaguch BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, 5558 1.1 yamaguch &ixm->ixm_map) != 0) 5559 1.1 yamaguch return 1; 5560 1.1 yamaguch if (bus_dmamem_alloc(sc->sc_dmat, ixm->ixm_size, 5561 1.1 yamaguch align, 0, &ixm->ixm_seg, 1, &ixm->ixm_nsegs, 5562 1.1 yamaguch BUS_DMA_WAITOK) != 0) 5563 1.1 yamaguch goto destroy; 5564 1.1 yamaguch if (bus_dmamem_map(sc->sc_dmat, &ixm->ixm_seg, ixm->ixm_nsegs, 5565 1.1 yamaguch ixm->ixm_size, &ixm->ixm_kva, BUS_DMA_WAITOK) != 0) 5566 1.1 yamaguch goto free; 5567 1.1 yamaguch if (bus_dmamap_load(sc->sc_dmat, ixm->ixm_map, ixm->ixm_kva, 5568 1.1 yamaguch ixm->ixm_size, NULL, BUS_DMA_WAITOK) != 0) 5569 1.1 yamaguch goto unmap; 5570 1.1 yamaguch 5571 1.1 yamaguch memset(ixm->ixm_kva, 0, ixm->ixm_size); 5572 1.1 yamaguch 5573 1.1 yamaguch return 0; 5574 1.1 yamaguch unmap: 5575 1.1 yamaguch bus_dmamem_unmap(sc->sc_dmat, ixm->ixm_kva, ixm->ixm_size); 5576 1.1 yamaguch free: 5577 1.1 yamaguch bus_dmamem_free(sc->sc_dmat, &ixm->ixm_seg, 1); 5578 1.1 yamaguch destroy: 5579 1.1 yamaguch bus_dmamap_destroy(sc->sc_dmat, ixm->ixm_map); 5580 1.1 yamaguch return 1; 5581 1.1 yamaguch } 5582 1.1 yamaguch 5583 1.1 yamaguch static void 5584 1.1 yamaguch ixl_dmamem_free(struct ixl_softc *sc, struct ixl_dmamem *ixm) 5585 1.1 yamaguch { 5586 1.1 yamaguch bus_dmamap_unload(sc->sc_dmat, ixm->ixm_map); 5587 1.1 yamaguch bus_dmamem_unmap(sc->sc_dmat, ixm->ixm_kva, ixm->ixm_size); 5588 1.1 yamaguch bus_dmamem_free(sc->sc_dmat, &ixm->ixm_seg, 1); 5589 1.1 yamaguch bus_dmamap_destroy(sc->sc_dmat, ixm->ixm_map); 5590 1.1 yamaguch } 5591 1.1 yamaguch 5592 1.1 yamaguch static int 5593 1.12 yamaguch ixl_setup_vlan_hwfilter(struct ixl_softc *sc) 5594 1.1 yamaguch { 5595 1.12 yamaguch struct ethercom *ec = &sc->sc_ec; 5596 1.12 yamaguch struct vlanid_list *vlanidp; 5597 1.12 yamaguch int rv; 5598 1.12 yamaguch 5599 1.12 yamaguch ixl_remove_macvlan(sc, sc->sc_enaddr, 0, 5600 1.12 yamaguch IXL_AQ_OP_REMOVE_MACVLAN_IGNORE_VLAN); 5601 1.12 yamaguch ixl_remove_macvlan(sc, etherbroadcastaddr, 0, 5602 1.12 yamaguch IXL_AQ_OP_REMOVE_MACVLAN_IGNORE_VLAN); 5603 1.1 yamaguch 5604 1.12 yamaguch rv = ixl_add_macvlan(sc, sc->sc_enaddr, 0, 5605 1.12 yamaguch IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH); 5606 1.12 yamaguch if (rv != 0) 5607 1.12 yamaguch return rv; 5608 1.12 yamaguch rv = ixl_add_macvlan(sc, etherbroadcastaddr, 0, 5609 1.12 yamaguch IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH); 5610 1.12 yamaguch if (rv != 0) 5611 1.12 yamaguch return rv; 5612 1.1 yamaguch 5613 1.12 yamaguch ETHER_LOCK(ec); 5614 1.12 yamaguch SIMPLEQ_FOREACH(vlanidp, &ec->ec_vids, vid_list) { 5615 1.12 yamaguch rv = ixl_add_macvlan(sc, sc->sc_enaddr, 5616 1.12 yamaguch vlanidp->vid, IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH); 5617 1.12 yamaguch if (rv != 0) 5618 1.12 yamaguch break; 5619 1.12 yamaguch rv = ixl_add_macvlan(sc, etherbroadcastaddr, 5620 1.12 yamaguch vlanidp->vid, IXL_AQ_OP_ADD_MACVLAN_PERFECT_MATCH); 5621 1.12 yamaguch if (rv != 0) 5622 1.12 yamaguch break; 5623 1.1 yamaguch } 5624 1.12 yamaguch ETHER_UNLOCK(ec); 5625 1.1 yamaguch 5626 1.12 yamaguch return rv; 5627 1.12 yamaguch } 5628 1.12 yamaguch 5629 1.12 yamaguch static void 5630 1.12 yamaguch ixl_teardown_vlan_hwfilter(struct ixl_softc *sc) 5631 1.12 yamaguch { 5632 1.12 yamaguch struct vlanid_list *vlanidp; 5633 1.12 yamaguch struct ethercom *ec = &sc->sc_ec; 5634 1.12 yamaguch 5635 1.12 yamaguch ixl_remove_macvlan(sc, sc->sc_enaddr, 0, 5636 1.12 yamaguch IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH); 5637 1.12 yamaguch ixl_remove_macvlan(sc, etherbroadcastaddr, 0, 5638 1.12 yamaguch IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH); 5639 1.12 yamaguch 5640 1.12 yamaguch ETHER_LOCK(ec); 5641 1.12 yamaguch SIMPLEQ_FOREACH(vlanidp, &ec->ec_vids, vid_list) { 5642 1.12 yamaguch ixl_remove_macvlan(sc, sc->sc_enaddr, 5643 1.12 yamaguch vlanidp->vid, IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH); 5644 1.12 yamaguch ixl_remove_macvlan(sc, etherbroadcastaddr, 5645 1.12 yamaguch vlanidp->vid, IXL_AQ_OP_REMOVE_MACVLAN_PERFECT_MATCH); 5646 1.1 yamaguch } 5647 1.12 yamaguch ETHER_UNLOCK(ec); 5648 1.1 yamaguch 5649 1.12 yamaguch ixl_add_macvlan(sc, sc->sc_enaddr, 0, 5650 1.1 yamaguch IXL_AQ_OP_ADD_MACVLAN_IGNORE_VLAN); 5651 1.12 yamaguch ixl_add_macvlan(sc, etherbroadcastaddr, 0, 5652 1.12 yamaguch IXL_AQ_OP_ADD_MACVLAN_IGNORE_VLAN); 5653 1.12 yamaguch } 5654 1.12 yamaguch 5655 1.12 yamaguch static int 5656 1.12 yamaguch ixl_update_macvlan(struct ixl_softc *sc) 5657 1.12 yamaguch { 5658 1.12 yamaguch int rv = 0; 5659 1.12 yamaguch int next_ec_capenable = sc->sc_ec.ec_capenable; 5660 1.1 yamaguch 5661 1.12 yamaguch if (ISSET(next_ec_capenable, ETHERCAP_VLAN_HWFILTER)) { 5662 1.12 yamaguch rv = ixl_setup_vlan_hwfilter(sc); 5663 1.12 yamaguch if (rv != 0) 5664 1.12 yamaguch ixl_teardown_vlan_hwfilter(sc); 5665 1.12 yamaguch } else { 5666 1.12 yamaguch ixl_teardown_vlan_hwfilter(sc); 5667 1.1 yamaguch } 5668 1.1 yamaguch 5669 1.1 yamaguch return rv; 5670 1.1 yamaguch } 5671 1.1 yamaguch 5672 1.1 yamaguch static int 5673 1.1 yamaguch ixl_ifflags_cb(struct ethercom *ec) 5674 1.1 yamaguch { 5675 1.9 yamaguch struct ifnet *ifp = &ec->ec_if; 5676 1.9 yamaguch struct ixl_softc *sc = ifp->if_softc; 5677 1.94 yamaguch int rv, change, reset_bits; 5678 1.9 yamaguch 5679 1.9 yamaguch mutex_enter(&sc->sc_cfg_lock); 5680 1.11 yamaguch 5681 1.11 yamaguch change = ec->ec_capenable ^ sc->sc_cur_ec_capenable; 5682 1.94 yamaguch reset_bits = change & (ETHERCAP_VLAN_HWTAGGING | ETHERCAP_VLAN_MTU); 5683 1.94 yamaguch if (reset_bits != 0) { 5684 1.94 yamaguch sc->sc_cur_ec_capenable ^= reset_bits; 5685 1.11 yamaguch rv = ENETRESET; 5686 1.11 yamaguch goto out; 5687 1.11 yamaguch } 5688 1.11 yamaguch 5689 1.12 yamaguch if (ISSET(change, ETHERCAP_VLAN_HWFILTER)) { 5690 1.12 yamaguch rv = ixl_update_macvlan(sc); 5691 1.12 yamaguch if (rv == 0) { 5692 1.12 yamaguch sc->sc_cur_ec_capenable ^= ETHERCAP_VLAN_HWFILTER; 5693 1.12 yamaguch } else { 5694 1.12 yamaguch CLR(ec->ec_capenable, ETHERCAP_VLAN_HWFILTER); 5695 1.12 yamaguch CLR(sc->sc_cur_ec_capenable, ETHERCAP_VLAN_HWFILTER); 5696 1.12 yamaguch } 5697 1.12 yamaguch } 5698 1.12 yamaguch 5699 1.9 yamaguch rv = ixl_iff(sc); 5700 1.11 yamaguch out: 5701 1.9 yamaguch mutex_exit(&sc->sc_cfg_lock); 5702 1.1 yamaguch 5703 1.9 yamaguch return rv; 5704 1.1 yamaguch } 5705 1.1 yamaguch 5706 1.1 yamaguch static int 5707 1.62 yamaguch ixl_set_link_status_locked(struct ixl_softc *sc, const struct ixl_aq_desc *iaq) 5708 1.1 yamaguch { 5709 1.1 yamaguch const struct ixl_aq_link_status *status; 5710 1.1 yamaguch const struct ixl_phy_type *itype; 5711 1.1 yamaguch 5712 1.1 yamaguch uint64_t ifm_active = IFM_ETHER; 5713 1.1 yamaguch uint64_t ifm_status = IFM_AVALID; 5714 1.1 yamaguch int link_state = LINK_STATE_DOWN; 5715 1.1 yamaguch uint64_t baudrate = 0; 5716 1.1 yamaguch 5717 1.1 yamaguch status = (const struct ixl_aq_link_status *)iaq->iaq_param; 5718 1.31 yamaguch if (!ISSET(status->link_info, IXL_AQ_LINK_UP_FUNCTION)) { 5719 1.31 yamaguch ifm_active |= IFM_NONE; 5720 1.1 yamaguch goto done; 5721 1.31 yamaguch } 5722 1.1 yamaguch 5723 1.1 yamaguch ifm_active |= IFM_FDX; 5724 1.1 yamaguch ifm_status |= IFM_ACTIVE; 5725 1.1 yamaguch link_state = LINK_STATE_UP; 5726 1.1 yamaguch 5727 1.1 yamaguch itype = ixl_search_phy_type(status->phy_type); 5728 1.1 yamaguch if (itype != NULL) 5729 1.1 yamaguch ifm_active |= itype->ifm_type; 5730 1.1 yamaguch 5731 1.1 yamaguch if (ISSET(status->an_info, IXL_AQ_LINK_PAUSE_TX)) 5732 1.1 yamaguch ifm_active |= IFM_ETH_TXPAUSE; 5733 1.1 yamaguch if (ISSET(status->an_info, IXL_AQ_LINK_PAUSE_RX)) 5734 1.1 yamaguch ifm_active |= IFM_ETH_RXPAUSE; 5735 1.1 yamaguch 5736 1.1 yamaguch baudrate = ixl_search_link_speed(status->link_speed); 5737 1.1 yamaguch 5738 1.1 yamaguch done: 5739 1.62 yamaguch /* sc->sc_cfg_lock held expect during attach */ 5740 1.1 yamaguch sc->sc_media_active = ifm_active; 5741 1.1 yamaguch sc->sc_media_status = ifm_status; 5742 1.1 yamaguch 5743 1.1 yamaguch sc->sc_ec.ec_if.if_baudrate = baudrate; 5744 1.1 yamaguch 5745 1.1 yamaguch return link_state; 5746 1.1 yamaguch } 5747 1.1 yamaguch 5748 1.1 yamaguch static int 5749 1.1 yamaguch ixl_establish_intx(struct ixl_softc *sc) 5750 1.1 yamaguch { 5751 1.1 yamaguch pci_chipset_tag_t pc = sc->sc_pa.pa_pc; 5752 1.1 yamaguch pci_intr_handle_t *intr; 5753 1.1 yamaguch char xnamebuf[32]; 5754 1.1 yamaguch char intrbuf[PCI_INTRSTR_LEN]; 5755 1.1 yamaguch char const *intrstr; 5756 1.1 yamaguch 5757 1.1 yamaguch KASSERT(sc->sc_nintrs == 1); 5758 1.1 yamaguch 5759 1.1 yamaguch intr = &sc->sc_ihp[0]; 5760 1.1 yamaguch 5761 1.1 yamaguch intrstr = pci_intr_string(pc, *intr, intrbuf, sizeof(intrbuf)); 5762 1.1 yamaguch snprintf(xnamebuf, sizeof(xnamebuf), "%s:legacy", 5763 1.1 yamaguch device_xname(sc->sc_dev)); 5764 1.1 yamaguch 5765 1.1 yamaguch sc->sc_ihs[0] = pci_intr_establish_xname(pc, *intr, IPL_NET, ixl_intr, 5766 1.1 yamaguch sc, xnamebuf); 5767 1.1 yamaguch 5768 1.1 yamaguch if (sc->sc_ihs[0] == NULL) { 5769 1.1 yamaguch aprint_error_dev(sc->sc_dev, 5770 1.1 yamaguch "unable to establish interrupt at %s\n", intrstr); 5771 1.1 yamaguch return -1; 5772 1.1 yamaguch } 5773 1.1 yamaguch 5774 1.1 yamaguch aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr); 5775 1.1 yamaguch return 0; 5776 1.1 yamaguch } 5777 1.1 yamaguch 5778 1.1 yamaguch static int 5779 1.1 yamaguch ixl_establish_msix(struct ixl_softc *sc) 5780 1.1 yamaguch { 5781 1.1 yamaguch pci_chipset_tag_t pc = sc->sc_pa.pa_pc; 5782 1.22 yamaguch kcpuset_t *affinity; 5783 1.1 yamaguch unsigned int vector = 0; 5784 1.1 yamaguch unsigned int i; 5785 1.22 yamaguch int affinity_to, r; 5786 1.1 yamaguch char xnamebuf[32]; 5787 1.1 yamaguch char intrbuf[PCI_INTRSTR_LEN]; 5788 1.1 yamaguch char const *intrstr; 5789 1.1 yamaguch 5790 1.22 yamaguch kcpuset_create(&affinity, false); 5791 1.22 yamaguch 5792 1.1 yamaguch /* the "other" intr is mapped to vector 0 */ 5793 1.1 yamaguch vector = 0; 5794 1.1 yamaguch intrstr = pci_intr_string(pc, sc->sc_ihp[vector], 5795 1.1 yamaguch intrbuf, sizeof(intrbuf)); 5796 1.1 yamaguch snprintf(xnamebuf, sizeof(xnamebuf), "%s others", 5797 1.1 yamaguch device_xname(sc->sc_dev)); 5798 1.1 yamaguch sc->sc_ihs[vector] = pci_intr_establish_xname(pc, 5799 1.1 yamaguch sc->sc_ihp[vector], IPL_NET, ixl_other_intr, 5800 1.1 yamaguch sc, xnamebuf); 5801 1.1 yamaguch if (sc->sc_ihs[vector] == NULL) { 5802 1.1 yamaguch aprint_error_dev(sc->sc_dev, 5803 1.1 yamaguch "unable to establish interrupt at %s\n", intrstr); 5804 1.1 yamaguch goto fail; 5805 1.1 yamaguch } 5806 1.22 yamaguch 5807 1.22 yamaguch aprint_normal_dev(sc->sc_dev, "other interrupt at %s", intrstr); 5808 1.22 yamaguch 5809 1.22 yamaguch affinity_to = ncpu > (int)sc->sc_nqueue_pairs_max ? 1 : 0; 5810 1.22 yamaguch affinity_to = (affinity_to + sc->sc_nqueue_pairs_max) % ncpu; 5811 1.22 yamaguch 5812 1.22 yamaguch kcpuset_zero(affinity); 5813 1.22 yamaguch kcpuset_set(affinity, affinity_to); 5814 1.22 yamaguch r = interrupt_distribute(sc->sc_ihs[vector], affinity, NULL); 5815 1.22 yamaguch if (r == 0) { 5816 1.22 yamaguch aprint_normal(", affinity to %u", affinity_to); 5817 1.22 yamaguch } 5818 1.22 yamaguch aprint_normal("\n"); 5819 1.1 yamaguch vector++; 5820 1.1 yamaguch 5821 1.1 yamaguch sc->sc_msix_vector_queue = vector; 5822 1.22 yamaguch affinity_to = ncpu > (int)sc->sc_nqueue_pairs_max ? 1 : 0; 5823 1.1 yamaguch 5824 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs_max; i++) { 5825 1.1 yamaguch intrstr = pci_intr_string(pc, sc->sc_ihp[vector], 5826 1.1 yamaguch intrbuf, sizeof(intrbuf)); 5827 1.1 yamaguch snprintf(xnamebuf, sizeof(xnamebuf), "%s TXRX%d", 5828 1.1 yamaguch device_xname(sc->sc_dev), i); 5829 1.1 yamaguch 5830 1.1 yamaguch sc->sc_ihs[vector] = pci_intr_establish_xname(pc, 5831 1.1 yamaguch sc->sc_ihp[vector], IPL_NET, ixl_queue_intr, 5832 1.1 yamaguch (void *)&sc->sc_qps[i], xnamebuf); 5833 1.1 yamaguch 5834 1.1 yamaguch if (sc->sc_ihs[vector] == NULL) { 5835 1.1 yamaguch aprint_error_dev(sc->sc_dev, 5836 1.1 yamaguch "unable to establish interrupt at %s\n", intrstr); 5837 1.1 yamaguch goto fail; 5838 1.1 yamaguch } 5839 1.22 yamaguch 5840 1.22 yamaguch aprint_normal_dev(sc->sc_dev, 5841 1.72 yamaguch "for TXRX%d interrupt at %s", i, intrstr); 5842 1.22 yamaguch 5843 1.22 yamaguch kcpuset_zero(affinity); 5844 1.22 yamaguch kcpuset_set(affinity, affinity_to); 5845 1.22 yamaguch r = interrupt_distribute(sc->sc_ihs[vector], affinity, NULL); 5846 1.22 yamaguch if (r == 0) { 5847 1.22 yamaguch aprint_normal(", affinity to %u", affinity_to); 5848 1.22 yamaguch affinity_to = (affinity_to + 1) % ncpu; 5849 1.22 yamaguch } 5850 1.22 yamaguch aprint_normal("\n"); 5851 1.1 yamaguch vector++; 5852 1.1 yamaguch } 5853 1.1 yamaguch 5854 1.22 yamaguch kcpuset_destroy(affinity); 5855 1.22 yamaguch 5856 1.1 yamaguch return 0; 5857 1.1 yamaguch fail: 5858 1.1 yamaguch for (i = 0; i < vector; i++) { 5859 1.1 yamaguch pci_intr_disestablish(pc, sc->sc_ihs[i]); 5860 1.1 yamaguch } 5861 1.1 yamaguch 5862 1.1 yamaguch sc->sc_msix_vector_queue = 0; 5863 1.1 yamaguch sc->sc_msix_vector_queue = 0; 5864 1.22 yamaguch kcpuset_destroy(affinity); 5865 1.1 yamaguch 5866 1.1 yamaguch return -1; 5867 1.1 yamaguch } 5868 1.1 yamaguch 5869 1.1 yamaguch static void 5870 1.1 yamaguch ixl_config_queue_intr(struct ixl_softc *sc) 5871 1.1 yamaguch { 5872 1.1 yamaguch unsigned int i, vector; 5873 1.1 yamaguch 5874 1.1 yamaguch if (sc->sc_intrtype == PCI_INTR_TYPE_MSIX) { 5875 1.1 yamaguch vector = sc->sc_msix_vector_queue; 5876 1.1 yamaguch } else { 5877 1.1 yamaguch vector = I40E_INTR_NOTX_INTR; 5878 1.1 yamaguch 5879 1.1 yamaguch ixl_wr(sc, I40E_PFINT_LNKLST0, 5880 1.1 yamaguch (I40E_INTR_NOTX_QUEUE << 5881 1.1 yamaguch I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT) | 5882 1.1 yamaguch (I40E_QUEUE_TYPE_RX << 5883 1.1 yamaguch I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT)); 5884 1.1 yamaguch } 5885 1.1 yamaguch 5886 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs; i++) { 5887 1.1 yamaguch ixl_wr(sc, I40E_PFINT_DYN_CTLN(i), 0); 5888 1.1 yamaguch ixl_flush(sc); 5889 1.1 yamaguch 5890 1.1 yamaguch ixl_wr(sc, I40E_PFINT_LNKLSTN(i), 5891 1.1 yamaguch ((i) << I40E_PFINT_LNKLSTN_FIRSTQ_INDX_SHIFT) | 5892 1.1 yamaguch (I40E_QUEUE_TYPE_RX << 5893 1.1 yamaguch I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT)); 5894 1.1 yamaguch 5895 1.1 yamaguch ixl_wr(sc, I40E_QINT_RQCTL(i), 5896 1.1 yamaguch (vector << I40E_QINT_RQCTL_MSIX_INDX_SHIFT) | 5897 1.1 yamaguch (I40E_ITR_INDEX_RX << 5898 1.1 yamaguch I40E_QINT_RQCTL_ITR_INDX_SHIFT) | 5899 1.1 yamaguch (I40E_INTR_NOTX_RX_QUEUE << 5900 1.1 yamaguch I40E_QINT_RQCTL_MSIX0_INDX_SHIFT) | 5901 1.1 yamaguch (i << I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT) | 5902 1.1 yamaguch (I40E_QUEUE_TYPE_TX << 5903 1.1 yamaguch I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT) | 5904 1.1 yamaguch I40E_QINT_RQCTL_CAUSE_ENA_MASK); 5905 1.1 yamaguch 5906 1.1 yamaguch ixl_wr(sc, I40E_QINT_TQCTL(i), 5907 1.1 yamaguch (vector << I40E_QINT_TQCTL_MSIX_INDX_SHIFT) | 5908 1.1 yamaguch (I40E_ITR_INDEX_TX << 5909 1.1 yamaguch I40E_QINT_TQCTL_ITR_INDX_SHIFT) | 5910 1.1 yamaguch (I40E_INTR_NOTX_TX_QUEUE << 5911 1.1 yamaguch I40E_QINT_TQCTL_MSIX0_INDX_SHIFT) | 5912 1.1 yamaguch (I40E_QUEUE_TYPE_EOL << 5913 1.1 yamaguch I40E_QINT_TQCTL_NEXTQ_INDX_SHIFT) | 5914 1.1 yamaguch (I40E_QUEUE_TYPE_RX << 5915 1.1 yamaguch I40E_QINT_TQCTL_NEXTQ_TYPE_SHIFT) | 5916 1.1 yamaguch I40E_QINT_TQCTL_CAUSE_ENA_MASK); 5917 1.1 yamaguch 5918 1.64 yamaguch if (sc->sc_intrtype == PCI_INTR_TYPE_MSIX) { 5919 1.64 yamaguch ixl_wr(sc, I40E_PFINT_ITRN(I40E_ITR_INDEX_RX, i), 5920 1.64 yamaguch sc->sc_itr_rx); 5921 1.64 yamaguch ixl_wr(sc, I40E_PFINT_ITRN(I40E_ITR_INDEX_TX, i), 5922 1.64 yamaguch sc->sc_itr_tx); 5923 1.1 yamaguch vector++; 5924 1.64 yamaguch } 5925 1.1 yamaguch } 5926 1.1 yamaguch ixl_flush(sc); 5927 1.1 yamaguch 5928 1.64 yamaguch ixl_wr(sc, I40E_PFINT_ITR0(I40E_ITR_INDEX_RX), sc->sc_itr_rx); 5929 1.64 yamaguch ixl_wr(sc, I40E_PFINT_ITR0(I40E_ITR_INDEX_TX), sc->sc_itr_tx); 5930 1.1 yamaguch ixl_flush(sc); 5931 1.1 yamaguch } 5932 1.1 yamaguch 5933 1.1 yamaguch static void 5934 1.1 yamaguch ixl_config_other_intr(struct ixl_softc *sc) 5935 1.1 yamaguch { 5936 1.1 yamaguch ixl_wr(sc, I40E_PFINT_ICR0_ENA, 0); 5937 1.1 yamaguch (void)ixl_rd(sc, I40E_PFINT_ICR0); 5938 1.1 yamaguch 5939 1.1 yamaguch ixl_wr(sc, I40E_PFINT_ICR0_ENA, 5940 1.1 yamaguch I40E_PFINT_ICR0_ENA_ECC_ERR_MASK | 5941 1.1 yamaguch I40E_PFINT_ICR0_ENA_GRST_MASK | 5942 1.1 yamaguch I40E_PFINT_ICR0_ENA_ADMINQ_MASK | 5943 1.1 yamaguch I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK | 5944 1.1 yamaguch I40E_PFINT_ICR0_ENA_HMC_ERR_MASK | 5945 1.1 yamaguch I40E_PFINT_ICR0_ENA_VFLR_MASK | 5946 1.1 yamaguch I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK | 5947 1.1 yamaguch I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_MASK | 5948 1.1 yamaguch I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK); 5949 1.1 yamaguch 5950 1.1 yamaguch ixl_wr(sc, I40E_PFINT_LNKLST0, 0x7FF); 5951 1.1 yamaguch ixl_wr(sc, I40E_PFINT_ITR0(I40E_ITR_INDEX_OTHER), 0); 5952 1.1 yamaguch ixl_wr(sc, I40E_PFINT_STAT_CTL0, 5953 1.1 yamaguch (I40E_ITR_INDEX_OTHER << 5954 1.1 yamaguch I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_SHIFT)); 5955 1.1 yamaguch ixl_flush(sc); 5956 1.1 yamaguch } 5957 1.1 yamaguch 5958 1.1 yamaguch static int 5959 1.1 yamaguch ixl_setup_interrupts(struct ixl_softc *sc) 5960 1.1 yamaguch { 5961 1.1 yamaguch struct pci_attach_args *pa = &sc->sc_pa; 5962 1.1 yamaguch pci_intr_type_t max_type, intr_type; 5963 1.1 yamaguch int counts[PCI_INTR_TYPE_SIZE]; 5964 1.1 yamaguch int error; 5965 1.1 yamaguch unsigned int i; 5966 1.19 yamaguch bool retry; 5967 1.1 yamaguch 5968 1.1 yamaguch memset(counts, 0, sizeof(counts)); 5969 1.1 yamaguch max_type = PCI_INTR_TYPE_MSIX; 5970 1.1 yamaguch /* QPs + other interrupt */ 5971 1.1 yamaguch counts[PCI_INTR_TYPE_MSIX] = sc->sc_nqueue_pairs_max + 1; 5972 1.1 yamaguch counts[PCI_INTR_TYPE_INTX] = 1; 5973 1.1 yamaguch 5974 1.19 yamaguch if (ixl_param_nomsix) 5975 1.1 yamaguch counts[PCI_INTR_TYPE_MSIX] = 0; 5976 1.1 yamaguch 5977 1.1 yamaguch do { 5978 1.1 yamaguch retry = false; 5979 1.1 yamaguch error = pci_intr_alloc(pa, &sc->sc_ihp, counts, max_type); 5980 1.1 yamaguch if (error != 0) { 5981 1.1 yamaguch aprint_error_dev(sc->sc_dev, 5982 1.1 yamaguch "couldn't map interrupt\n"); 5983 1.1 yamaguch break; 5984 1.1 yamaguch } 5985 1.27 yamaguch 5986 1.27 yamaguch intr_type = pci_intr_type(pa->pa_pc, sc->sc_ihp[0]); 5987 1.27 yamaguch sc->sc_nintrs = counts[intr_type]; 5988 1.27 yamaguch KASSERT(sc->sc_nintrs > 0); 5989 1.27 yamaguch 5990 1.1 yamaguch for (i = 0; i < sc->sc_nintrs; i++) { 5991 1.1 yamaguch pci_intr_setattr(pa->pa_pc, &sc->sc_ihp[i], 5992 1.1 yamaguch PCI_INTR_MPSAFE, true); 5993 1.1 yamaguch } 5994 1.1 yamaguch 5995 1.76 jakllsch sc->sc_ihs = kmem_zalloc(sizeof(sc->sc_ihs[0]) * sc->sc_nintrs, 5996 1.1 yamaguch KM_SLEEP); 5997 1.1 yamaguch 5998 1.1 yamaguch if (intr_type == PCI_INTR_TYPE_MSIX) { 5999 1.1 yamaguch error = ixl_establish_msix(sc); 6000 1.1 yamaguch if (error) { 6001 1.1 yamaguch counts[PCI_INTR_TYPE_MSIX] = 0; 6002 1.1 yamaguch retry = true; 6003 1.1 yamaguch } 6004 1.1 yamaguch } else if (intr_type == PCI_INTR_TYPE_INTX) { 6005 1.1 yamaguch error = ixl_establish_intx(sc); 6006 1.1 yamaguch } else { 6007 1.1 yamaguch error = -1; 6008 1.1 yamaguch } 6009 1.1 yamaguch 6010 1.1 yamaguch if (error) { 6011 1.1 yamaguch kmem_free(sc->sc_ihs, 6012 1.1 yamaguch sizeof(sc->sc_ihs[0]) * sc->sc_nintrs); 6013 1.1 yamaguch pci_intr_release(pa->pa_pc, sc->sc_ihp, sc->sc_nintrs); 6014 1.1 yamaguch } else { 6015 1.1 yamaguch sc->sc_intrtype = intr_type; 6016 1.1 yamaguch } 6017 1.1 yamaguch } while (retry); 6018 1.1 yamaguch 6019 1.1 yamaguch return error; 6020 1.1 yamaguch } 6021 1.1 yamaguch 6022 1.1 yamaguch static void 6023 1.1 yamaguch ixl_teardown_interrupts(struct ixl_softc *sc) 6024 1.1 yamaguch { 6025 1.1 yamaguch struct pci_attach_args *pa = &sc->sc_pa; 6026 1.1 yamaguch unsigned int i; 6027 1.1 yamaguch 6028 1.1 yamaguch for (i = 0; i < sc->sc_nintrs; i++) { 6029 1.1 yamaguch pci_intr_disestablish(pa->pa_pc, sc->sc_ihs[i]); 6030 1.1 yamaguch } 6031 1.1 yamaguch 6032 1.1 yamaguch pci_intr_release(pa->pa_pc, sc->sc_ihp, sc->sc_nintrs); 6033 1.1 yamaguch 6034 1.1 yamaguch kmem_free(sc->sc_ihs, sizeof(sc->sc_ihs[0]) * sc->sc_nintrs); 6035 1.1 yamaguch sc->sc_ihs = NULL; 6036 1.1 yamaguch sc->sc_nintrs = 0; 6037 1.1 yamaguch } 6038 1.1 yamaguch 6039 1.1 yamaguch static int 6040 1.1 yamaguch ixl_setup_stats(struct ixl_softc *sc) 6041 1.1 yamaguch { 6042 1.1 yamaguch struct ixl_queue_pair *qp; 6043 1.1 yamaguch struct ixl_tx_ring *txr; 6044 1.1 yamaguch struct ixl_rx_ring *rxr; 6045 1.17 yamaguch struct ixl_stats_counters *isc; 6046 1.1 yamaguch unsigned int i; 6047 1.1 yamaguch 6048 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs_max; i++) { 6049 1.1 yamaguch qp = &sc->sc_qps[i]; 6050 1.1 yamaguch txr = qp->qp_txr; 6051 1.1 yamaguch rxr = qp->qp_rxr; 6052 1.1 yamaguch 6053 1.1 yamaguch evcnt_attach_dynamic(&txr->txr_defragged, EVCNT_TYPE_MISC, 6054 1.1 yamaguch NULL, qp->qp_name, "m_defrag successed"); 6055 1.1 yamaguch evcnt_attach_dynamic(&txr->txr_defrag_failed, EVCNT_TYPE_MISC, 6056 1.1 yamaguch NULL, qp->qp_name, "m_defrag_failed"); 6057 1.1 yamaguch evcnt_attach_dynamic(&txr->txr_pcqdrop, EVCNT_TYPE_MISC, 6058 1.1 yamaguch NULL, qp->qp_name, "Dropped in pcq"); 6059 1.1 yamaguch evcnt_attach_dynamic(&txr->txr_transmitdef, EVCNT_TYPE_MISC, 6060 1.1 yamaguch NULL, qp->qp_name, "Deferred transmit"); 6061 1.1 yamaguch evcnt_attach_dynamic(&txr->txr_intr, EVCNT_TYPE_INTR, 6062 1.1 yamaguch NULL, qp->qp_name, "Interrupt on queue"); 6063 1.1 yamaguch evcnt_attach_dynamic(&txr->txr_defer, EVCNT_TYPE_MISC, 6064 1.1 yamaguch NULL, qp->qp_name, "Handled queue in softint/workqueue"); 6065 1.1 yamaguch 6066 1.1 yamaguch evcnt_attach_dynamic(&rxr->rxr_mgethdr_failed, EVCNT_TYPE_MISC, 6067 1.1 yamaguch NULL, qp->qp_name, "MGETHDR failed"); 6068 1.1 yamaguch evcnt_attach_dynamic(&rxr->rxr_mgetcl_failed, EVCNT_TYPE_MISC, 6069 1.1 yamaguch NULL, qp->qp_name, "MCLGET failed"); 6070 1.1 yamaguch evcnt_attach_dynamic(&rxr->rxr_mbuf_load_failed, 6071 1.1 yamaguch EVCNT_TYPE_MISC, NULL, qp->qp_name, 6072 1.1 yamaguch "bus_dmamap_load_mbuf failed"); 6073 1.1 yamaguch evcnt_attach_dynamic(&rxr->rxr_intr, EVCNT_TYPE_INTR, 6074 1.1 yamaguch NULL, qp->qp_name, "Interrupt on queue"); 6075 1.1 yamaguch evcnt_attach_dynamic(&rxr->rxr_defer, EVCNT_TYPE_MISC, 6076 1.1 yamaguch NULL, qp->qp_name, "Handled queue in softint/workqueue"); 6077 1.1 yamaguch } 6078 1.1 yamaguch 6079 1.1 yamaguch evcnt_attach_dynamic(&sc->sc_event_atq, EVCNT_TYPE_INTR, 6080 1.1 yamaguch NULL, device_xname(sc->sc_dev), "Interrupt for other events"); 6081 1.1 yamaguch evcnt_attach_dynamic(&sc->sc_event_link, EVCNT_TYPE_MISC, 6082 1.1 yamaguch NULL, device_xname(sc->sc_dev), "Link status event"); 6083 1.1 yamaguch evcnt_attach_dynamic(&sc->sc_event_ecc_err, EVCNT_TYPE_MISC, 6084 1.1 yamaguch NULL, device_xname(sc->sc_dev), "ECC error"); 6085 1.1 yamaguch evcnt_attach_dynamic(&sc->sc_event_pci_exception, EVCNT_TYPE_MISC, 6086 1.1 yamaguch NULL, device_xname(sc->sc_dev), "PCI exception"); 6087 1.1 yamaguch evcnt_attach_dynamic(&sc->sc_event_crit_err, EVCNT_TYPE_MISC, 6088 1.1 yamaguch NULL, device_xname(sc->sc_dev), "Critical error"); 6089 1.1 yamaguch 6090 1.17 yamaguch isc = &sc->sc_stats_counters; 6091 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_crc_errors, EVCNT_TYPE_MISC, 6092 1.17 yamaguch NULL, device_xname(sc->sc_dev), "CRC errors"); 6093 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_illegal_bytes, EVCNT_TYPE_MISC, 6094 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Illegal bytes"); 6095 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_mac_local_faults, EVCNT_TYPE_MISC, 6096 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Mac local faults"); 6097 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_mac_remote_faults, EVCNT_TYPE_MISC, 6098 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Mac remote faults"); 6099 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_link_xon_rx, EVCNT_TYPE_MISC, 6100 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx xon"); 6101 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_link_xon_tx, EVCNT_TYPE_MISC, 6102 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Tx xon"); 6103 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_link_xoff_rx, EVCNT_TYPE_MISC, 6104 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx xoff"); 6105 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_link_xoff_tx, EVCNT_TYPE_MISC, 6106 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Tx xoff"); 6107 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_fragments, EVCNT_TYPE_MISC, 6108 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx fragments"); 6109 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_jabber, EVCNT_TYPE_MISC, 6110 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx jabber"); 6111 1.17 yamaguch 6112 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_size_64, EVCNT_TYPE_MISC, 6113 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx size 64"); 6114 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_size_127, EVCNT_TYPE_MISC, 6115 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx size 127"); 6116 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_size_255, EVCNT_TYPE_MISC, 6117 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx size 255"); 6118 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_size_511, EVCNT_TYPE_MISC, 6119 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx size 511"); 6120 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_size_1023, EVCNT_TYPE_MISC, 6121 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx size 1023"); 6122 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_size_1522, EVCNT_TYPE_MISC, 6123 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx size 1522"); 6124 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_size_big, EVCNT_TYPE_MISC, 6125 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx jumbo packets"); 6126 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_undersize, EVCNT_TYPE_MISC, 6127 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx under size"); 6128 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_oversize, EVCNT_TYPE_MISC, 6129 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx over size"); 6130 1.17 yamaguch 6131 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_bytes, EVCNT_TYPE_MISC, 6132 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx bytes / port"); 6133 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_discards, EVCNT_TYPE_MISC, 6134 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx discards / port"); 6135 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_unicast, EVCNT_TYPE_MISC, 6136 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx unicast / port"); 6137 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_multicast, EVCNT_TYPE_MISC, 6138 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx multicast / port"); 6139 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_rx_broadcast, EVCNT_TYPE_MISC, 6140 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Rx broadcast / port"); 6141 1.17 yamaguch 6142 1.18 yamaguch evcnt_attach_dynamic(&isc->isc_vsi_rx_bytes, EVCNT_TYPE_MISC, 6143 1.18 yamaguch NULL, device_xname(sc->sc_dev), "Rx bytes / vsi"); 6144 1.18 yamaguch evcnt_attach_dynamic(&isc->isc_vsi_rx_discards, EVCNT_TYPE_MISC, 6145 1.85 yamaguch NULL, device_xname(sc->sc_dev), "Rx discards / vsi"); 6146 1.18 yamaguch evcnt_attach_dynamic(&isc->isc_vsi_rx_unicast, EVCNT_TYPE_MISC, 6147 1.18 yamaguch NULL, device_xname(sc->sc_dev), "Rx unicast / vsi"); 6148 1.18 yamaguch evcnt_attach_dynamic(&isc->isc_vsi_rx_multicast, EVCNT_TYPE_MISC, 6149 1.18 yamaguch NULL, device_xname(sc->sc_dev), "Rx multicast / vsi"); 6150 1.18 yamaguch evcnt_attach_dynamic(&isc->isc_vsi_rx_broadcast, EVCNT_TYPE_MISC, 6151 1.18 yamaguch NULL, device_xname(sc->sc_dev), "Rx broadcast / vsi"); 6152 1.18 yamaguch 6153 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_tx_size_64, EVCNT_TYPE_MISC, 6154 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Tx size 64"); 6155 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_tx_size_127, EVCNT_TYPE_MISC, 6156 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Tx size 127"); 6157 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_tx_size_255, EVCNT_TYPE_MISC, 6158 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Tx size 255"); 6159 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_tx_size_511, EVCNT_TYPE_MISC, 6160 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Tx size 511"); 6161 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_tx_size_1023, EVCNT_TYPE_MISC, 6162 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Tx size 1023"); 6163 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_tx_size_1522, EVCNT_TYPE_MISC, 6164 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Tx size 1522"); 6165 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_tx_size_big, EVCNT_TYPE_MISC, 6166 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Tx jumbo packets"); 6167 1.17 yamaguch 6168 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_tx_bytes, EVCNT_TYPE_MISC, 6169 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Tx bytes / port"); 6170 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_tx_dropped_link_down, EVCNT_TYPE_MISC, 6171 1.17 yamaguch NULL, device_xname(sc->sc_dev), 6172 1.17 yamaguch "Tx dropped due to link down / port"); 6173 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_tx_unicast, EVCNT_TYPE_MISC, 6174 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Tx unicast / port"); 6175 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_tx_multicast, EVCNT_TYPE_MISC, 6176 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Tx multicast / port"); 6177 1.17 yamaguch evcnt_attach_dynamic(&isc->isc_tx_broadcast, EVCNT_TYPE_MISC, 6178 1.17 yamaguch NULL, device_xname(sc->sc_dev), "Tx broadcast / port"); 6179 1.17 yamaguch 6180 1.18 yamaguch evcnt_attach_dynamic(&isc->isc_vsi_tx_bytes, EVCNT_TYPE_MISC, 6181 1.18 yamaguch NULL, device_xname(sc->sc_dev), "Tx bytes / vsi"); 6182 1.18 yamaguch evcnt_attach_dynamic(&isc->isc_vsi_tx_errors, EVCNT_TYPE_MISC, 6183 1.18 yamaguch NULL, device_xname(sc->sc_dev), "Tx errors / vsi"); 6184 1.18 yamaguch evcnt_attach_dynamic(&isc->isc_vsi_tx_unicast, EVCNT_TYPE_MISC, 6185 1.18 yamaguch NULL, device_xname(sc->sc_dev), "Tx unicast / vsi"); 6186 1.18 yamaguch evcnt_attach_dynamic(&isc->isc_vsi_tx_multicast, EVCNT_TYPE_MISC, 6187 1.18 yamaguch NULL, device_xname(sc->sc_dev), "Tx multicast / vsi"); 6188 1.18 yamaguch evcnt_attach_dynamic(&isc->isc_vsi_tx_broadcast, EVCNT_TYPE_MISC, 6189 1.18 yamaguch NULL, device_xname(sc->sc_dev), "Tx broadcast / vsi"); 6190 1.18 yamaguch 6191 1.19 yamaguch sc->sc_stats_intval = ixl_param_stats_interval; 6192 1.17 yamaguch callout_init(&sc->sc_stats_callout, CALLOUT_MPSAFE); 6193 1.17 yamaguch callout_setfunc(&sc->sc_stats_callout, ixl_stats_callout, sc); 6194 1.17 yamaguch ixl_work_set(&sc->sc_stats_task, ixl_stats_update, sc); 6195 1.17 yamaguch 6196 1.1 yamaguch return 0; 6197 1.1 yamaguch } 6198 1.1 yamaguch 6199 1.1 yamaguch static void 6200 1.1 yamaguch ixl_teardown_stats(struct ixl_softc *sc) 6201 1.1 yamaguch { 6202 1.1 yamaguch struct ixl_tx_ring *txr; 6203 1.1 yamaguch struct ixl_rx_ring *rxr; 6204 1.17 yamaguch struct ixl_stats_counters *isc; 6205 1.1 yamaguch unsigned int i; 6206 1.1 yamaguch 6207 1.1 yamaguch for (i = 0; i < sc->sc_nqueue_pairs_max; i++) { 6208 1.1 yamaguch txr = sc->sc_qps[i].qp_txr; 6209 1.1 yamaguch rxr = sc->sc_qps[i].qp_rxr; 6210 1.1 yamaguch 6211 1.1 yamaguch evcnt_detach(&txr->txr_defragged); 6212 1.1 yamaguch evcnt_detach(&txr->txr_defrag_failed); 6213 1.1 yamaguch evcnt_detach(&txr->txr_pcqdrop); 6214 1.1 yamaguch evcnt_detach(&txr->txr_transmitdef); 6215 1.1 yamaguch evcnt_detach(&txr->txr_intr); 6216 1.1 yamaguch evcnt_detach(&txr->txr_defer); 6217 1.1 yamaguch 6218 1.1 yamaguch evcnt_detach(&rxr->rxr_mgethdr_failed); 6219 1.1 yamaguch evcnt_detach(&rxr->rxr_mgetcl_failed); 6220 1.1 yamaguch evcnt_detach(&rxr->rxr_mbuf_load_failed); 6221 1.1 yamaguch evcnt_detach(&rxr->rxr_intr); 6222 1.1 yamaguch evcnt_detach(&rxr->rxr_defer); 6223 1.1 yamaguch } 6224 1.1 yamaguch 6225 1.17 yamaguch isc = &sc->sc_stats_counters; 6226 1.17 yamaguch evcnt_detach(&isc->isc_crc_errors); 6227 1.17 yamaguch evcnt_detach(&isc->isc_illegal_bytes); 6228 1.17 yamaguch evcnt_detach(&isc->isc_mac_local_faults); 6229 1.17 yamaguch evcnt_detach(&isc->isc_mac_remote_faults); 6230 1.17 yamaguch evcnt_detach(&isc->isc_link_xon_rx); 6231 1.17 yamaguch evcnt_detach(&isc->isc_link_xon_tx); 6232 1.17 yamaguch evcnt_detach(&isc->isc_link_xoff_rx); 6233 1.17 yamaguch evcnt_detach(&isc->isc_link_xoff_tx); 6234 1.17 yamaguch evcnt_detach(&isc->isc_rx_fragments); 6235 1.17 yamaguch evcnt_detach(&isc->isc_rx_jabber); 6236 1.17 yamaguch evcnt_detach(&isc->isc_rx_bytes); 6237 1.17 yamaguch evcnt_detach(&isc->isc_rx_discards); 6238 1.17 yamaguch evcnt_detach(&isc->isc_rx_unicast); 6239 1.17 yamaguch evcnt_detach(&isc->isc_rx_multicast); 6240 1.17 yamaguch evcnt_detach(&isc->isc_rx_broadcast); 6241 1.17 yamaguch evcnt_detach(&isc->isc_rx_size_64); 6242 1.17 yamaguch evcnt_detach(&isc->isc_rx_size_127); 6243 1.17 yamaguch evcnt_detach(&isc->isc_rx_size_255); 6244 1.17 yamaguch evcnt_detach(&isc->isc_rx_size_511); 6245 1.17 yamaguch evcnt_detach(&isc->isc_rx_size_1023); 6246 1.17 yamaguch evcnt_detach(&isc->isc_rx_size_1522); 6247 1.17 yamaguch evcnt_detach(&isc->isc_rx_size_big); 6248 1.17 yamaguch evcnt_detach(&isc->isc_rx_undersize); 6249 1.17 yamaguch evcnt_detach(&isc->isc_rx_oversize); 6250 1.17 yamaguch evcnt_detach(&isc->isc_tx_bytes); 6251 1.17 yamaguch evcnt_detach(&isc->isc_tx_dropped_link_down); 6252 1.17 yamaguch evcnt_detach(&isc->isc_tx_unicast); 6253 1.17 yamaguch evcnt_detach(&isc->isc_tx_multicast); 6254 1.17 yamaguch evcnt_detach(&isc->isc_tx_broadcast); 6255 1.17 yamaguch evcnt_detach(&isc->isc_tx_size_64); 6256 1.17 yamaguch evcnt_detach(&isc->isc_tx_size_127); 6257 1.17 yamaguch evcnt_detach(&isc->isc_tx_size_255); 6258 1.17 yamaguch evcnt_detach(&isc->isc_tx_size_511); 6259 1.17 yamaguch evcnt_detach(&isc->isc_tx_size_1023); 6260 1.17 yamaguch evcnt_detach(&isc->isc_tx_size_1522); 6261 1.17 yamaguch evcnt_detach(&isc->isc_tx_size_big); 6262 1.18 yamaguch evcnt_detach(&isc->isc_vsi_rx_discards); 6263 1.18 yamaguch evcnt_detach(&isc->isc_vsi_rx_bytes); 6264 1.18 yamaguch evcnt_detach(&isc->isc_vsi_rx_unicast); 6265 1.18 yamaguch evcnt_detach(&isc->isc_vsi_rx_multicast); 6266 1.18 yamaguch evcnt_detach(&isc->isc_vsi_rx_broadcast); 6267 1.18 yamaguch evcnt_detach(&isc->isc_vsi_tx_errors); 6268 1.18 yamaguch evcnt_detach(&isc->isc_vsi_tx_bytes); 6269 1.18 yamaguch evcnt_detach(&isc->isc_vsi_tx_unicast); 6270 1.18 yamaguch evcnt_detach(&isc->isc_vsi_tx_multicast); 6271 1.18 yamaguch evcnt_detach(&isc->isc_vsi_tx_broadcast); 6272 1.17 yamaguch 6273 1.1 yamaguch evcnt_detach(&sc->sc_event_atq); 6274 1.1 yamaguch evcnt_detach(&sc->sc_event_link); 6275 1.1 yamaguch evcnt_detach(&sc->sc_event_ecc_err); 6276 1.1 yamaguch evcnt_detach(&sc->sc_event_pci_exception); 6277 1.1 yamaguch evcnt_detach(&sc->sc_event_crit_err); 6278 1.17 yamaguch 6279 1.17 yamaguch callout_destroy(&sc->sc_stats_callout); 6280 1.17 yamaguch } 6281 1.17 yamaguch 6282 1.17 yamaguch static void 6283 1.17 yamaguch ixl_stats_callout(void *xsc) 6284 1.17 yamaguch { 6285 1.17 yamaguch struct ixl_softc *sc = xsc; 6286 1.17 yamaguch 6287 1.17 yamaguch ixl_work_add(sc->sc_workq, &sc->sc_stats_task); 6288 1.17 yamaguch callout_schedule(&sc->sc_stats_callout, mstohz(sc->sc_stats_intval)); 6289 1.17 yamaguch } 6290 1.17 yamaguch 6291 1.17 yamaguch static uint64_t 6292 1.17 yamaguch ixl_stat_delta(struct ixl_softc *sc, uint32_t reg_hi, uint32_t reg_lo, 6293 1.17 yamaguch uint64_t *offset, bool has_offset) 6294 1.17 yamaguch { 6295 1.17 yamaguch uint64_t value, delta; 6296 1.17 yamaguch int bitwidth; 6297 1.17 yamaguch 6298 1.17 yamaguch bitwidth = reg_hi == 0 ? 32 : 48; 6299 1.17 yamaguch 6300 1.17 yamaguch value = ixl_rd(sc, reg_lo); 6301 1.17 yamaguch 6302 1.17 yamaguch if (bitwidth > 32) { 6303 1.17 yamaguch value |= ((uint64_t)ixl_rd(sc, reg_hi) << 32); 6304 1.17 yamaguch } 6305 1.17 yamaguch 6306 1.17 yamaguch if (__predict_true(has_offset)) { 6307 1.17 yamaguch delta = value; 6308 1.17 yamaguch if (value < *offset) 6309 1.17 yamaguch delta += ((uint64_t)1 << bitwidth); 6310 1.17 yamaguch delta -= *offset; 6311 1.17 yamaguch } else { 6312 1.17 yamaguch delta = 0; 6313 1.17 yamaguch } 6314 1.17 yamaguch atomic_swap_64(offset, value); 6315 1.17 yamaguch 6316 1.17 yamaguch return delta; 6317 1.17 yamaguch } 6318 1.17 yamaguch 6319 1.17 yamaguch static void 6320 1.17 yamaguch ixl_stats_update(void *xsc) 6321 1.17 yamaguch { 6322 1.17 yamaguch struct ixl_softc *sc = xsc; 6323 1.17 yamaguch struct ixl_stats_counters *isc; 6324 1.17 yamaguch uint64_t delta; 6325 1.17 yamaguch 6326 1.17 yamaguch isc = &sc->sc_stats_counters; 6327 1.17 yamaguch 6328 1.17 yamaguch /* errors */ 6329 1.17 yamaguch delta = ixl_stat_delta(sc, 6330 1.17 yamaguch 0, I40E_GLPRT_CRCERRS(sc->sc_port), 6331 1.17 yamaguch &isc->isc_crc_errors_offset, isc->isc_has_offset); 6332 1.17 yamaguch atomic_add_64(&isc->isc_crc_errors.ev_count, delta); 6333 1.17 yamaguch 6334 1.17 yamaguch delta = ixl_stat_delta(sc, 6335 1.17 yamaguch 0, I40E_GLPRT_ILLERRC(sc->sc_port), 6336 1.17 yamaguch &isc->isc_illegal_bytes_offset, isc->isc_has_offset); 6337 1.17 yamaguch atomic_add_64(&isc->isc_illegal_bytes.ev_count, delta); 6338 1.17 yamaguch 6339 1.17 yamaguch /* rx */ 6340 1.17 yamaguch delta = ixl_stat_delta(sc, 6341 1.17 yamaguch I40E_GLPRT_GORCH(sc->sc_port), I40E_GLPRT_GORCL(sc->sc_port), 6342 1.17 yamaguch &isc->isc_rx_bytes_offset, isc->isc_has_offset); 6343 1.17 yamaguch atomic_add_64(&isc->isc_rx_bytes.ev_count, delta); 6344 1.17 yamaguch 6345 1.17 yamaguch delta = ixl_stat_delta(sc, 6346 1.17 yamaguch 0, I40E_GLPRT_RDPC(sc->sc_port), 6347 1.17 yamaguch &isc->isc_rx_discards_offset, isc->isc_has_offset); 6348 1.17 yamaguch atomic_add_64(&isc->isc_rx_discards.ev_count, delta); 6349 1.17 yamaguch 6350 1.17 yamaguch delta = ixl_stat_delta(sc, 6351 1.17 yamaguch I40E_GLPRT_UPRCH(sc->sc_port), I40E_GLPRT_UPRCL(sc->sc_port), 6352 1.17 yamaguch &isc->isc_rx_unicast_offset, isc->isc_has_offset); 6353 1.17 yamaguch atomic_add_64(&isc->isc_rx_unicast.ev_count, delta); 6354 1.17 yamaguch 6355 1.17 yamaguch delta = ixl_stat_delta(sc, 6356 1.17 yamaguch I40E_GLPRT_MPRCH(sc->sc_port), I40E_GLPRT_MPRCL(sc->sc_port), 6357 1.17 yamaguch &isc->isc_rx_multicast_offset, isc->isc_has_offset); 6358 1.17 yamaguch atomic_add_64(&isc->isc_rx_multicast.ev_count, delta); 6359 1.17 yamaguch 6360 1.17 yamaguch delta = ixl_stat_delta(sc, 6361 1.17 yamaguch I40E_GLPRT_BPRCH(sc->sc_port), I40E_GLPRT_BPRCL(sc->sc_port), 6362 1.17 yamaguch &isc->isc_rx_broadcast_offset, isc->isc_has_offset); 6363 1.17 yamaguch atomic_add_64(&isc->isc_rx_broadcast.ev_count, delta); 6364 1.17 yamaguch 6365 1.17 yamaguch /* Packet size stats rx */ 6366 1.17 yamaguch delta = ixl_stat_delta(sc, 6367 1.17 yamaguch I40E_GLPRT_PRC64H(sc->sc_port), I40E_GLPRT_PRC64L(sc->sc_port), 6368 1.17 yamaguch &isc->isc_rx_size_64_offset, isc->isc_has_offset); 6369 1.17 yamaguch atomic_add_64(&isc->isc_rx_size_64.ev_count, delta); 6370 1.17 yamaguch 6371 1.17 yamaguch delta = ixl_stat_delta(sc, 6372 1.17 yamaguch I40E_GLPRT_PRC127H(sc->sc_port), I40E_GLPRT_PRC127L(sc->sc_port), 6373 1.17 yamaguch &isc->isc_rx_size_127_offset, isc->isc_has_offset); 6374 1.17 yamaguch atomic_add_64(&isc->isc_rx_size_127.ev_count, delta); 6375 1.17 yamaguch 6376 1.17 yamaguch delta = ixl_stat_delta(sc, 6377 1.17 yamaguch I40E_GLPRT_PRC255H(sc->sc_port), I40E_GLPRT_PRC255L(sc->sc_port), 6378 1.17 yamaguch &isc->isc_rx_size_255_offset, isc->isc_has_offset); 6379 1.17 yamaguch atomic_add_64(&isc->isc_rx_size_255.ev_count, delta); 6380 1.17 yamaguch 6381 1.17 yamaguch delta = ixl_stat_delta(sc, 6382 1.17 yamaguch I40E_GLPRT_PRC511H(sc->sc_port), I40E_GLPRT_PRC511L(sc->sc_port), 6383 1.17 yamaguch &isc->isc_rx_size_511_offset, isc->isc_has_offset); 6384 1.17 yamaguch atomic_add_64(&isc->isc_rx_size_511.ev_count, delta); 6385 1.17 yamaguch 6386 1.17 yamaguch delta = ixl_stat_delta(sc, 6387 1.17 yamaguch I40E_GLPRT_PRC1023H(sc->sc_port), I40E_GLPRT_PRC1023L(sc->sc_port), 6388 1.17 yamaguch &isc->isc_rx_size_1023_offset, isc->isc_has_offset); 6389 1.17 yamaguch atomic_add_64(&isc->isc_rx_size_1023.ev_count, delta); 6390 1.17 yamaguch 6391 1.17 yamaguch delta = ixl_stat_delta(sc, 6392 1.17 yamaguch I40E_GLPRT_PRC1522H(sc->sc_port), I40E_GLPRT_PRC1522L(sc->sc_port), 6393 1.17 yamaguch &isc->isc_rx_size_1522_offset, isc->isc_has_offset); 6394 1.17 yamaguch atomic_add_64(&isc->isc_rx_size_1522.ev_count, delta); 6395 1.17 yamaguch 6396 1.17 yamaguch delta = ixl_stat_delta(sc, 6397 1.17 yamaguch I40E_GLPRT_PRC9522H(sc->sc_port), I40E_GLPRT_PRC9522L(sc->sc_port), 6398 1.17 yamaguch &isc->isc_rx_size_big_offset, isc->isc_has_offset); 6399 1.17 yamaguch atomic_add_64(&isc->isc_rx_size_big.ev_count, delta); 6400 1.17 yamaguch 6401 1.17 yamaguch delta = ixl_stat_delta(sc, 6402 1.17 yamaguch 0, I40E_GLPRT_RUC(sc->sc_port), 6403 1.17 yamaguch &isc->isc_rx_undersize_offset, isc->isc_has_offset); 6404 1.17 yamaguch atomic_add_64(&isc->isc_rx_undersize.ev_count, delta); 6405 1.17 yamaguch 6406 1.17 yamaguch delta = ixl_stat_delta(sc, 6407 1.17 yamaguch 0, I40E_GLPRT_ROC(sc->sc_port), 6408 1.17 yamaguch &isc->isc_rx_oversize_offset, isc->isc_has_offset); 6409 1.17 yamaguch atomic_add_64(&isc->isc_rx_oversize.ev_count, delta); 6410 1.17 yamaguch 6411 1.17 yamaguch /* tx */ 6412 1.17 yamaguch delta = ixl_stat_delta(sc, 6413 1.17 yamaguch I40E_GLPRT_GOTCH(sc->sc_port), I40E_GLPRT_GOTCL(sc->sc_port), 6414 1.17 yamaguch &isc->isc_tx_bytes_offset, isc->isc_has_offset); 6415 1.17 yamaguch atomic_add_64(&isc->isc_tx_bytes.ev_count, delta); 6416 1.17 yamaguch 6417 1.17 yamaguch delta = ixl_stat_delta(sc, 6418 1.17 yamaguch 0, I40E_GLPRT_TDOLD(sc->sc_port), 6419 1.17 yamaguch &isc->isc_tx_dropped_link_down_offset, isc->isc_has_offset); 6420 1.17 yamaguch atomic_add_64(&isc->isc_tx_dropped_link_down.ev_count, delta); 6421 1.17 yamaguch 6422 1.17 yamaguch delta = ixl_stat_delta(sc, 6423 1.17 yamaguch I40E_GLPRT_UPTCH(sc->sc_port), I40E_GLPRT_UPTCL(sc->sc_port), 6424 1.17 yamaguch &isc->isc_tx_unicast_offset, isc->isc_has_offset); 6425 1.17 yamaguch atomic_add_64(&isc->isc_tx_unicast.ev_count, delta); 6426 1.17 yamaguch 6427 1.17 yamaguch delta = ixl_stat_delta(sc, 6428 1.17 yamaguch I40E_GLPRT_MPTCH(sc->sc_port), I40E_GLPRT_MPTCL(sc->sc_port), 6429 1.17 yamaguch &isc->isc_tx_multicast_offset, isc->isc_has_offset); 6430 1.17 yamaguch atomic_add_64(&isc->isc_tx_multicast.ev_count, delta); 6431 1.17 yamaguch 6432 1.17 yamaguch delta = ixl_stat_delta(sc, 6433 1.17 yamaguch I40E_GLPRT_BPTCH(sc->sc_port), I40E_GLPRT_BPTCL(sc->sc_port), 6434 1.17 yamaguch &isc->isc_tx_broadcast_offset, isc->isc_has_offset); 6435 1.17 yamaguch atomic_add_64(&isc->isc_tx_broadcast.ev_count, delta); 6436 1.17 yamaguch 6437 1.17 yamaguch /* Packet size stats tx */ 6438 1.17 yamaguch delta = ixl_stat_delta(sc, 6439 1.17 yamaguch I40E_GLPRT_PTC64L(sc->sc_port), I40E_GLPRT_PTC64L(sc->sc_port), 6440 1.17 yamaguch &isc->isc_tx_size_64_offset, isc->isc_has_offset); 6441 1.17 yamaguch atomic_add_64(&isc->isc_tx_size_64.ev_count, delta); 6442 1.17 yamaguch 6443 1.17 yamaguch delta = ixl_stat_delta(sc, 6444 1.17 yamaguch I40E_GLPRT_PTC127H(sc->sc_port), I40E_GLPRT_PTC127L(sc->sc_port), 6445 1.17 yamaguch &isc->isc_tx_size_127_offset, isc->isc_has_offset); 6446 1.17 yamaguch atomic_add_64(&isc->isc_tx_size_127.ev_count, delta); 6447 1.17 yamaguch 6448 1.17 yamaguch delta = ixl_stat_delta(sc, 6449 1.17 yamaguch I40E_GLPRT_PTC255H(sc->sc_port), I40E_GLPRT_PTC255L(sc->sc_port), 6450 1.17 yamaguch &isc->isc_tx_size_255_offset, isc->isc_has_offset); 6451 1.17 yamaguch atomic_add_64(&isc->isc_tx_size_255.ev_count, delta); 6452 1.17 yamaguch 6453 1.17 yamaguch delta = ixl_stat_delta(sc, 6454 1.17 yamaguch I40E_GLPRT_PTC511H(sc->sc_port), I40E_GLPRT_PTC511L(sc->sc_port), 6455 1.17 yamaguch &isc->isc_tx_size_511_offset, isc->isc_has_offset); 6456 1.17 yamaguch atomic_add_64(&isc->isc_tx_size_511.ev_count, delta); 6457 1.17 yamaguch 6458 1.17 yamaguch delta = ixl_stat_delta(sc, 6459 1.17 yamaguch I40E_GLPRT_PTC1023H(sc->sc_port), I40E_GLPRT_PTC1023L(sc->sc_port), 6460 1.17 yamaguch &isc->isc_tx_size_1023_offset, isc->isc_has_offset); 6461 1.17 yamaguch atomic_add_64(&isc->isc_tx_size_1023.ev_count, delta); 6462 1.17 yamaguch 6463 1.17 yamaguch delta = ixl_stat_delta(sc, 6464 1.17 yamaguch I40E_GLPRT_PTC1522H(sc->sc_port), I40E_GLPRT_PTC1522L(sc->sc_port), 6465 1.17 yamaguch &isc->isc_tx_size_1522_offset, isc->isc_has_offset); 6466 1.17 yamaguch atomic_add_64(&isc->isc_tx_size_1522.ev_count, delta); 6467 1.17 yamaguch 6468 1.17 yamaguch delta = ixl_stat_delta(sc, 6469 1.17 yamaguch I40E_GLPRT_PTC9522H(sc->sc_port), I40E_GLPRT_PTC9522L(sc->sc_port), 6470 1.17 yamaguch &isc->isc_tx_size_big_offset, isc->isc_has_offset); 6471 1.17 yamaguch atomic_add_64(&isc->isc_tx_size_big.ev_count, delta); 6472 1.17 yamaguch 6473 1.17 yamaguch /* mac faults */ 6474 1.17 yamaguch delta = ixl_stat_delta(sc, 6475 1.17 yamaguch 0, I40E_GLPRT_MLFC(sc->sc_port), 6476 1.17 yamaguch &isc->isc_mac_local_faults_offset, isc->isc_has_offset); 6477 1.17 yamaguch atomic_add_64(&isc->isc_mac_local_faults.ev_count, delta); 6478 1.17 yamaguch 6479 1.17 yamaguch delta = ixl_stat_delta(sc, 6480 1.17 yamaguch 0, I40E_GLPRT_MRFC(sc->sc_port), 6481 1.17 yamaguch &isc->isc_mac_remote_faults_offset, isc->isc_has_offset); 6482 1.17 yamaguch atomic_add_64(&isc->isc_mac_remote_faults.ev_count, delta); 6483 1.17 yamaguch 6484 1.17 yamaguch /* Flow control (LFC) stats */ 6485 1.17 yamaguch delta = ixl_stat_delta(sc, 6486 1.17 yamaguch 0, I40E_GLPRT_LXONRXC(sc->sc_port), 6487 1.17 yamaguch &isc->isc_link_xon_rx_offset, isc->isc_has_offset); 6488 1.17 yamaguch atomic_add_64(&isc->isc_link_xon_rx.ev_count, delta); 6489 1.17 yamaguch 6490 1.17 yamaguch delta = ixl_stat_delta(sc, 6491 1.17 yamaguch 0, I40E_GLPRT_LXONTXC(sc->sc_port), 6492 1.17 yamaguch &isc->isc_link_xon_tx_offset, isc->isc_has_offset); 6493 1.17 yamaguch atomic_add_64(&isc->isc_link_xon_tx.ev_count, delta); 6494 1.17 yamaguch 6495 1.17 yamaguch delta = ixl_stat_delta(sc, 6496 1.17 yamaguch 0, I40E_GLPRT_LXOFFRXC(sc->sc_port), 6497 1.17 yamaguch &isc->isc_link_xoff_rx_offset, isc->isc_has_offset); 6498 1.17 yamaguch atomic_add_64(&isc->isc_link_xoff_rx.ev_count, delta); 6499 1.17 yamaguch 6500 1.17 yamaguch delta = ixl_stat_delta(sc, 6501 1.17 yamaguch 0, I40E_GLPRT_LXOFFTXC(sc->sc_port), 6502 1.17 yamaguch &isc->isc_link_xoff_tx_offset, isc->isc_has_offset); 6503 1.17 yamaguch atomic_add_64(&isc->isc_link_xoff_tx.ev_count, delta); 6504 1.17 yamaguch 6505 1.17 yamaguch /* fragments */ 6506 1.17 yamaguch delta = ixl_stat_delta(sc, 6507 1.17 yamaguch 0, I40E_GLPRT_RFC(sc->sc_port), 6508 1.17 yamaguch &isc->isc_rx_fragments_offset, isc->isc_has_offset); 6509 1.17 yamaguch atomic_add_64(&isc->isc_rx_fragments.ev_count, delta); 6510 1.17 yamaguch 6511 1.17 yamaguch delta = ixl_stat_delta(sc, 6512 1.17 yamaguch 0, I40E_GLPRT_RJC(sc->sc_port), 6513 1.17 yamaguch &isc->isc_rx_jabber_offset, isc->isc_has_offset); 6514 1.17 yamaguch atomic_add_64(&isc->isc_rx_jabber.ev_count, delta); 6515 1.18 yamaguch 6516 1.18 yamaguch /* VSI rx counters */ 6517 1.18 yamaguch delta = ixl_stat_delta(sc, 6518 1.18 yamaguch 0, I40E_GLV_RDPC(sc->sc_vsi_stat_counter_idx), 6519 1.18 yamaguch &isc->isc_vsi_rx_discards_offset, isc->isc_has_offset); 6520 1.18 yamaguch atomic_add_64(&isc->isc_vsi_rx_discards.ev_count, delta); 6521 1.18 yamaguch 6522 1.18 yamaguch delta = ixl_stat_delta(sc, 6523 1.18 yamaguch I40E_GLV_GORCH(sc->sc_vsi_stat_counter_idx), 6524 1.18 yamaguch I40E_GLV_GORCL(sc->sc_vsi_stat_counter_idx), 6525 1.18 yamaguch &isc->isc_vsi_rx_bytes_offset, isc->isc_has_offset); 6526 1.18 yamaguch atomic_add_64(&isc->isc_vsi_rx_bytes.ev_count, delta); 6527 1.18 yamaguch 6528 1.18 yamaguch delta = ixl_stat_delta(sc, 6529 1.18 yamaguch I40E_GLV_UPRCH(sc->sc_vsi_stat_counter_idx), 6530 1.18 yamaguch I40E_GLV_UPRCL(sc->sc_vsi_stat_counter_idx), 6531 1.18 yamaguch &isc->isc_vsi_rx_unicast_offset, isc->isc_has_offset); 6532 1.18 yamaguch atomic_add_64(&isc->isc_vsi_rx_unicast.ev_count, delta); 6533 1.18 yamaguch 6534 1.18 yamaguch delta = ixl_stat_delta(sc, 6535 1.18 yamaguch I40E_GLV_MPRCH(sc->sc_vsi_stat_counter_idx), 6536 1.18 yamaguch I40E_GLV_MPRCL(sc->sc_vsi_stat_counter_idx), 6537 1.18 yamaguch &isc->isc_vsi_rx_multicast_offset, isc->isc_has_offset); 6538 1.18 yamaguch atomic_add_64(&isc->isc_vsi_rx_multicast.ev_count, delta); 6539 1.18 yamaguch 6540 1.18 yamaguch delta = ixl_stat_delta(sc, 6541 1.18 yamaguch I40E_GLV_BPRCH(sc->sc_vsi_stat_counter_idx), 6542 1.18 yamaguch I40E_GLV_BPRCL(sc->sc_vsi_stat_counter_idx), 6543 1.18 yamaguch &isc->isc_vsi_rx_broadcast_offset, isc->isc_has_offset); 6544 1.18 yamaguch atomic_add_64(&isc->isc_vsi_rx_broadcast.ev_count, delta); 6545 1.18 yamaguch 6546 1.18 yamaguch /* VSI tx counters */ 6547 1.18 yamaguch delta = ixl_stat_delta(sc, 6548 1.18 yamaguch 0, I40E_GLV_TEPC(sc->sc_vsi_stat_counter_idx), 6549 1.18 yamaguch &isc->isc_vsi_tx_errors_offset, isc->isc_has_offset); 6550 1.18 yamaguch atomic_add_64(&isc->isc_vsi_tx_errors.ev_count, delta); 6551 1.18 yamaguch 6552 1.18 yamaguch delta = ixl_stat_delta(sc, 6553 1.18 yamaguch I40E_GLV_GOTCH(sc->sc_vsi_stat_counter_idx), 6554 1.18 yamaguch I40E_GLV_GOTCL(sc->sc_vsi_stat_counter_idx), 6555 1.18 yamaguch &isc->isc_vsi_tx_bytes_offset, isc->isc_has_offset); 6556 1.18 yamaguch atomic_add_64(&isc->isc_vsi_tx_bytes.ev_count, delta); 6557 1.18 yamaguch 6558 1.18 yamaguch delta = ixl_stat_delta(sc, 6559 1.18 yamaguch I40E_GLV_UPTCH(sc->sc_vsi_stat_counter_idx), 6560 1.18 yamaguch I40E_GLV_UPTCL(sc->sc_vsi_stat_counter_idx), 6561 1.18 yamaguch &isc->isc_vsi_tx_unicast_offset, isc->isc_has_offset); 6562 1.18 yamaguch atomic_add_64(&isc->isc_vsi_tx_unicast.ev_count, delta); 6563 1.18 yamaguch 6564 1.18 yamaguch delta = ixl_stat_delta(sc, 6565 1.18 yamaguch I40E_GLV_MPTCH(sc->sc_vsi_stat_counter_idx), 6566 1.18 yamaguch I40E_GLV_MPTCL(sc->sc_vsi_stat_counter_idx), 6567 1.18 yamaguch &isc->isc_vsi_tx_multicast_offset, isc->isc_has_offset); 6568 1.18 yamaguch atomic_add_64(&isc->isc_vsi_tx_multicast.ev_count, delta); 6569 1.18 yamaguch 6570 1.18 yamaguch delta = ixl_stat_delta(sc, 6571 1.18 yamaguch I40E_GLV_BPTCH(sc->sc_vsi_stat_counter_idx), 6572 1.18 yamaguch I40E_GLV_BPTCL(sc->sc_vsi_stat_counter_idx), 6573 1.18 yamaguch &isc->isc_vsi_tx_broadcast_offset, isc->isc_has_offset); 6574 1.18 yamaguch atomic_add_64(&isc->isc_vsi_tx_broadcast.ev_count, delta); 6575 1.1 yamaguch } 6576 1.1 yamaguch 6577 1.1 yamaguch static int 6578 1.1 yamaguch ixl_setup_sysctls(struct ixl_softc *sc) 6579 1.1 yamaguch { 6580 1.1 yamaguch const char *devname; 6581 1.1 yamaguch struct sysctllog **log; 6582 1.1 yamaguch const struct sysctlnode *rnode, *rxnode, *txnode; 6583 1.1 yamaguch int error; 6584 1.1 yamaguch 6585 1.1 yamaguch log = &sc->sc_sysctllog; 6586 1.1 yamaguch devname = device_xname(sc->sc_dev); 6587 1.1 yamaguch 6588 1.1 yamaguch error = sysctl_createv(log, 0, NULL, &rnode, 6589 1.1 yamaguch 0, CTLTYPE_NODE, devname, 6590 1.1 yamaguch SYSCTL_DESCR("ixl information and settings"), 6591 1.1 yamaguch NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 6592 1.1 yamaguch if (error) 6593 1.1 yamaguch goto out; 6594 1.1 yamaguch 6595 1.1 yamaguch error = sysctl_createv(log, 0, &rnode, NULL, 6596 1.1 yamaguch CTLFLAG_READWRITE, CTLTYPE_BOOL, "txrx_workqueue", 6597 1.1 yamaguch SYSCTL_DESCR("Use workqueue for packet processing"), 6598 1.1 yamaguch NULL, 0, &sc->sc_txrx_workqueue, 0, CTL_CREATE, CTL_EOL); 6599 1.1 yamaguch if (error) 6600 1.1 yamaguch goto out; 6601 1.1 yamaguch 6602 1.17 yamaguch error = sysctl_createv(log, 0, &rnode, NULL, 6603 1.17 yamaguch CTLFLAG_READONLY, CTLTYPE_INT, "stats_interval", 6604 1.17 yamaguch SYSCTL_DESCR("Statistics collection interval in milliseconds"), 6605 1.17 yamaguch NULL, 0, &sc->sc_stats_intval, 0, CTL_CREATE, CTL_EOL); 6606 1.17 yamaguch 6607 1.1 yamaguch error = sysctl_createv(log, 0, &rnode, &rxnode, 6608 1.1 yamaguch 0, CTLTYPE_NODE, "rx", 6609 1.1 yamaguch SYSCTL_DESCR("ixl information and settings for Rx"), 6610 1.1 yamaguch NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 6611 1.1 yamaguch if (error) 6612 1.1 yamaguch goto out; 6613 1.1 yamaguch 6614 1.1 yamaguch error = sysctl_createv(log, 0, &rxnode, NULL, 6615 1.69 yamaguch CTLFLAG_READWRITE, CTLTYPE_INT, "itr", 6616 1.69 yamaguch SYSCTL_DESCR("Interrupt Throttling"), 6617 1.69 yamaguch ixl_sysctl_itr_handler, 0, 6618 1.69 yamaguch (void *)sc, 0, CTL_CREATE, CTL_EOL); 6619 1.69 yamaguch if (error) 6620 1.69 yamaguch goto out; 6621 1.69 yamaguch 6622 1.69 yamaguch error = sysctl_createv(log, 0, &rxnode, NULL, 6623 1.74 yamaguch CTLFLAG_READONLY, CTLTYPE_INT, "descriptor_num", 6624 1.70 yamaguch SYSCTL_DESCR("the number of rx descriptors"), 6625 1.74 yamaguch NULL, 0, &sc->sc_rx_ring_ndescs, 0, CTL_CREATE, CTL_EOL); 6626 1.70 yamaguch if (error) 6627 1.70 yamaguch goto out; 6628 1.70 yamaguch 6629 1.70 yamaguch error = sysctl_createv(log, 0, &rxnode, NULL, 6630 1.1 yamaguch CTLFLAG_READWRITE, CTLTYPE_INT, "intr_process_limit", 6631 1.1 yamaguch SYSCTL_DESCR("max number of Rx packets" 6632 1.1 yamaguch " to process for interrupt processing"), 6633 1.1 yamaguch NULL, 0, &sc->sc_rx_intr_process_limit, 0, CTL_CREATE, CTL_EOL); 6634 1.1 yamaguch if (error) 6635 1.1 yamaguch goto out; 6636 1.1 yamaguch 6637 1.1 yamaguch error = sysctl_createv(log, 0, &rxnode, NULL, 6638 1.1 yamaguch CTLFLAG_READWRITE, CTLTYPE_INT, "process_limit", 6639 1.1 yamaguch SYSCTL_DESCR("max number of Rx packets" 6640 1.1 yamaguch " to process for deferred processing"), 6641 1.1 yamaguch NULL, 0, &sc->sc_rx_process_limit, 0, CTL_CREATE, CTL_EOL); 6642 1.1 yamaguch if (error) 6643 1.1 yamaguch goto out; 6644 1.1 yamaguch 6645 1.1 yamaguch error = sysctl_createv(log, 0, &rnode, &txnode, 6646 1.1 yamaguch 0, CTLTYPE_NODE, "tx", 6647 1.1 yamaguch SYSCTL_DESCR("ixl information and settings for Tx"), 6648 1.1 yamaguch NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 6649 1.1 yamaguch if (error) 6650 1.1 yamaguch goto out; 6651 1.1 yamaguch 6652 1.1 yamaguch error = sysctl_createv(log, 0, &txnode, NULL, 6653 1.69 yamaguch CTLFLAG_READWRITE, CTLTYPE_INT, "itr", 6654 1.69 yamaguch SYSCTL_DESCR("Interrupt Throttling"), 6655 1.69 yamaguch ixl_sysctl_itr_handler, 0, 6656 1.69 yamaguch (void *)sc, 0, CTL_CREATE, CTL_EOL); 6657 1.69 yamaguch if (error) 6658 1.69 yamaguch goto out; 6659 1.69 yamaguch 6660 1.69 yamaguch error = sysctl_createv(log, 0, &txnode, NULL, 6661 1.74 yamaguch CTLFLAG_READONLY, CTLTYPE_INT, "descriptor_num", 6662 1.70 yamaguch SYSCTL_DESCR("the number of tx descriptors"), 6663 1.74 yamaguch NULL, 0, &sc->sc_tx_ring_ndescs, 0, CTL_CREATE, CTL_EOL); 6664 1.70 yamaguch if (error) 6665 1.70 yamaguch goto out; 6666 1.70 yamaguch 6667 1.70 yamaguch error = sysctl_createv(log, 0, &txnode, NULL, 6668 1.1 yamaguch CTLFLAG_READWRITE, CTLTYPE_INT, "intr_process_limit", 6669 1.1 yamaguch SYSCTL_DESCR("max number of Tx packets" 6670 1.1 yamaguch " to process for interrupt processing"), 6671 1.1 yamaguch NULL, 0, &sc->sc_tx_intr_process_limit, 0, CTL_CREATE, CTL_EOL); 6672 1.1 yamaguch if (error) 6673 1.1 yamaguch goto out; 6674 1.1 yamaguch 6675 1.1 yamaguch error = sysctl_createv(log, 0, &txnode, NULL, 6676 1.1 yamaguch CTLFLAG_READWRITE, CTLTYPE_INT, "process_limit", 6677 1.1 yamaguch SYSCTL_DESCR("max number of Tx packets" 6678 1.1 yamaguch " to process for deferred processing"), 6679 1.1 yamaguch NULL, 0, &sc->sc_tx_process_limit, 0, CTL_CREATE, CTL_EOL); 6680 1.1 yamaguch if (error) 6681 1.1 yamaguch goto out; 6682 1.1 yamaguch 6683 1.1 yamaguch out: 6684 1.1 yamaguch if (error) { 6685 1.1 yamaguch aprint_error_dev(sc->sc_dev, 6686 1.1 yamaguch "unable to create sysctl node\n"); 6687 1.1 yamaguch sysctl_teardown(log); 6688 1.1 yamaguch } 6689 1.1 yamaguch 6690 1.1 yamaguch return error; 6691 1.1 yamaguch } 6692 1.1 yamaguch 6693 1.1 yamaguch static void 6694 1.1 yamaguch ixl_teardown_sysctls(struct ixl_softc *sc) 6695 1.1 yamaguch { 6696 1.1 yamaguch 6697 1.1 yamaguch sysctl_teardown(&sc->sc_sysctllog); 6698 1.1 yamaguch } 6699 1.1 yamaguch 6700 1.69 yamaguch static bool 6701 1.69 yamaguch ixl_sysctlnode_is_rx(struct sysctlnode *node) 6702 1.69 yamaguch { 6703 1.69 yamaguch 6704 1.69 yamaguch if (strstr(node->sysctl_parent->sysctl_name, "rx") != NULL) 6705 1.69 yamaguch return true; 6706 1.69 yamaguch 6707 1.69 yamaguch return false; 6708 1.69 yamaguch } 6709 1.69 yamaguch 6710 1.69 yamaguch static int 6711 1.69 yamaguch ixl_sysctl_itr_handler(SYSCTLFN_ARGS) 6712 1.69 yamaguch { 6713 1.69 yamaguch struct sysctlnode node = *rnode; 6714 1.69 yamaguch struct ixl_softc *sc = (struct ixl_softc *)node.sysctl_data; 6715 1.69 yamaguch struct ifnet *ifp = &sc->sc_ec.ec_if; 6716 1.69 yamaguch uint32_t newitr, *itrptr; 6717 1.69 yamaguch int error; 6718 1.69 yamaguch 6719 1.69 yamaguch if (ixl_sysctlnode_is_rx(&node)) { 6720 1.69 yamaguch itrptr = &sc->sc_itr_rx; 6721 1.69 yamaguch } else { 6722 1.69 yamaguch itrptr = &sc->sc_itr_tx; 6723 1.69 yamaguch } 6724 1.69 yamaguch 6725 1.69 yamaguch newitr = *itrptr; 6726 1.69 yamaguch node.sysctl_data = &newitr; 6727 1.69 yamaguch node.sysctl_size = sizeof(newitr); 6728 1.69 yamaguch 6729 1.69 yamaguch error = sysctl_lookup(SYSCTLFN_CALL(&node)); 6730 1.69 yamaguch 6731 1.69 yamaguch if (error || newp == NULL) 6732 1.69 yamaguch return error; 6733 1.69 yamaguch 6734 1.89 andvar /* ITRs are applied in ixl_init() for simple implementation */ 6735 1.69 yamaguch if (ISSET(ifp->if_flags, IFF_RUNNING)) 6736 1.69 yamaguch return EBUSY; 6737 1.69 yamaguch 6738 1.69 yamaguch if (newitr > 0x07ff) 6739 1.69 yamaguch return EINVAL; 6740 1.69 yamaguch 6741 1.69 yamaguch *itrptr = newitr; 6742 1.69 yamaguch 6743 1.69 yamaguch return 0; 6744 1.69 yamaguch } 6745 1.69 yamaguch 6746 1.1 yamaguch static struct workqueue * 6747 1.1 yamaguch ixl_workq_create(const char *name, pri_t prio, int ipl, int flags) 6748 1.1 yamaguch { 6749 1.1 yamaguch struct workqueue *wq; 6750 1.1 yamaguch int error; 6751 1.1 yamaguch 6752 1.1 yamaguch error = workqueue_create(&wq, name, ixl_workq_work, NULL, 6753 1.1 yamaguch prio, ipl, flags); 6754 1.1 yamaguch 6755 1.1 yamaguch if (error) 6756 1.1 yamaguch return NULL; 6757 1.1 yamaguch 6758 1.1 yamaguch return wq; 6759 1.1 yamaguch } 6760 1.1 yamaguch 6761 1.1 yamaguch static void 6762 1.1 yamaguch ixl_workq_destroy(struct workqueue *wq) 6763 1.1 yamaguch { 6764 1.1 yamaguch 6765 1.1 yamaguch workqueue_destroy(wq); 6766 1.1 yamaguch } 6767 1.1 yamaguch 6768 1.1 yamaguch static void 6769 1.1 yamaguch ixl_work_set(struct ixl_work *work, void (*func)(void *), void *arg) 6770 1.1 yamaguch { 6771 1.1 yamaguch 6772 1.1 yamaguch memset(work, 0, sizeof(*work)); 6773 1.1 yamaguch work->ixw_func = func; 6774 1.1 yamaguch work->ixw_arg = arg; 6775 1.1 yamaguch } 6776 1.1 yamaguch 6777 1.1 yamaguch static void 6778 1.1 yamaguch ixl_work_add(struct workqueue *wq, struct ixl_work *work) 6779 1.1 yamaguch { 6780 1.1 yamaguch if (atomic_cas_uint(&work->ixw_added, 0, 1) != 0) 6781 1.1 yamaguch return; 6782 1.1 yamaguch 6783 1.44 yamaguch kpreempt_disable(); 6784 1.1 yamaguch workqueue_enqueue(wq, &work->ixw_cookie, NULL); 6785 1.44 yamaguch kpreempt_enable(); 6786 1.1 yamaguch } 6787 1.1 yamaguch 6788 1.1 yamaguch static void 6789 1.1 yamaguch ixl_work_wait(struct workqueue *wq, struct ixl_work *work) 6790 1.1 yamaguch { 6791 1.1 yamaguch 6792 1.1 yamaguch workqueue_wait(wq, &work->ixw_cookie); 6793 1.1 yamaguch } 6794 1.1 yamaguch 6795 1.1 yamaguch static void 6796 1.1 yamaguch ixl_workq_work(struct work *wk, void *context) 6797 1.1 yamaguch { 6798 1.1 yamaguch struct ixl_work *work; 6799 1.1 yamaguch 6800 1.1 yamaguch work = container_of(wk, struct ixl_work, ixw_cookie); 6801 1.1 yamaguch 6802 1.1 yamaguch atomic_swap_uint(&work->ixw_added, 0); 6803 1.1 yamaguch work->ixw_func(work->ixw_arg); 6804 1.1 yamaguch } 6805 1.1 yamaguch 6806 1.1 yamaguch static int 6807 1.1 yamaguch ixl_rx_ctl_read(struct ixl_softc *sc, uint32_t reg, uint32_t *rv) 6808 1.1 yamaguch { 6809 1.1 yamaguch struct ixl_aq_desc iaq; 6810 1.1 yamaguch 6811 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 6812 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_RX_CTL_REG_READ); 6813 1.1 yamaguch iaq.iaq_param[1] = htole32(reg); 6814 1.1 yamaguch 6815 1.1 yamaguch if (ixl_atq_poll(sc, &iaq, 250) != 0) 6816 1.1 yamaguch return ETIMEDOUT; 6817 1.1 yamaguch 6818 1.1 yamaguch switch (htole16(iaq.iaq_retval)) { 6819 1.1 yamaguch case IXL_AQ_RC_OK: 6820 1.1 yamaguch /* success */ 6821 1.1 yamaguch break; 6822 1.1 yamaguch case IXL_AQ_RC_EACCES: 6823 1.1 yamaguch return EPERM; 6824 1.1 yamaguch case IXL_AQ_RC_EAGAIN: 6825 1.1 yamaguch return EAGAIN; 6826 1.1 yamaguch default: 6827 1.1 yamaguch return EIO; 6828 1.1 yamaguch } 6829 1.1 yamaguch 6830 1.1 yamaguch *rv = htole32(iaq.iaq_param[3]); 6831 1.1 yamaguch return 0; 6832 1.1 yamaguch } 6833 1.1 yamaguch 6834 1.1 yamaguch static uint32_t 6835 1.1 yamaguch ixl_rd_rx_csr(struct ixl_softc *sc, uint32_t reg) 6836 1.1 yamaguch { 6837 1.1 yamaguch uint32_t val; 6838 1.1 yamaguch int rv, retry, retry_limit; 6839 1.1 yamaguch 6840 1.25 yamaguch if (ISSET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_RXCTL)) { 6841 1.25 yamaguch retry_limit = 5; 6842 1.25 yamaguch } else { 6843 1.25 yamaguch retry_limit = 0; 6844 1.25 yamaguch } 6845 1.1 yamaguch 6846 1.1 yamaguch for (retry = 0; retry < retry_limit; retry++) { 6847 1.1 yamaguch rv = ixl_rx_ctl_read(sc, reg, &val); 6848 1.1 yamaguch if (rv == 0) 6849 1.1 yamaguch return val; 6850 1.1 yamaguch else if (rv == EAGAIN) 6851 1.1 yamaguch delaymsec(1); 6852 1.1 yamaguch else 6853 1.1 yamaguch break; 6854 1.1 yamaguch } 6855 1.1 yamaguch 6856 1.1 yamaguch val = ixl_rd(sc, reg); 6857 1.1 yamaguch 6858 1.1 yamaguch return val; 6859 1.1 yamaguch } 6860 1.1 yamaguch 6861 1.1 yamaguch static int 6862 1.1 yamaguch ixl_rx_ctl_write(struct ixl_softc *sc, uint32_t reg, uint32_t value) 6863 1.1 yamaguch { 6864 1.1 yamaguch struct ixl_aq_desc iaq; 6865 1.1 yamaguch 6866 1.1 yamaguch memset(&iaq, 0, sizeof(iaq)); 6867 1.1 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_RX_CTL_REG_WRITE); 6868 1.1 yamaguch iaq.iaq_param[1] = htole32(reg); 6869 1.1 yamaguch iaq.iaq_param[3] = htole32(value); 6870 1.1 yamaguch 6871 1.1 yamaguch if (ixl_atq_poll(sc, &iaq, 250) != 0) 6872 1.1 yamaguch return ETIMEDOUT; 6873 1.1 yamaguch 6874 1.1 yamaguch switch (htole16(iaq.iaq_retval)) { 6875 1.1 yamaguch case IXL_AQ_RC_OK: 6876 1.1 yamaguch /* success */ 6877 1.1 yamaguch break; 6878 1.1 yamaguch case IXL_AQ_RC_EACCES: 6879 1.1 yamaguch return EPERM; 6880 1.1 yamaguch case IXL_AQ_RC_EAGAIN: 6881 1.1 yamaguch return EAGAIN; 6882 1.1 yamaguch default: 6883 1.1 yamaguch return EIO; 6884 1.1 yamaguch } 6885 1.1 yamaguch 6886 1.1 yamaguch return 0; 6887 1.1 yamaguch } 6888 1.1 yamaguch 6889 1.1 yamaguch static void 6890 1.1 yamaguch ixl_wr_rx_csr(struct ixl_softc *sc, uint32_t reg, uint32_t value) 6891 1.1 yamaguch { 6892 1.1 yamaguch int rv, retry, retry_limit; 6893 1.1 yamaguch 6894 1.25 yamaguch if (ISSET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_RXCTL)) { 6895 1.25 yamaguch retry_limit = 5; 6896 1.25 yamaguch } else { 6897 1.25 yamaguch retry_limit = 0; 6898 1.25 yamaguch } 6899 1.1 yamaguch 6900 1.1 yamaguch for (retry = 0; retry < retry_limit; retry++) { 6901 1.1 yamaguch rv = ixl_rx_ctl_write(sc, reg, value); 6902 1.1 yamaguch if (rv == 0) 6903 1.1 yamaguch return; 6904 1.1 yamaguch else if (rv == EAGAIN) 6905 1.1 yamaguch delaymsec(1); 6906 1.1 yamaguch else 6907 1.1 yamaguch break; 6908 1.1 yamaguch } 6909 1.1 yamaguch 6910 1.1 yamaguch ixl_wr(sc, reg, value); 6911 1.1 yamaguch } 6912 1.1 yamaguch 6913 1.26 yamaguch static int 6914 1.26 yamaguch ixl_nvm_lock(struct ixl_softc *sc, char rw) 6915 1.26 yamaguch { 6916 1.26 yamaguch struct ixl_aq_desc iaq; 6917 1.26 yamaguch struct ixl_aq_req_resource_param *param; 6918 1.26 yamaguch int rv; 6919 1.26 yamaguch 6920 1.26 yamaguch if (!ISSET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_NVMLOCK)) 6921 1.26 yamaguch return 0; 6922 1.26 yamaguch 6923 1.26 yamaguch memset(&iaq, 0, sizeof(iaq)); 6924 1.26 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_REQUEST_RESOURCE); 6925 1.26 yamaguch 6926 1.26 yamaguch param = (struct ixl_aq_req_resource_param *)&iaq.iaq_param; 6927 1.26 yamaguch param->resource_id = htole16(IXL_AQ_RESOURCE_ID_NVM); 6928 1.26 yamaguch if (rw == 'R') { 6929 1.26 yamaguch param->access_type = htole16(IXL_AQ_RESOURCE_ACCES_READ); 6930 1.26 yamaguch } else { 6931 1.26 yamaguch param->access_type = htole16(IXL_AQ_RESOURCE_ACCES_WRITE); 6932 1.26 yamaguch } 6933 1.26 yamaguch 6934 1.26 yamaguch rv = ixl_atq_poll(sc, &iaq, 250); 6935 1.26 yamaguch 6936 1.26 yamaguch if (rv != 0) 6937 1.26 yamaguch return ETIMEDOUT; 6938 1.26 yamaguch 6939 1.26 yamaguch switch (le16toh(iaq.iaq_retval)) { 6940 1.26 yamaguch case IXL_AQ_RC_OK: 6941 1.26 yamaguch break; 6942 1.26 yamaguch case IXL_AQ_RC_EACCES: 6943 1.26 yamaguch return EACCES; 6944 1.26 yamaguch case IXL_AQ_RC_EBUSY: 6945 1.26 yamaguch return EBUSY; 6946 1.26 yamaguch case IXL_AQ_RC_EPERM: 6947 1.26 yamaguch return EPERM; 6948 1.26 yamaguch } 6949 1.26 yamaguch 6950 1.26 yamaguch return 0; 6951 1.26 yamaguch } 6952 1.26 yamaguch 6953 1.26 yamaguch static int 6954 1.26 yamaguch ixl_nvm_unlock(struct ixl_softc *sc) 6955 1.26 yamaguch { 6956 1.26 yamaguch struct ixl_aq_desc iaq; 6957 1.26 yamaguch struct ixl_aq_rel_resource_param *param; 6958 1.26 yamaguch int rv; 6959 1.26 yamaguch 6960 1.26 yamaguch if (!ISSET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_NVMLOCK)) 6961 1.26 yamaguch return 0; 6962 1.26 yamaguch 6963 1.26 yamaguch memset(&iaq, 0, sizeof(iaq)); 6964 1.26 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_RELEASE_RESOURCE); 6965 1.26 yamaguch 6966 1.26 yamaguch param = (struct ixl_aq_rel_resource_param *)&iaq.iaq_param; 6967 1.26 yamaguch param->resource_id = htole16(IXL_AQ_RESOURCE_ID_NVM); 6968 1.26 yamaguch 6969 1.26 yamaguch rv = ixl_atq_poll(sc, &iaq, 250); 6970 1.26 yamaguch 6971 1.26 yamaguch if (rv != 0) 6972 1.26 yamaguch return ETIMEDOUT; 6973 1.26 yamaguch 6974 1.26 yamaguch switch (le16toh(iaq.iaq_retval)) { 6975 1.26 yamaguch case IXL_AQ_RC_OK: 6976 1.26 yamaguch break; 6977 1.26 yamaguch default: 6978 1.26 yamaguch return EIO; 6979 1.26 yamaguch } 6980 1.26 yamaguch return 0; 6981 1.26 yamaguch } 6982 1.26 yamaguch 6983 1.26 yamaguch static int 6984 1.26 yamaguch ixl_srdone_poll(struct ixl_softc *sc) 6985 1.26 yamaguch { 6986 1.26 yamaguch int wait_count; 6987 1.26 yamaguch uint32_t reg; 6988 1.26 yamaguch 6989 1.26 yamaguch for (wait_count = 0; wait_count < IXL_SRRD_SRCTL_ATTEMPTS; 6990 1.26 yamaguch wait_count++) { 6991 1.26 yamaguch reg = ixl_rd(sc, I40E_GLNVM_SRCTL); 6992 1.26 yamaguch if (ISSET(reg, I40E_GLNVM_SRCTL_DONE_MASK)) 6993 1.26 yamaguch break; 6994 1.26 yamaguch 6995 1.26 yamaguch delaymsec(5); 6996 1.26 yamaguch } 6997 1.26 yamaguch 6998 1.26 yamaguch if (wait_count == IXL_SRRD_SRCTL_ATTEMPTS) 6999 1.26 yamaguch return -1; 7000 1.26 yamaguch 7001 1.26 yamaguch return 0; 7002 1.26 yamaguch } 7003 1.26 yamaguch 7004 1.26 yamaguch static int 7005 1.26 yamaguch ixl_nvm_read_srctl(struct ixl_softc *sc, uint16_t offset, uint16_t *data) 7006 1.26 yamaguch { 7007 1.26 yamaguch uint32_t reg; 7008 1.26 yamaguch 7009 1.26 yamaguch if (ixl_srdone_poll(sc) != 0) 7010 1.26 yamaguch return ETIMEDOUT; 7011 1.26 yamaguch 7012 1.26 yamaguch reg = ((uint32_t)offset << I40E_GLNVM_SRCTL_ADDR_SHIFT) | 7013 1.26 yamaguch __BIT(I40E_GLNVM_SRCTL_START_SHIFT); 7014 1.26 yamaguch ixl_wr(sc, I40E_GLNVM_SRCTL, reg); 7015 1.26 yamaguch 7016 1.26 yamaguch if (ixl_srdone_poll(sc) != 0) { 7017 1.26 yamaguch aprint_debug("NVM read error: couldn't access " 7018 1.26 yamaguch "Shadow RAM address: 0x%x\n", offset); 7019 1.26 yamaguch return ETIMEDOUT; 7020 1.26 yamaguch } 7021 1.26 yamaguch 7022 1.26 yamaguch reg = ixl_rd(sc, I40E_GLNVM_SRDATA); 7023 1.26 yamaguch *data = (uint16_t)__SHIFTOUT(reg, I40E_GLNVM_SRDATA_RDDATA_MASK); 7024 1.26 yamaguch 7025 1.26 yamaguch return 0; 7026 1.26 yamaguch } 7027 1.26 yamaguch 7028 1.26 yamaguch static int 7029 1.26 yamaguch ixl_nvm_read_aq(struct ixl_softc *sc, uint16_t offset_word, 7030 1.26 yamaguch void *data, size_t len) 7031 1.26 yamaguch { 7032 1.26 yamaguch struct ixl_dmamem *idm; 7033 1.26 yamaguch struct ixl_aq_desc iaq; 7034 1.26 yamaguch struct ixl_aq_nvm_param *param; 7035 1.26 yamaguch uint32_t offset_bytes; 7036 1.26 yamaguch int rv; 7037 1.26 yamaguch 7038 1.26 yamaguch idm = &sc->sc_aqbuf; 7039 1.26 yamaguch if (len > IXL_DMA_LEN(idm)) 7040 1.26 yamaguch return ENOMEM; 7041 1.26 yamaguch 7042 1.26 yamaguch memset(IXL_DMA_KVA(idm), 0, IXL_DMA_LEN(idm)); 7043 1.26 yamaguch memset(&iaq, 0, sizeof(iaq)); 7044 1.26 yamaguch iaq.iaq_opcode = htole16(IXL_AQ_OP_NVM_READ); 7045 1.26 yamaguch iaq.iaq_flags = htole16(IXL_AQ_BUF | 7046 1.26 yamaguch ((len > I40E_AQ_LARGE_BUF) ? IXL_AQ_LB : 0)); 7047 1.26 yamaguch iaq.iaq_datalen = htole16(len); 7048 1.26 yamaguch ixl_aq_dva(&iaq, IXL_DMA_DVA(idm)); 7049 1.26 yamaguch 7050 1.26 yamaguch param = (struct ixl_aq_nvm_param *)iaq.iaq_param; 7051 1.26 yamaguch param->command_flags = IXL_AQ_NVM_LAST_CMD; 7052 1.26 yamaguch param->module_pointer = 0; 7053 1.26 yamaguch param->length = htole16(len); 7054 1.26 yamaguch offset_bytes = (uint32_t)offset_word * 2; 7055 1.26 yamaguch offset_bytes &= 0x00FFFFFF; 7056 1.26 yamaguch param->offset = htole32(offset_bytes); 7057 1.26 yamaguch 7058 1.26 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(idm), 0, IXL_DMA_LEN(idm), 7059 1.26 yamaguch BUS_DMASYNC_PREREAD); 7060 1.26 yamaguch 7061 1.26 yamaguch rv = ixl_atq_poll(sc, &iaq, 250); 7062 1.26 yamaguch 7063 1.26 yamaguch bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(idm), 0, IXL_DMA_LEN(idm), 7064 1.26 yamaguch BUS_DMASYNC_POSTREAD); 7065 1.26 yamaguch 7066 1.26 yamaguch if (rv != 0) { 7067 1.26 yamaguch return ETIMEDOUT; 7068 1.26 yamaguch } 7069 1.26 yamaguch 7070 1.26 yamaguch switch (le16toh(iaq.iaq_retval)) { 7071 1.26 yamaguch case IXL_AQ_RC_OK: 7072 1.26 yamaguch break; 7073 1.26 yamaguch case IXL_AQ_RC_EPERM: 7074 1.26 yamaguch return EPERM; 7075 1.26 yamaguch case IXL_AQ_RC_EINVAL: 7076 1.26 yamaguch return EINVAL; 7077 1.26 yamaguch case IXL_AQ_RC_EBUSY: 7078 1.26 yamaguch return EBUSY; 7079 1.26 yamaguch case IXL_AQ_RC_EIO: 7080 1.26 yamaguch default: 7081 1.26 yamaguch return EIO; 7082 1.26 yamaguch } 7083 1.26 yamaguch 7084 1.26 yamaguch memcpy(data, IXL_DMA_KVA(idm), len); 7085 1.26 yamaguch 7086 1.26 yamaguch return 0; 7087 1.26 yamaguch } 7088 1.26 yamaguch 7089 1.26 yamaguch static int 7090 1.26 yamaguch ixl_rd16_nvm(struct ixl_softc *sc, uint16_t offset, uint16_t *data) 7091 1.26 yamaguch { 7092 1.26 yamaguch int error; 7093 1.26 yamaguch uint16_t buf; 7094 1.26 yamaguch 7095 1.26 yamaguch error = ixl_nvm_lock(sc, 'R'); 7096 1.26 yamaguch if (error) 7097 1.26 yamaguch return error; 7098 1.26 yamaguch 7099 1.26 yamaguch if (ISSET(sc->sc_aq_flags, IXL_SC_AQ_FLAG_NVMREAD)) { 7100 1.26 yamaguch error = ixl_nvm_read_aq(sc, offset, 7101 1.26 yamaguch &buf, sizeof(buf)); 7102 1.26 yamaguch if (error == 0) 7103 1.26 yamaguch *data = le16toh(buf); 7104 1.26 yamaguch } else { 7105 1.26 yamaguch error = ixl_nvm_read_srctl(sc, offset, &buf); 7106 1.26 yamaguch if (error == 0) 7107 1.26 yamaguch *data = buf; 7108 1.26 yamaguch } 7109 1.26 yamaguch 7110 1.26 yamaguch ixl_nvm_unlock(sc); 7111 1.26 yamaguch 7112 1.26 yamaguch return error; 7113 1.26 yamaguch } 7114 1.26 yamaguch 7115 1.1 yamaguch MODULE(MODULE_CLASS_DRIVER, if_ixl, "pci"); 7116 1.1 yamaguch 7117 1.1 yamaguch #ifdef _MODULE 7118 1.1 yamaguch #include "ioconf.c" 7119 1.1 yamaguch #endif 7120 1.1 yamaguch 7121 1.19 yamaguch #ifdef _MODULE 7122 1.19 yamaguch static void 7123 1.19 yamaguch ixl_parse_modprop(prop_dictionary_t dict) 7124 1.19 yamaguch { 7125 1.19 yamaguch prop_object_t obj; 7126 1.19 yamaguch int64_t val; 7127 1.19 yamaguch uint64_t uval; 7128 1.19 yamaguch 7129 1.19 yamaguch if (dict == NULL) 7130 1.19 yamaguch return; 7131 1.19 yamaguch 7132 1.19 yamaguch obj = prop_dictionary_get(dict, "nomsix"); 7133 1.19 yamaguch if (obj != NULL && prop_object_type(obj) == PROP_TYPE_BOOL) { 7134 1.19 yamaguch ixl_param_nomsix = prop_bool_true((prop_bool_t)obj); 7135 1.19 yamaguch } 7136 1.19 yamaguch 7137 1.19 yamaguch obj = prop_dictionary_get(dict, "stats_interval"); 7138 1.19 yamaguch if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) { 7139 1.67 thorpej val = prop_number_signed_value((prop_number_t)obj); 7140 1.19 yamaguch 7141 1.19 yamaguch /* the range has no reason */ 7142 1.24 yamaguch if (100 < val && val < 180000) { 7143 1.19 yamaguch ixl_param_stats_interval = val; 7144 1.19 yamaguch } 7145 1.19 yamaguch } 7146 1.19 yamaguch 7147 1.19 yamaguch obj = prop_dictionary_get(dict, "nqps_limit"); 7148 1.19 yamaguch if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) { 7149 1.67 thorpej val = prop_number_signed_value((prop_number_t)obj); 7150 1.19 yamaguch 7151 1.19 yamaguch if (val <= INT32_MAX) 7152 1.19 yamaguch ixl_param_nqps_limit = val; 7153 1.19 yamaguch } 7154 1.19 yamaguch 7155 1.19 yamaguch obj = prop_dictionary_get(dict, "rx_ndescs"); 7156 1.19 yamaguch if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) { 7157 1.19 yamaguch uval = prop_number_unsigned_integer_value((prop_number_t)obj); 7158 1.19 yamaguch 7159 1.19 yamaguch if (uval > 8) 7160 1.19 yamaguch ixl_param_rx_ndescs = uval; 7161 1.19 yamaguch } 7162 1.19 yamaguch 7163 1.19 yamaguch obj = prop_dictionary_get(dict, "tx_ndescs"); 7164 1.19 yamaguch if (obj != NULL && prop_object_type(obj) == PROP_TYPE_NUMBER) { 7165 1.19 yamaguch uval = prop_number_unsigned_integer_value((prop_number_t)obj); 7166 1.19 yamaguch 7167 1.19 yamaguch if (uval > IXL_TX_PKT_DESCS) 7168 1.19 yamaguch ixl_param_tx_ndescs = uval; 7169 1.19 yamaguch } 7170 1.19 yamaguch 7171 1.19 yamaguch } 7172 1.19 yamaguch #endif 7173 1.19 yamaguch 7174 1.1 yamaguch static int 7175 1.1 yamaguch if_ixl_modcmd(modcmd_t cmd, void *opaque) 7176 1.1 yamaguch { 7177 1.1 yamaguch int error = 0; 7178 1.1 yamaguch 7179 1.1 yamaguch #ifdef _MODULE 7180 1.1 yamaguch switch (cmd) { 7181 1.1 yamaguch case MODULE_CMD_INIT: 7182 1.19 yamaguch ixl_parse_modprop((prop_dictionary_t)opaque); 7183 1.1 yamaguch error = config_init_component(cfdriver_ioconf_if_ixl, 7184 1.1 yamaguch cfattach_ioconf_if_ixl, cfdata_ioconf_if_ixl); 7185 1.1 yamaguch break; 7186 1.1 yamaguch case MODULE_CMD_FINI: 7187 1.1 yamaguch error = config_fini_component(cfdriver_ioconf_if_ixl, 7188 1.1 yamaguch cfattach_ioconf_if_ixl, cfdata_ioconf_if_ixl); 7189 1.1 yamaguch break; 7190 1.1 yamaguch default: 7191 1.1 yamaguch error = ENOTTY; 7192 1.1 yamaguch break; 7193 1.1 yamaguch } 7194 1.1 yamaguch #endif 7195 1.1 yamaguch 7196 1.1 yamaguch return error; 7197 1.1 yamaguch } 7198