1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2012, 2016, 2025 Chelsio Communications. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 #include "opt_inet.h" 30 31 #include <sys/param.h> 32 #include <sys/eventhandler.h> 33 34 #include "common.h" 35 #include "t4_regs.h" 36 #include "t4_regs_values.h" 37 #include "firmware/t4fw_interface.h" 38 39 #undef msleep 40 #define msleep(x) do { \ 41 if (cold) \ 42 DELAY((x) * 1000); \ 43 else \ 44 pause("t4hw", (x) * hz / 1000); \ 45 } while (0) 46 47 /** 48 * t4_wait_op_done_val - wait until an operation is completed 49 * @adapter: the adapter performing the operation 50 * @reg: the register to check for completion 51 * @mask: a single-bit field within @reg that indicates completion 52 * @polarity: the value of the field when the operation is completed 53 * @attempts: number of check iterations 54 * @delay: delay in usecs between iterations 55 * @valp: where to store the value of the register at completion time 56 * 57 * Wait until an operation is completed by checking a bit in a register 58 * up to @attempts times. If @valp is not NULL the value of the register 59 * at the time it indicated completion is stored there. Returns 0 if the 60 * operation completes and -EAGAIN otherwise. 61 */ 62 static int t4_wait_op_done_val(struct adapter *adapter, int reg, u32 mask, 63 int polarity, int attempts, int delay, u32 *valp) 64 { 65 while (1) { 66 u32 val = t4_read_reg(adapter, reg); 67 68 if (!!(val & mask) == polarity) { 69 if (valp) 70 *valp = val; 71 return 0; 72 } 73 if (--attempts == 0) 74 return -EAGAIN; 75 if (delay) 76 udelay(delay); 77 } 78 } 79 80 static inline int t4_wait_op_done(struct adapter *adapter, int reg, u32 mask, 81 int polarity, int attempts, int delay) 82 { 83 return t4_wait_op_done_val(adapter, reg, mask, polarity, attempts, 84 delay, NULL); 85 } 86 87 /** 88 * t7_wait_sram_done - wait until an operation is completed 89 * @adapter: the adapter performing the operation 90 * @reg: the register to check for completion 91 * @result_reg: register that holds the result value 92 * @attempts: number of check iterations 93 * @delay: delay in usecs between iterations 94 * @valp: where to store the value of the result register at completion time 95 * 96 * Waits until a specific bit in @reg is cleared, checking up to 97 * @attempts times.Once the bit is cleared, reads from @result_reg 98 * and stores the value in @valp if it is not NULL. Returns 0 if the 99 * operation completes successfully and -EAGAIN if it times out. 100 */ 101 static int t7_wait_sram_done(struct adapter *adap, int reg, int result_reg, 102 int attempts, int delay, u32 *valp) 103 { 104 while (1) { 105 u32 val = t4_read_reg(adap, reg); 106 107 /* Check if SramStart (bit 19) is cleared */ 108 if (!(val & (1 << 19))) { 109 if (valp) 110 *valp = t4_read_reg(adap, result_reg); 111 return 0; 112 } 113 114 if (--attempts == 0) 115 return -EAGAIN; 116 117 if (delay) 118 udelay(delay); 119 } 120 } 121 122 /** 123 * t4_set_reg_field - set a register field to a value 124 * @adapter: the adapter to program 125 * @addr: the register address 126 * @mask: specifies the portion of the register to modify 127 * @val: the new value for the register field 128 * 129 * Sets a register field specified by the supplied mask to the 130 * given value. 131 */ 132 void t4_set_reg_field(struct adapter *adapter, unsigned int addr, u32 mask, 133 u32 val) 134 { 135 u32 v = t4_read_reg(adapter, addr) & ~mask; 136 137 t4_write_reg(adapter, addr, v | val); 138 (void) t4_read_reg(adapter, addr); /* flush */ 139 } 140 141 /** 142 * t4_read_indirect - read indirectly addressed registers 143 * @adap: the adapter 144 * @addr_reg: register holding the indirect address 145 * @data_reg: register holding the value of the indirect register 146 * @vals: where the read register values are stored 147 * @nregs: how many indirect registers to read 148 * @start_idx: index of first indirect register to read 149 * 150 * Reads registers that are accessed indirectly through an address/data 151 * register pair. 152 */ 153 void t4_read_indirect(struct adapter *adap, unsigned int addr_reg, 154 unsigned int data_reg, u32 *vals, 155 unsigned int nregs, unsigned int start_idx) 156 { 157 while (nregs--) { 158 t4_write_reg(adap, addr_reg, start_idx); 159 *vals++ = t4_read_reg(adap, data_reg); 160 start_idx++; 161 } 162 } 163 164 /** 165 * t4_write_indirect - write indirectly addressed registers 166 * @adap: the adapter 167 * @addr_reg: register holding the indirect addresses 168 * @data_reg: register holding the value for the indirect registers 169 * @vals: values to write 170 * @nregs: how many indirect registers to write 171 * @start_idx: address of first indirect register to write 172 * 173 * Writes a sequential block of registers that are accessed indirectly 174 * through an address/data register pair. 175 */ 176 void t4_write_indirect(struct adapter *adap, unsigned int addr_reg, 177 unsigned int data_reg, const u32 *vals, 178 unsigned int nregs, unsigned int start_idx) 179 { 180 while (nregs--) { 181 t4_write_reg(adap, addr_reg, start_idx++); 182 t4_write_reg(adap, data_reg, *vals++); 183 } 184 } 185 186 /* 187 * Read a 32-bit PCI Configuration Space register via the PCI-E backdoor 188 * mechanism. This guarantees that we get the real value even if we're 189 * operating within a Virtual Machine and the Hypervisor is trapping our 190 * Configuration Space accesses. 191 * 192 * N.B. This routine should only be used as a last resort: the firmware uses 193 * the backdoor registers on a regular basis and we can end up 194 * conflicting with it's uses! 195 */ 196 u32 t4_hw_pci_read_cfg4(adapter_t *adap, int reg) 197 { 198 u32 req = V_FUNCTION(adap->pf) | V_REGISTER(reg); 199 u32 val; 200 201 if (chip_id(adap) <= CHELSIO_T5) 202 req |= F_ENABLE; 203 else 204 req |= F_T6_ENABLE; 205 206 if (is_t4(adap)) 207 req |= F_LOCALCFG; 208 209 t4_write_reg(adap, A_PCIE_CFG_SPACE_REQ, req); 210 val = t4_read_reg(adap, A_PCIE_CFG_SPACE_DATA); 211 212 /* 213 * Reset F_ENABLE to 0 so reads of PCIE_CFG_SPACE_DATA won't cause a 214 * Configuration Space read. (None of the other fields matter when 215 * F_ENABLE is 0 so a simple register write is easier than a 216 * read-modify-write via t4_set_reg_field().) 217 */ 218 t4_write_reg(adap, A_PCIE_CFG_SPACE_REQ, 0); 219 220 return val; 221 } 222 223 /* 224 * t4_report_fw_error - report firmware error 225 * @adap: the adapter 226 * 227 * The adapter firmware can indicate error conditions to the host. 228 * If the firmware has indicated an error, print out the reason for 229 * the firmware error. 230 */ 231 void t4_report_fw_error(struct adapter *adap) 232 { 233 static const char *const reason[] = { 234 "Crash", /* PCIE_FW_EVAL_CRASH */ 235 "During Device Preparation", /* PCIE_FW_EVAL_PREP */ 236 "During Device Configuration", /* PCIE_FW_EVAL_CONF */ 237 "During Device Initialization", /* PCIE_FW_EVAL_INIT */ 238 "Unexpected Event", /* PCIE_FW_EVAL_UNEXPECTEDEVENT */ 239 "Insufficient Airflow", /* PCIE_FW_EVAL_OVERHEAT */ 240 "Device Shutdown", /* PCIE_FW_EVAL_DEVICESHUTDOWN */ 241 "Reserved", /* reserved */ 242 }; 243 u32 pcie_fw; 244 245 pcie_fw = t4_read_reg(adap, A_PCIE_FW); 246 if (pcie_fw & F_PCIE_FW_ERR) { 247 CH_ERR(adap, "firmware reports adapter error: %s (0x%08x)\n", 248 reason[G_PCIE_FW_EVAL(pcie_fw)], pcie_fw); 249 } 250 } 251 252 /* 253 * Get the reply to a mailbox command and store it in @rpl in big-endian order. 254 */ 255 static void get_mbox_rpl(struct adapter *adap, __be64 *rpl, int nflit, 256 u32 mbox_addr) 257 { 258 for ( ; nflit; nflit--, mbox_addr += 8) 259 *rpl++ = cpu_to_be64(t4_read_reg64(adap, mbox_addr)); 260 } 261 262 /* 263 * Handle a FW assertion reported in a mailbox. 264 */ 265 static void fw_asrt(struct adapter *adap, struct fw_debug_cmd *asrt) 266 { 267 CH_ALERT(adap, 268 "FW assertion at %.16s:%u, val0 %#x, val1 %#x\n", 269 asrt->u.assert.filename_0_7, 270 be32_to_cpu(asrt->u.assert.line), 271 be32_to_cpu(asrt->u.assert.x), 272 be32_to_cpu(asrt->u.assert.y)); 273 } 274 275 struct port_tx_state { 276 uint64_t rx_pause; 277 uint64_t tx_frames; 278 }; 279 280 u32 281 t4_port_reg(struct adapter *adap, u8 port, u32 reg) 282 { 283 if (chip_id(adap) > CHELSIO_T6) 284 return T7_PORT_REG(port, reg); 285 if (chip_id(adap) > CHELSIO_T4) 286 return T5_PORT_REG(port, reg); 287 return PORT_REG(port, reg); 288 } 289 290 static void 291 read_tx_state_one(struct adapter *sc, int i, struct port_tx_state *tx_state) 292 { 293 uint32_t rx_pause_reg, tx_frames_reg; 294 295 rx_pause_reg = t4_port_reg(sc, i, A_MPS_PORT_STAT_RX_PORT_PAUSE_L); 296 tx_frames_reg = t4_port_reg(sc, i, A_MPS_PORT_STAT_TX_PORT_FRAMES_L); 297 298 tx_state->rx_pause = t4_read_reg64(sc, rx_pause_reg); 299 tx_state->tx_frames = t4_read_reg64(sc, tx_frames_reg); 300 } 301 302 static void 303 read_tx_state(struct adapter *sc, struct port_tx_state *tx_state) 304 { 305 int i; 306 307 for (i = 0; i < MAX_NCHAN; i++) { 308 if (sc->chan_map[i] != 0xff) 309 read_tx_state_one(sc, i, &tx_state[i]); 310 } 311 } 312 313 static void 314 check_tx_state(struct adapter *sc, struct port_tx_state *tx_state) 315 { 316 uint32_t port_ctl_reg; 317 uint64_t tx_frames, rx_pause; 318 int i; 319 320 for (i = 0; i < MAX_NCHAN; i++) { 321 if (sc->chan_map[i] == 0xff) 322 continue; 323 rx_pause = tx_state[i].rx_pause; 324 tx_frames = tx_state[i].tx_frames; 325 read_tx_state_one(sc, i, &tx_state[i]); /* update */ 326 327 port_ctl_reg = t4_port_reg(sc, i, A_MPS_PORT_CTL); 328 if (t4_read_reg(sc, port_ctl_reg) & F_PORTTXEN && 329 rx_pause != tx_state[i].rx_pause && 330 tx_frames == tx_state[i].tx_frames) { 331 t4_set_reg_field(sc, port_ctl_reg, F_PORTTXEN, 0); 332 mdelay(1); 333 t4_set_reg_field(sc, port_ctl_reg, F_PORTTXEN, F_PORTTXEN); 334 } 335 } 336 } 337 338 #define X_CIM_PF_NOACCESS 0xeeeeeeee 339 /** 340 * t4_wr_mbox_meat_timeout - send a command to FW through the given mailbox 341 * @adap: the adapter 342 * @mbox: index of the mailbox to use 343 * @cmd: the command to write 344 * @size: command length in bytes 345 * @rpl: where to optionally store the reply 346 * @sleep_ok: if true we may sleep while awaiting command completion 347 * @timeout: time to wait for command to finish before timing out 348 * (negative implies @sleep_ok=false) 349 * 350 * Sends the given command to FW through the selected mailbox and waits 351 * for the FW to execute the command. If @rpl is not %NULL it is used to 352 * store the FW's reply to the command. The command and its optional 353 * reply are of the same length. Some FW commands like RESET and 354 * INITIALIZE can take a considerable amount of time to execute. 355 * @sleep_ok determines whether we may sleep while awaiting the response. 356 * If sleeping is allowed we use progressive backoff otherwise we spin. 357 * Note that passing in a negative @timeout is an alternate mechanism 358 * for specifying @sleep_ok=false. This is useful when a higher level 359 * interface allows for specification of @timeout but not @sleep_ok ... 360 * 361 * The return value is 0 on success or a negative errno on failure. A 362 * failure can happen either because we are not able to execute the 363 * command or FW executes it but signals an error. In the latter case 364 * the return value is the error code indicated by FW (negated). 365 */ 366 int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd, 367 int size, void *rpl, bool sleep_ok, int timeout) 368 { 369 /* 370 * We delay in small increments at first in an effort to maintain 371 * responsiveness for simple, fast executing commands but then back 372 * off to larger delays to a maximum retry delay. 373 */ 374 static const int delay[] = { 375 1, 1, 3, 5, 10, 10, 20, 50, 100 376 }; 377 u32 v; 378 u64 res; 379 int i, ms, delay_idx, ret, next_tx_check; 380 u32 data_reg = PF_REG(mbox, A_CIM_PF_MAILBOX_DATA); 381 u32 ctl_reg = PF_REG(mbox, A_CIM_PF_MAILBOX_CTRL); 382 u32 ctl; 383 __be64 cmd_rpl[MBOX_LEN/8]; 384 u32 pcie_fw; 385 struct port_tx_state tx_state[MAX_NPORTS]; 386 387 if (adap->flags & CHK_MBOX_ACCESS) 388 ASSERT_SYNCHRONIZED_OP(adap); 389 390 if (size <= 0 || (size & 15) || size > MBOX_LEN) 391 return -EINVAL; 392 393 if (adap->flags & IS_VF) { 394 if (chip_id(adap) >= CHELSIO_T6) 395 data_reg = FW_T6VF_MBDATA_BASE_ADDR; 396 else 397 data_reg = FW_T4VF_MBDATA_BASE_ADDR; 398 ctl_reg = VF_CIM_REG(A_CIM_VF_EXT_MAILBOX_CTRL); 399 } 400 401 /* 402 * If we have a negative timeout, that implies that we can't sleep. 403 */ 404 if (timeout < 0) { 405 sleep_ok = false; 406 timeout = -timeout; 407 } 408 409 /* 410 * Attempt to gain access to the mailbox. 411 */ 412 pcie_fw = 0; 413 if (!(adap->flags & IS_VF)) { 414 pcie_fw = t4_read_reg(adap, A_PCIE_FW); 415 if (pcie_fw & F_PCIE_FW_ERR) 416 goto failed; 417 } 418 for (i = 0; i < 4; i++) { 419 ctl = t4_read_reg(adap, ctl_reg); 420 v = G_MBOWNER(ctl); 421 if (v != X_MBOWNER_NONE) 422 break; 423 } 424 425 /* 426 * If we were unable to gain access, report the error to our caller. 427 */ 428 if (v != X_MBOWNER_PL) { 429 if (!(adap->flags & IS_VF)) { 430 pcie_fw = t4_read_reg(adap, A_PCIE_FW); 431 if (pcie_fw & F_PCIE_FW_ERR) 432 goto failed; 433 } 434 ret = (v == X_MBOWNER_FW) ? -EBUSY : -ETIMEDOUT; 435 return ret; 436 } 437 438 /* 439 * If we gain ownership of the mailbox and there's a "valid" message 440 * in it, this is likely an asynchronous error message from the 441 * firmware. So we'll report that and then proceed on with attempting 442 * to issue our own command ... which may well fail if the error 443 * presaged the firmware crashing ... 444 */ 445 if (ctl & F_MBMSGVALID) { 446 CH_DUMP_MBOX(adap, mbox, data_reg, "VLD", NULL, true); 447 } 448 449 /* 450 * Copy in the new mailbox command and send it on its way ... 451 */ 452 memset(cmd_rpl, 0, sizeof(cmd_rpl)); 453 memcpy(cmd_rpl, cmd, size); 454 CH_DUMP_MBOX(adap, mbox, 0, "cmd", cmd_rpl, false); 455 for (i = 0; i < ARRAY_SIZE(cmd_rpl); i++) 456 t4_write_reg64(adap, data_reg + i * 8, be64_to_cpu(cmd_rpl[i])); 457 458 if (adap->flags & IS_VF) { 459 /* 460 * For the VFs, the Mailbox Data "registers" are 461 * actually backed by T4's "MA" interface rather than 462 * PL Registers (as is the case for the PFs). Because 463 * these are in different coherency domains, the write 464 * to the VF's PL-register-backed Mailbox Control can 465 * race in front of the writes to the MA-backed VF 466 * Mailbox Data "registers". So we need to do a 467 * read-back on at least one byte of the VF Mailbox 468 * Data registers before doing the write to the VF 469 * Mailbox Control register. 470 */ 471 t4_read_reg(adap, data_reg); 472 } 473 474 t4_write_reg(adap, ctl_reg, F_MBMSGVALID | V_MBOWNER(X_MBOWNER_FW)); 475 read_tx_state(adap, &tx_state[0]); /* also flushes the write_reg */ 476 next_tx_check = 1000; 477 delay_idx = 0; 478 ms = delay[0]; 479 480 /* 481 * Loop waiting for the reply; bail out if we time out or the firmware 482 * reports an error. 483 */ 484 for (i = 0; i < timeout; i += ms) { 485 if (!(adap->flags & IS_VF)) { 486 pcie_fw = t4_read_reg(adap, A_PCIE_FW); 487 if (pcie_fw & F_PCIE_FW_ERR) 488 break; 489 } 490 491 if (i >= next_tx_check) { 492 check_tx_state(adap, &tx_state[0]); 493 next_tx_check = i + 1000; 494 } 495 496 if (sleep_ok) { 497 ms = delay[delay_idx]; /* last element may repeat */ 498 if (delay_idx < ARRAY_SIZE(delay) - 1) 499 delay_idx++; 500 msleep(ms); 501 } else { 502 mdelay(ms); 503 } 504 505 v = t4_read_reg(adap, ctl_reg); 506 if (v == X_CIM_PF_NOACCESS) 507 continue; 508 if (G_MBOWNER(v) == X_MBOWNER_PL) { 509 if (!(v & F_MBMSGVALID)) { 510 t4_write_reg(adap, ctl_reg, 511 V_MBOWNER(X_MBOWNER_NONE)); 512 continue; 513 } 514 515 /* 516 * Retrieve the command reply and release the mailbox. 517 */ 518 get_mbox_rpl(adap, cmd_rpl, MBOX_LEN/8, data_reg); 519 CH_DUMP_MBOX(adap, mbox, 0, "rpl", cmd_rpl, false); 520 t4_write_reg(adap, ctl_reg, V_MBOWNER(X_MBOWNER_NONE)); 521 522 res = be64_to_cpu(cmd_rpl[0]); 523 if (G_FW_CMD_OP(res >> 32) == FW_DEBUG_CMD) { 524 fw_asrt(adap, (struct fw_debug_cmd *)cmd_rpl); 525 res = V_FW_CMD_RETVAL(EIO); 526 } else if (rpl) 527 memcpy(rpl, cmd_rpl, size); 528 return -G_FW_CMD_RETVAL((int)res); 529 } 530 } 531 532 /* 533 * We timed out waiting for a reply to our mailbox command. Report 534 * the error and also check to see if the firmware reported any 535 * errors ... 536 */ 537 CH_ERR(adap, "command %#x in mbox %d timed out (0x%08x).\n", 538 *(const u8 *)cmd, mbox, pcie_fw); 539 CH_DUMP_MBOX(adap, mbox, 0, "cmdsent", cmd_rpl, true); 540 CH_DUMP_MBOX(adap, mbox, data_reg, "current", NULL, true); 541 failed: 542 adap->flags &= ~FW_OK; 543 ret = pcie_fw & F_PCIE_FW_ERR ? -ENXIO : -ETIMEDOUT; 544 t4_fatal_err(adap, true); 545 return ret; 546 } 547 548 int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size, 549 void *rpl, bool sleep_ok) 550 { 551 return t4_wr_mbox_meat_timeout(adap, mbox, cmd, size, rpl, 552 sleep_ok, FW_CMD_MAX_TIMEOUT); 553 } 554 555 static int t4_edc_err_read(struct adapter *adap, int idx) 556 { 557 u32 edc_ecc_err_addr_reg; 558 u32 edc_bist_status_rdata_reg; 559 560 if (is_t4(adap)) { 561 CH_WARN(adap, "%s: T4 NOT supported.\n", __func__); 562 return 0; 563 } 564 if (idx != MEM_EDC0 && idx != MEM_EDC1) { 565 CH_WARN(adap, "%s: idx %d NOT supported.\n", __func__, idx); 566 return 0; 567 } 568 569 edc_ecc_err_addr_reg = EDC_T5_REG(A_EDC_H_ECC_ERR_ADDR, idx); 570 edc_bist_status_rdata_reg = EDC_T5_REG(A_EDC_H_BIST_STATUS_RDATA, idx); 571 572 CH_WARN(adap, 573 " edc%d err addr 0x%x: 0x%x.\n", 574 idx, edc_ecc_err_addr_reg, 575 t4_read_reg(adap, edc_ecc_err_addr_reg)); 576 CH_WARN(adap, 577 " bist: 0x%x, status %llx %llx %llx %llx %llx %llx %llx %llx %llx.\n", 578 edc_bist_status_rdata_reg, 579 (unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg), 580 (unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 8), 581 (unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 16), 582 (unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 24), 583 (unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 32), 584 (unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 40), 585 (unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 48), 586 (unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 56), 587 (unsigned long long)t4_read_reg64(adap, edc_bist_status_rdata_reg + 64)); 588 589 return 0; 590 } 591 592 /** 593 * t4_mc_read - read from MC through backdoor accesses 594 * @adap: the adapter 595 * @idx: which MC to access 596 * @addr: address of first byte requested 597 * @data: 64 bytes of data containing the requested address 598 * @ecc: where to store the corresponding 64-bit ECC word 599 * 600 * Read 64 bytes of data from MC starting at a 64-byte-aligned address 601 * that covers the requested address @addr. If @parity is not %NULL it 602 * is assigned the 64-bit ECC word for the read data. 603 */ 604 int t4_mc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc) 605 { 606 int i; 607 u32 mc_bist_cmd_reg, mc_bist_cmd_addr_reg, mc_bist_cmd_len_reg; 608 u32 mc_bist_status_rdata_reg, mc_bist_data_pattern_reg; 609 610 if (is_t4(adap)) { 611 mc_bist_cmd_reg = A_MC_BIST_CMD; 612 mc_bist_cmd_addr_reg = A_MC_BIST_CMD_ADDR; 613 mc_bist_cmd_len_reg = A_MC_BIST_CMD_LEN; 614 mc_bist_status_rdata_reg = A_MC_BIST_STATUS_RDATA; 615 mc_bist_data_pattern_reg = A_MC_BIST_DATA_PATTERN; 616 } else if (chip_id(adap) < CHELSIO_T7) { 617 mc_bist_cmd_reg = MC_REG(A_MC_P_BIST_CMD, idx); 618 mc_bist_cmd_addr_reg = MC_REG(A_MC_P_BIST_CMD_ADDR, idx); 619 mc_bist_cmd_len_reg = MC_REG(A_MC_P_BIST_CMD_LEN, idx); 620 mc_bist_status_rdata_reg = MC_REG(A_MC_P_BIST_STATUS_RDATA, idx); 621 mc_bist_data_pattern_reg = MC_REG(A_MC_P_BIST_DATA_PATTERN, idx); 622 } else { 623 /* Need to figure out split mode and the rest. */ 624 return (-ENOTSUP); 625 } 626 627 if (t4_read_reg(adap, mc_bist_cmd_reg) & F_START_BIST) 628 return -EBUSY; 629 t4_write_reg(adap, mc_bist_cmd_addr_reg, addr & ~0x3fU); 630 t4_write_reg(adap, mc_bist_cmd_len_reg, 64); 631 t4_write_reg(adap, mc_bist_data_pattern_reg, 0xc); 632 t4_write_reg(adap, mc_bist_cmd_reg, V_BIST_OPCODE(1) | 633 F_START_BIST | V_BIST_CMD_GAP(1)); 634 i = t4_wait_op_done(adap, mc_bist_cmd_reg, F_START_BIST, 0, 10, 1); 635 if (i) 636 return i; 637 638 #define MC_DATA(i) MC_BIST_STATUS_REG(mc_bist_status_rdata_reg, i) 639 640 for (i = 15; i >= 0; i--) 641 *data++ = ntohl(t4_read_reg(adap, MC_DATA(i))); 642 if (ecc) 643 *ecc = t4_read_reg64(adap, MC_DATA(16)); 644 #undef MC_DATA 645 return 0; 646 } 647 648 /** 649 * t4_edc_read - read from EDC through backdoor accesses 650 * @adap: the adapter 651 * @idx: which EDC to access 652 * @addr: address of first byte requested 653 * @data: 64 bytes of data containing the requested address 654 * @ecc: where to store the corresponding 64-bit ECC word 655 * 656 * Read 64 bytes of data from EDC starting at a 64-byte-aligned address 657 * that covers the requested address @addr. If @parity is not %NULL it 658 * is assigned the 64-bit ECC word for the read data. 659 */ 660 int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc) 661 { 662 int i; 663 u32 edc_bist_cmd_reg, edc_bist_cmd_addr_reg, edc_bist_cmd_len_reg; 664 u32 edc_bist_cmd_data_pattern, edc_bist_status_rdata_reg; 665 666 if (is_t4(adap)) { 667 edc_bist_cmd_reg = EDC_REG(A_EDC_BIST_CMD, idx); 668 edc_bist_cmd_addr_reg = EDC_REG(A_EDC_BIST_CMD_ADDR, idx); 669 edc_bist_cmd_len_reg = EDC_REG(A_EDC_BIST_CMD_LEN, idx); 670 edc_bist_cmd_data_pattern = EDC_REG(A_EDC_BIST_DATA_PATTERN, 671 idx); 672 edc_bist_status_rdata_reg = EDC_REG(A_EDC_BIST_STATUS_RDATA, 673 idx); 674 } else { 675 edc_bist_cmd_reg = EDC_T5_REG(A_EDC_H_BIST_CMD, idx); 676 edc_bist_cmd_addr_reg = EDC_T5_REG(A_EDC_H_BIST_CMD_ADDR, idx); 677 edc_bist_cmd_len_reg = EDC_T5_REG(A_EDC_H_BIST_CMD_LEN, idx); 678 edc_bist_cmd_data_pattern = EDC_T5_REG(A_EDC_H_BIST_DATA_PATTERN, 679 idx); 680 edc_bist_status_rdata_reg = EDC_T5_REG(A_EDC_H_BIST_STATUS_RDATA, 681 idx); 682 } 683 684 if (t4_read_reg(adap, edc_bist_cmd_reg) & F_START_BIST) 685 return -EBUSY; 686 t4_write_reg(adap, edc_bist_cmd_addr_reg, addr & ~0x3fU); 687 t4_write_reg(adap, edc_bist_cmd_len_reg, 64); 688 t4_write_reg(adap, edc_bist_cmd_data_pattern, 0xc); 689 t4_write_reg(adap, edc_bist_cmd_reg, 690 V_BIST_OPCODE(1) | V_BIST_CMD_GAP(1) | F_START_BIST); 691 i = t4_wait_op_done(adap, edc_bist_cmd_reg, F_START_BIST, 0, 10, 1); 692 if (i) 693 return i; 694 695 #define EDC_DATA(i) EDC_BIST_STATUS_REG(edc_bist_status_rdata_reg, i) 696 697 for (i = 15; i >= 0; i--) 698 *data++ = ntohl(t4_read_reg(adap, EDC_DATA(i))); 699 if (ecc) 700 *ecc = t4_read_reg64(adap, EDC_DATA(16)); 701 #undef EDC_DATA 702 return 0; 703 } 704 705 /** 706 * t4_mem_read - read EDC 0, EDC 1 or MC into buffer 707 * @adap: the adapter 708 * @mtype: memory type: MEM_EDC0, MEM_EDC1 or MEM_MC 709 * @addr: address within indicated memory type 710 * @len: amount of memory to read 711 * @buf: host memory buffer 712 * 713 * Reads an [almost] arbitrary memory region in the firmware: the 714 * firmware memory address, length and host buffer must be aligned on 715 * 32-bit boudaries. The memory is returned as a raw byte sequence from 716 * the firmware's memory. If this memory contains data structures which 717 * contain multi-byte integers, it's the callers responsibility to 718 * perform appropriate byte order conversions. 719 */ 720 int t4_mem_read(struct adapter *adap, int mtype, u32 addr, u32 len, 721 __be32 *buf) 722 { 723 u32 pos, start, end, offset; 724 int ret; 725 726 /* 727 * Argument sanity checks ... 728 */ 729 if ((addr & 0x3) || (len & 0x3)) 730 return -EINVAL; 731 732 /* 733 * The underlaying EDC/MC read routines read 64 bytes at a time so we 734 * need to round down the start and round up the end. We'll start 735 * copying out of the first line at (addr - start) a word at a time. 736 */ 737 start = rounddown2(addr, 64); 738 end = roundup2(addr + len, 64); 739 offset = (addr - start)/sizeof(__be32); 740 741 for (pos = start; pos < end; pos += 64, offset = 0) { 742 __be32 data[16]; 743 744 /* 745 * Read the chip's memory block and bail if there's an error. 746 */ 747 if ((mtype == MEM_MC) || (mtype == MEM_MC1)) 748 ret = t4_mc_read(adap, mtype - MEM_MC, pos, data, NULL); 749 else 750 ret = t4_edc_read(adap, mtype, pos, data, NULL); 751 if (ret) 752 return ret; 753 754 /* 755 * Copy the data into the caller's memory buffer. 756 */ 757 while (offset < 16 && len > 0) { 758 *buf++ = data[offset++]; 759 len -= sizeof(__be32); 760 } 761 } 762 763 return 0; 764 } 765 766 /* 767 * Return the specified PCI-E Configuration Space register from our Physical 768 * Function. We try first via a Firmware LDST Command (if fw_attach != 0) 769 * since we prefer to let the firmware own all of these registers, but if that 770 * fails we go for it directly ourselves. 771 */ 772 u32 t4_read_pcie_cfg4(struct adapter *adap, int reg, int drv_fw_attach) 773 { 774 775 /* 776 * If fw_attach != 0, construct and send the Firmware LDST Command to 777 * retrieve the specified PCI-E Configuration Space register. 778 */ 779 if (drv_fw_attach != 0) { 780 struct fw_ldst_cmd ldst_cmd; 781 int ret; 782 783 memset(&ldst_cmd, 0, sizeof(ldst_cmd)); 784 ldst_cmd.op_to_addrspace = 785 cpu_to_be32(V_FW_CMD_OP(FW_LDST_CMD) | 786 F_FW_CMD_REQUEST | 787 F_FW_CMD_READ | 788 V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FUNC_PCIE)); 789 ldst_cmd.cycles_to_len16 = cpu_to_be32(FW_LEN16(ldst_cmd)); 790 ldst_cmd.u.pcie.select_naccess = V_FW_LDST_CMD_NACCESS(1); 791 ldst_cmd.u.pcie.ctrl_to_fn = 792 (F_FW_LDST_CMD_LC | V_FW_LDST_CMD_FN(adap->pf)); 793 ldst_cmd.u.pcie.r = reg; 794 795 /* 796 * If the LDST Command succeeds, return the result, otherwise 797 * fall through to reading it directly ourselves ... 798 */ 799 ret = t4_wr_mbox(adap, adap->mbox, &ldst_cmd, sizeof(ldst_cmd), 800 &ldst_cmd); 801 if (ret == 0) 802 return be32_to_cpu(ldst_cmd.u.pcie.data[0]); 803 804 CH_WARN(adap, "Firmware failed to return " 805 "Configuration Space register %d, err = %d\n", 806 reg, -ret); 807 } 808 809 /* 810 * Read the desired Configuration Space register via the PCI-E 811 * Backdoor mechanism. 812 */ 813 return t4_hw_pci_read_cfg4(adap, reg); 814 } 815 816 /** 817 * t4_get_regs_len - return the size of the chips register set 818 * @adapter: the adapter 819 * 820 * Returns the size of the chip's BAR0 register space. 821 */ 822 unsigned int t4_get_regs_len(struct adapter *adapter) 823 { 824 unsigned int chip_version = chip_id(adapter); 825 826 switch (chip_version) { 827 case CHELSIO_T4: 828 if (adapter->flags & IS_VF) 829 return FW_T4VF_REGMAP_SIZE; 830 return T4_REGMAP_SIZE; 831 832 case CHELSIO_T5: 833 case CHELSIO_T6: 834 case CHELSIO_T7: 835 if (adapter->flags & IS_VF) 836 return FW_T4VF_REGMAP_SIZE; 837 return T5_REGMAP_SIZE; 838 } 839 840 CH_ERR(adapter, 841 "Unsupported chip version %d\n", chip_version); 842 return 0; 843 } 844 845 /** 846 * t4_get_regs - read chip registers into provided buffer 847 * @adap: the adapter 848 * @buf: register buffer 849 * @buf_size: size (in bytes) of register buffer 850 * 851 * If the provided register buffer isn't large enough for the chip's 852 * full register range, the register dump will be truncated to the 853 * register buffer's size. 854 */ 855 void t4_get_regs(struct adapter *adap, u8 *buf, size_t buf_size) 856 { 857 static const unsigned int t4_reg_ranges[] = { 858 0x1008, 0x1108, 859 0x1180, 0x1184, 860 0x1190, 0x1194, 861 0x11a0, 0x11a4, 862 0x11b0, 0x11b4, 863 0x11fc, 0x123c, 864 0x1300, 0x173c, 865 0x1800, 0x18fc, 866 0x3000, 0x30d8, 867 0x30e0, 0x30e4, 868 0x30ec, 0x5910, 869 0x5920, 0x5924, 870 0x5960, 0x5960, 871 0x5968, 0x5968, 872 0x5970, 0x5970, 873 0x5978, 0x5978, 874 0x5980, 0x5980, 875 0x5988, 0x5988, 876 0x5990, 0x5990, 877 0x5998, 0x5998, 878 0x59a0, 0x59d4, 879 0x5a00, 0x5ae0, 880 0x5ae8, 0x5ae8, 881 0x5af0, 0x5af0, 882 0x5af8, 0x5af8, 883 0x6000, 0x6098, 884 0x6100, 0x6150, 885 0x6200, 0x6208, 886 0x6240, 0x6248, 887 0x6280, 0x62b0, 888 0x62c0, 0x6338, 889 0x6370, 0x638c, 890 0x6400, 0x643c, 891 0x6500, 0x6524, 892 0x6a00, 0x6a04, 893 0x6a14, 0x6a38, 894 0x6a60, 0x6a70, 895 0x6a78, 0x6a78, 896 0x6b00, 0x6b0c, 897 0x6b1c, 0x6b84, 898 0x6bf0, 0x6bf8, 899 0x6c00, 0x6c0c, 900 0x6c1c, 0x6c84, 901 0x6cf0, 0x6cf8, 902 0x6d00, 0x6d0c, 903 0x6d1c, 0x6d84, 904 0x6df0, 0x6df8, 905 0x6e00, 0x6e0c, 906 0x6e1c, 0x6e84, 907 0x6ef0, 0x6ef8, 908 0x6f00, 0x6f0c, 909 0x6f1c, 0x6f84, 910 0x6ff0, 0x6ff8, 911 0x7000, 0x700c, 912 0x701c, 0x7084, 913 0x70f0, 0x70f8, 914 0x7100, 0x710c, 915 0x711c, 0x7184, 916 0x71f0, 0x71f8, 917 0x7200, 0x720c, 918 0x721c, 0x7284, 919 0x72f0, 0x72f8, 920 0x7300, 0x730c, 921 0x731c, 0x7384, 922 0x73f0, 0x73f8, 923 0x7400, 0x7450, 924 0x7500, 0x7530, 925 0x7600, 0x760c, 926 0x7614, 0x761c, 927 0x7680, 0x76cc, 928 0x7700, 0x7798, 929 0x77c0, 0x77fc, 930 0x7900, 0x79fc, 931 0x7b00, 0x7b58, 932 0x7b60, 0x7b84, 933 0x7b8c, 0x7c38, 934 0x7d00, 0x7d38, 935 0x7d40, 0x7d80, 936 0x7d8c, 0x7ddc, 937 0x7de4, 0x7e04, 938 0x7e10, 0x7e1c, 939 0x7e24, 0x7e38, 940 0x7e40, 0x7e44, 941 0x7e4c, 0x7e78, 942 0x7e80, 0x7ea4, 943 0x7eac, 0x7edc, 944 0x7ee8, 0x7efc, 945 0x8dc0, 0x8e04, 946 0x8e10, 0x8e1c, 947 0x8e30, 0x8e78, 948 0x8ea0, 0x8eb8, 949 0x8ec0, 0x8f6c, 950 0x8fc0, 0x9008, 951 0x9010, 0x9058, 952 0x9060, 0x9060, 953 0x9068, 0x9074, 954 0x90fc, 0x90fc, 955 0x9400, 0x9408, 956 0x9410, 0x9458, 957 0x9600, 0x9600, 958 0x9608, 0x9638, 959 0x9640, 0x96bc, 960 0x9800, 0x9808, 961 0x9820, 0x983c, 962 0x9850, 0x9864, 963 0x9c00, 0x9c6c, 964 0x9c80, 0x9cec, 965 0x9d00, 0x9d6c, 966 0x9d80, 0x9dec, 967 0x9e00, 0x9e6c, 968 0x9e80, 0x9eec, 969 0x9f00, 0x9f6c, 970 0x9f80, 0x9fec, 971 0xd004, 0xd004, 972 0xd010, 0xd03c, 973 0xdfc0, 0xdfe0, 974 0xe000, 0xea7c, 975 0xf000, 0x11110, 976 0x11118, 0x11190, 977 0x19040, 0x1906c, 978 0x19078, 0x19080, 979 0x1908c, 0x190e4, 980 0x190f0, 0x190f8, 981 0x19100, 0x19110, 982 0x19120, 0x19124, 983 0x19150, 0x19194, 984 0x1919c, 0x191b0, 985 0x191d0, 0x191e8, 986 0x19238, 0x1924c, 987 0x193f8, 0x1943c, 988 0x1944c, 0x19474, 989 0x19490, 0x194e0, 990 0x194f0, 0x194f8, 991 0x19800, 0x19c08, 992 0x19c10, 0x19c90, 993 0x19ca0, 0x19ce4, 994 0x19cf0, 0x19d40, 995 0x19d50, 0x19d94, 996 0x19da0, 0x19de8, 997 0x19df0, 0x19e40, 998 0x19e50, 0x19e90, 999 0x19ea0, 0x19f4c, 1000 0x1a000, 0x1a004, 1001 0x1a010, 0x1a06c, 1002 0x1a0b0, 0x1a0e4, 1003 0x1a0ec, 0x1a0f4, 1004 0x1a100, 0x1a108, 1005 0x1a114, 0x1a120, 1006 0x1a128, 0x1a130, 1007 0x1a138, 0x1a138, 1008 0x1a190, 0x1a1c4, 1009 0x1a1fc, 0x1a1fc, 1010 0x1e040, 0x1e04c, 1011 0x1e284, 0x1e28c, 1012 0x1e2c0, 0x1e2c0, 1013 0x1e2e0, 0x1e2e0, 1014 0x1e300, 0x1e384, 1015 0x1e3c0, 0x1e3c8, 1016 0x1e440, 0x1e44c, 1017 0x1e684, 0x1e68c, 1018 0x1e6c0, 0x1e6c0, 1019 0x1e6e0, 0x1e6e0, 1020 0x1e700, 0x1e784, 1021 0x1e7c0, 0x1e7c8, 1022 0x1e840, 0x1e84c, 1023 0x1ea84, 0x1ea8c, 1024 0x1eac0, 0x1eac0, 1025 0x1eae0, 0x1eae0, 1026 0x1eb00, 0x1eb84, 1027 0x1ebc0, 0x1ebc8, 1028 0x1ec40, 0x1ec4c, 1029 0x1ee84, 0x1ee8c, 1030 0x1eec0, 0x1eec0, 1031 0x1eee0, 0x1eee0, 1032 0x1ef00, 0x1ef84, 1033 0x1efc0, 0x1efc8, 1034 0x1f040, 0x1f04c, 1035 0x1f284, 0x1f28c, 1036 0x1f2c0, 0x1f2c0, 1037 0x1f2e0, 0x1f2e0, 1038 0x1f300, 0x1f384, 1039 0x1f3c0, 0x1f3c8, 1040 0x1f440, 0x1f44c, 1041 0x1f684, 0x1f68c, 1042 0x1f6c0, 0x1f6c0, 1043 0x1f6e0, 0x1f6e0, 1044 0x1f700, 0x1f784, 1045 0x1f7c0, 0x1f7c8, 1046 0x1f840, 0x1f84c, 1047 0x1fa84, 0x1fa8c, 1048 0x1fac0, 0x1fac0, 1049 0x1fae0, 0x1fae0, 1050 0x1fb00, 0x1fb84, 1051 0x1fbc0, 0x1fbc8, 1052 0x1fc40, 0x1fc4c, 1053 0x1fe84, 0x1fe8c, 1054 0x1fec0, 0x1fec0, 1055 0x1fee0, 0x1fee0, 1056 0x1ff00, 0x1ff84, 1057 0x1ffc0, 0x1ffc8, 1058 0x20000, 0x2002c, 1059 0x20100, 0x2013c, 1060 0x20190, 0x201a0, 1061 0x201a8, 0x201b8, 1062 0x201c4, 0x201c8, 1063 0x20200, 0x20318, 1064 0x20400, 0x204b4, 1065 0x204c0, 0x20528, 1066 0x20540, 0x20614, 1067 0x21000, 0x21040, 1068 0x2104c, 0x21060, 1069 0x210c0, 0x210ec, 1070 0x21200, 0x21268, 1071 0x21270, 0x21284, 1072 0x212fc, 0x21388, 1073 0x21400, 0x21404, 1074 0x21500, 0x21500, 1075 0x21510, 0x21518, 1076 0x2152c, 0x21530, 1077 0x2153c, 0x2153c, 1078 0x21550, 0x21554, 1079 0x21600, 0x21600, 1080 0x21608, 0x2161c, 1081 0x21624, 0x21628, 1082 0x21630, 0x21634, 1083 0x2163c, 0x2163c, 1084 0x21700, 0x2171c, 1085 0x21780, 0x2178c, 1086 0x21800, 0x21818, 1087 0x21820, 0x21828, 1088 0x21830, 0x21848, 1089 0x21850, 0x21854, 1090 0x21860, 0x21868, 1091 0x21870, 0x21870, 1092 0x21878, 0x21898, 1093 0x218a0, 0x218a8, 1094 0x218b0, 0x218c8, 1095 0x218d0, 0x218d4, 1096 0x218e0, 0x218e8, 1097 0x218f0, 0x218f0, 1098 0x218f8, 0x21a18, 1099 0x21a20, 0x21a28, 1100 0x21a30, 0x21a48, 1101 0x21a50, 0x21a54, 1102 0x21a60, 0x21a68, 1103 0x21a70, 0x21a70, 1104 0x21a78, 0x21a98, 1105 0x21aa0, 0x21aa8, 1106 0x21ab0, 0x21ac8, 1107 0x21ad0, 0x21ad4, 1108 0x21ae0, 0x21ae8, 1109 0x21af0, 0x21af0, 1110 0x21af8, 0x21c18, 1111 0x21c20, 0x21c20, 1112 0x21c28, 0x21c30, 1113 0x21c38, 0x21c38, 1114 0x21c80, 0x21c98, 1115 0x21ca0, 0x21ca8, 1116 0x21cb0, 0x21cc8, 1117 0x21cd0, 0x21cd4, 1118 0x21ce0, 0x21ce8, 1119 0x21cf0, 0x21cf0, 1120 0x21cf8, 0x21d7c, 1121 0x21e00, 0x21e04, 1122 0x22000, 0x2202c, 1123 0x22100, 0x2213c, 1124 0x22190, 0x221a0, 1125 0x221a8, 0x221b8, 1126 0x221c4, 0x221c8, 1127 0x22200, 0x22318, 1128 0x22400, 0x224b4, 1129 0x224c0, 0x22528, 1130 0x22540, 0x22614, 1131 0x23000, 0x23040, 1132 0x2304c, 0x23060, 1133 0x230c0, 0x230ec, 1134 0x23200, 0x23268, 1135 0x23270, 0x23284, 1136 0x232fc, 0x23388, 1137 0x23400, 0x23404, 1138 0x23500, 0x23500, 1139 0x23510, 0x23518, 1140 0x2352c, 0x23530, 1141 0x2353c, 0x2353c, 1142 0x23550, 0x23554, 1143 0x23600, 0x23600, 1144 0x23608, 0x2361c, 1145 0x23624, 0x23628, 1146 0x23630, 0x23634, 1147 0x2363c, 0x2363c, 1148 0x23700, 0x2371c, 1149 0x23780, 0x2378c, 1150 0x23800, 0x23818, 1151 0x23820, 0x23828, 1152 0x23830, 0x23848, 1153 0x23850, 0x23854, 1154 0x23860, 0x23868, 1155 0x23870, 0x23870, 1156 0x23878, 0x23898, 1157 0x238a0, 0x238a8, 1158 0x238b0, 0x238c8, 1159 0x238d0, 0x238d4, 1160 0x238e0, 0x238e8, 1161 0x238f0, 0x238f0, 1162 0x238f8, 0x23a18, 1163 0x23a20, 0x23a28, 1164 0x23a30, 0x23a48, 1165 0x23a50, 0x23a54, 1166 0x23a60, 0x23a68, 1167 0x23a70, 0x23a70, 1168 0x23a78, 0x23a98, 1169 0x23aa0, 0x23aa8, 1170 0x23ab0, 0x23ac8, 1171 0x23ad0, 0x23ad4, 1172 0x23ae0, 0x23ae8, 1173 0x23af0, 0x23af0, 1174 0x23af8, 0x23c18, 1175 0x23c20, 0x23c20, 1176 0x23c28, 0x23c30, 1177 0x23c38, 0x23c38, 1178 0x23c80, 0x23c98, 1179 0x23ca0, 0x23ca8, 1180 0x23cb0, 0x23cc8, 1181 0x23cd0, 0x23cd4, 1182 0x23ce0, 0x23ce8, 1183 0x23cf0, 0x23cf0, 1184 0x23cf8, 0x23d7c, 1185 0x23e00, 0x23e04, 1186 0x24000, 0x2402c, 1187 0x24100, 0x2413c, 1188 0x24190, 0x241a0, 1189 0x241a8, 0x241b8, 1190 0x241c4, 0x241c8, 1191 0x24200, 0x24318, 1192 0x24400, 0x244b4, 1193 0x244c0, 0x24528, 1194 0x24540, 0x24614, 1195 0x25000, 0x25040, 1196 0x2504c, 0x25060, 1197 0x250c0, 0x250ec, 1198 0x25200, 0x25268, 1199 0x25270, 0x25284, 1200 0x252fc, 0x25388, 1201 0x25400, 0x25404, 1202 0x25500, 0x25500, 1203 0x25510, 0x25518, 1204 0x2552c, 0x25530, 1205 0x2553c, 0x2553c, 1206 0x25550, 0x25554, 1207 0x25600, 0x25600, 1208 0x25608, 0x2561c, 1209 0x25624, 0x25628, 1210 0x25630, 0x25634, 1211 0x2563c, 0x2563c, 1212 0x25700, 0x2571c, 1213 0x25780, 0x2578c, 1214 0x25800, 0x25818, 1215 0x25820, 0x25828, 1216 0x25830, 0x25848, 1217 0x25850, 0x25854, 1218 0x25860, 0x25868, 1219 0x25870, 0x25870, 1220 0x25878, 0x25898, 1221 0x258a0, 0x258a8, 1222 0x258b0, 0x258c8, 1223 0x258d0, 0x258d4, 1224 0x258e0, 0x258e8, 1225 0x258f0, 0x258f0, 1226 0x258f8, 0x25a18, 1227 0x25a20, 0x25a28, 1228 0x25a30, 0x25a48, 1229 0x25a50, 0x25a54, 1230 0x25a60, 0x25a68, 1231 0x25a70, 0x25a70, 1232 0x25a78, 0x25a98, 1233 0x25aa0, 0x25aa8, 1234 0x25ab0, 0x25ac8, 1235 0x25ad0, 0x25ad4, 1236 0x25ae0, 0x25ae8, 1237 0x25af0, 0x25af0, 1238 0x25af8, 0x25c18, 1239 0x25c20, 0x25c20, 1240 0x25c28, 0x25c30, 1241 0x25c38, 0x25c38, 1242 0x25c80, 0x25c98, 1243 0x25ca0, 0x25ca8, 1244 0x25cb0, 0x25cc8, 1245 0x25cd0, 0x25cd4, 1246 0x25ce0, 0x25ce8, 1247 0x25cf0, 0x25cf0, 1248 0x25cf8, 0x25d7c, 1249 0x25e00, 0x25e04, 1250 0x26000, 0x2602c, 1251 0x26100, 0x2613c, 1252 0x26190, 0x261a0, 1253 0x261a8, 0x261b8, 1254 0x261c4, 0x261c8, 1255 0x26200, 0x26318, 1256 0x26400, 0x264b4, 1257 0x264c0, 0x26528, 1258 0x26540, 0x26614, 1259 0x27000, 0x27040, 1260 0x2704c, 0x27060, 1261 0x270c0, 0x270ec, 1262 0x27200, 0x27268, 1263 0x27270, 0x27284, 1264 0x272fc, 0x27388, 1265 0x27400, 0x27404, 1266 0x27500, 0x27500, 1267 0x27510, 0x27518, 1268 0x2752c, 0x27530, 1269 0x2753c, 0x2753c, 1270 0x27550, 0x27554, 1271 0x27600, 0x27600, 1272 0x27608, 0x2761c, 1273 0x27624, 0x27628, 1274 0x27630, 0x27634, 1275 0x2763c, 0x2763c, 1276 0x27700, 0x2771c, 1277 0x27780, 0x2778c, 1278 0x27800, 0x27818, 1279 0x27820, 0x27828, 1280 0x27830, 0x27848, 1281 0x27850, 0x27854, 1282 0x27860, 0x27868, 1283 0x27870, 0x27870, 1284 0x27878, 0x27898, 1285 0x278a0, 0x278a8, 1286 0x278b0, 0x278c8, 1287 0x278d0, 0x278d4, 1288 0x278e0, 0x278e8, 1289 0x278f0, 0x278f0, 1290 0x278f8, 0x27a18, 1291 0x27a20, 0x27a28, 1292 0x27a30, 0x27a48, 1293 0x27a50, 0x27a54, 1294 0x27a60, 0x27a68, 1295 0x27a70, 0x27a70, 1296 0x27a78, 0x27a98, 1297 0x27aa0, 0x27aa8, 1298 0x27ab0, 0x27ac8, 1299 0x27ad0, 0x27ad4, 1300 0x27ae0, 0x27ae8, 1301 0x27af0, 0x27af0, 1302 0x27af8, 0x27c18, 1303 0x27c20, 0x27c20, 1304 0x27c28, 0x27c30, 1305 0x27c38, 0x27c38, 1306 0x27c80, 0x27c98, 1307 0x27ca0, 0x27ca8, 1308 0x27cb0, 0x27cc8, 1309 0x27cd0, 0x27cd4, 1310 0x27ce0, 0x27ce8, 1311 0x27cf0, 0x27cf0, 1312 0x27cf8, 0x27d7c, 1313 0x27e00, 0x27e04, 1314 }; 1315 1316 static const unsigned int t4vf_reg_ranges[] = { 1317 VF_SGE_REG(A_SGE_VF_KDOORBELL), VF_SGE_REG(A_SGE_VF_GTS), 1318 VF_MPS_REG(A_MPS_VF_CTL), 1319 VF_MPS_REG(A_MPS_VF_STAT_RX_VF_ERR_FRAMES_H), 1320 VF_PL_REG(A_PL_VF_WHOAMI), VF_PL_REG(A_PL_VF_WHOAMI), 1321 VF_CIM_REG(A_CIM_VF_EXT_MAILBOX_CTRL), 1322 VF_CIM_REG(A_CIM_VF_EXT_MAILBOX_STATUS), 1323 FW_T4VF_MBDATA_BASE_ADDR, 1324 FW_T4VF_MBDATA_BASE_ADDR + 1325 ((NUM_CIM_PF_MAILBOX_DATA_INSTANCES - 1) * 4), 1326 }; 1327 1328 static const unsigned int t5_reg_ranges[] = { 1329 0x1008, 0x10c0, 1330 0x10cc, 0x10f8, 1331 0x1100, 0x1100, 1332 0x110c, 0x1148, 1333 0x1180, 0x1184, 1334 0x1190, 0x1194, 1335 0x11a0, 0x11a4, 1336 0x11b0, 0x11b4, 1337 0x11fc, 0x123c, 1338 0x1280, 0x173c, 1339 0x1800, 0x18fc, 1340 0x3000, 0x3028, 1341 0x3060, 0x30b0, 1342 0x30b8, 0x30d8, 1343 0x30e0, 0x30fc, 1344 0x3140, 0x357c, 1345 0x35a8, 0x35cc, 1346 0x35ec, 0x35ec, 1347 0x3600, 0x5624, 1348 0x56cc, 0x56ec, 1349 0x56f4, 0x5720, 1350 0x5728, 0x575c, 1351 0x580c, 0x5814, 1352 0x5890, 0x589c, 1353 0x58a4, 0x58ac, 1354 0x58b8, 0x58bc, 1355 0x5940, 0x59c8, 1356 0x59d0, 0x59dc, 1357 0x59fc, 0x5a18, 1358 0x5a60, 0x5a70, 1359 0x5a80, 0x5a9c, 1360 0x5b94, 0x5bfc, 1361 0x6000, 0x6020, 1362 0x6028, 0x6040, 1363 0x6058, 0x609c, 1364 0x60a8, 0x614c, 1365 0x7700, 0x7798, 1366 0x77c0, 0x78fc, 1367 0x7b00, 0x7b58, 1368 0x7b60, 0x7b84, 1369 0x7b8c, 0x7c54, 1370 0x7d00, 0x7d38, 1371 0x7d40, 0x7d80, 1372 0x7d8c, 0x7ddc, 1373 0x7de4, 0x7e04, 1374 0x7e10, 0x7e1c, 1375 0x7e24, 0x7e38, 1376 0x7e40, 0x7e44, 1377 0x7e4c, 0x7e78, 1378 0x7e80, 0x7edc, 1379 0x7ee8, 0x7efc, 1380 0x8dc0, 0x8de0, 1381 0x8df8, 0x8e04, 1382 0x8e10, 0x8e84, 1383 0x8ea0, 0x8f84, 1384 0x8fc0, 0x9058, 1385 0x9060, 0x9060, 1386 0x9068, 0x90f8, 1387 0x9400, 0x9408, 1388 0x9410, 0x9470, 1389 0x9600, 0x9600, 1390 0x9608, 0x9638, 1391 0x9640, 0x96f4, 1392 0x9800, 0x9808, 1393 0x9810, 0x9864, 1394 0x9c00, 0x9c6c, 1395 0x9c80, 0x9cec, 1396 0x9d00, 0x9d6c, 1397 0x9d80, 0x9dec, 1398 0x9e00, 0x9e6c, 1399 0x9e80, 0x9eec, 1400 0x9f00, 0x9f6c, 1401 0x9f80, 0xa020, 1402 0xd000, 0xd004, 1403 0xd010, 0xd03c, 1404 0xdfc0, 0xdfe0, 1405 0xe000, 0x1106c, 1406 0x11074, 0x11088, 1407 0x1109c, 0x11110, 1408 0x11118, 0x1117c, 1409 0x11190, 0x11204, 1410 0x19040, 0x1906c, 1411 0x19078, 0x19080, 1412 0x1908c, 0x190e8, 1413 0x190f0, 0x190f8, 1414 0x19100, 0x19110, 1415 0x19120, 0x19124, 1416 0x19150, 0x19194, 1417 0x1919c, 0x191b0, 1418 0x191d0, 0x191e8, 1419 0x19238, 0x19290, 1420 0x193f8, 0x19428, 1421 0x19430, 0x19444, 1422 0x1944c, 0x1946c, 1423 0x19474, 0x19474, 1424 0x19490, 0x194cc, 1425 0x194f0, 0x194f8, 1426 0x19c00, 0x19c08, 1427 0x19c10, 0x19c60, 1428 0x19c94, 0x19ce4, 1429 0x19cf0, 0x19d40, 1430 0x19d50, 0x19d94, 1431 0x19da0, 0x19de8, 1432 0x19df0, 0x19e10, 1433 0x19e50, 0x19e90, 1434 0x19ea0, 0x19f24, 1435 0x19f34, 0x19f34, 1436 0x19f40, 0x19f50, 1437 0x19f90, 0x19fb4, 1438 0x19fc4, 0x19fe4, 1439 0x1a000, 0x1a004, 1440 0x1a010, 0x1a06c, 1441 0x1a0b0, 0x1a0e4, 1442 0x1a0ec, 0x1a0f8, 1443 0x1a100, 0x1a108, 1444 0x1a114, 0x1a130, 1445 0x1a138, 0x1a1c4, 1446 0x1a1fc, 0x1a1fc, 1447 0x1e008, 0x1e00c, 1448 0x1e040, 0x1e044, 1449 0x1e04c, 0x1e04c, 1450 0x1e284, 0x1e290, 1451 0x1e2c0, 0x1e2c0, 1452 0x1e2e0, 0x1e2e0, 1453 0x1e300, 0x1e384, 1454 0x1e3c0, 0x1e3c8, 1455 0x1e408, 0x1e40c, 1456 0x1e440, 0x1e444, 1457 0x1e44c, 0x1e44c, 1458 0x1e684, 0x1e690, 1459 0x1e6c0, 0x1e6c0, 1460 0x1e6e0, 0x1e6e0, 1461 0x1e700, 0x1e784, 1462 0x1e7c0, 0x1e7c8, 1463 0x1e808, 0x1e80c, 1464 0x1e840, 0x1e844, 1465 0x1e84c, 0x1e84c, 1466 0x1ea84, 0x1ea90, 1467 0x1eac0, 0x1eac0, 1468 0x1eae0, 0x1eae0, 1469 0x1eb00, 0x1eb84, 1470 0x1ebc0, 0x1ebc8, 1471 0x1ec08, 0x1ec0c, 1472 0x1ec40, 0x1ec44, 1473 0x1ec4c, 0x1ec4c, 1474 0x1ee84, 0x1ee90, 1475 0x1eec0, 0x1eec0, 1476 0x1eee0, 0x1eee0, 1477 0x1ef00, 0x1ef84, 1478 0x1efc0, 0x1efc8, 1479 0x1f008, 0x1f00c, 1480 0x1f040, 0x1f044, 1481 0x1f04c, 0x1f04c, 1482 0x1f284, 0x1f290, 1483 0x1f2c0, 0x1f2c0, 1484 0x1f2e0, 0x1f2e0, 1485 0x1f300, 0x1f384, 1486 0x1f3c0, 0x1f3c8, 1487 0x1f408, 0x1f40c, 1488 0x1f440, 0x1f444, 1489 0x1f44c, 0x1f44c, 1490 0x1f684, 0x1f690, 1491 0x1f6c0, 0x1f6c0, 1492 0x1f6e0, 0x1f6e0, 1493 0x1f700, 0x1f784, 1494 0x1f7c0, 0x1f7c8, 1495 0x1f808, 0x1f80c, 1496 0x1f840, 0x1f844, 1497 0x1f84c, 0x1f84c, 1498 0x1fa84, 0x1fa90, 1499 0x1fac0, 0x1fac0, 1500 0x1fae0, 0x1fae0, 1501 0x1fb00, 0x1fb84, 1502 0x1fbc0, 0x1fbc8, 1503 0x1fc08, 0x1fc0c, 1504 0x1fc40, 0x1fc44, 1505 0x1fc4c, 0x1fc4c, 1506 0x1fe84, 0x1fe90, 1507 0x1fec0, 0x1fec0, 1508 0x1fee0, 0x1fee0, 1509 0x1ff00, 0x1ff84, 1510 0x1ffc0, 0x1ffc8, 1511 0x30000, 0x30030, 1512 0x30100, 0x30144, 1513 0x30190, 0x301a0, 1514 0x301a8, 0x301b8, 1515 0x301c4, 0x301c8, 1516 0x301d0, 0x301d0, 1517 0x30200, 0x30318, 1518 0x30400, 0x304b4, 1519 0x304c0, 0x3052c, 1520 0x30540, 0x3061c, 1521 0x30800, 0x30828, 1522 0x30834, 0x30834, 1523 0x308c0, 0x30908, 1524 0x30910, 0x309ac, 1525 0x30a00, 0x30a14, 1526 0x30a1c, 0x30a2c, 1527 0x30a44, 0x30a50, 1528 0x30a74, 0x30a74, 1529 0x30a7c, 0x30afc, 1530 0x30b08, 0x30c24, 1531 0x30d00, 0x30d00, 1532 0x30d08, 0x30d14, 1533 0x30d1c, 0x30d20, 1534 0x30d3c, 0x30d3c, 1535 0x30d48, 0x30d50, 1536 0x31200, 0x3120c, 1537 0x31220, 0x31220, 1538 0x31240, 0x31240, 1539 0x31600, 0x3160c, 1540 0x31a00, 0x31a1c, 1541 0x31e00, 0x31e20, 1542 0x31e38, 0x31e3c, 1543 0x31e80, 0x31e80, 1544 0x31e88, 0x31ea8, 1545 0x31eb0, 0x31eb4, 1546 0x31ec8, 0x31ed4, 1547 0x31fb8, 0x32004, 1548 0x32200, 0x32200, 1549 0x32208, 0x32240, 1550 0x32248, 0x32280, 1551 0x32288, 0x322c0, 1552 0x322c8, 0x322fc, 1553 0x32600, 0x32630, 1554 0x32a00, 0x32abc, 1555 0x32b00, 0x32b10, 1556 0x32b20, 0x32b30, 1557 0x32b40, 0x32b50, 1558 0x32b60, 0x32b70, 1559 0x33000, 0x33028, 1560 0x33030, 0x33048, 1561 0x33060, 0x33068, 1562 0x33070, 0x3309c, 1563 0x330f0, 0x33128, 1564 0x33130, 0x33148, 1565 0x33160, 0x33168, 1566 0x33170, 0x3319c, 1567 0x331f0, 0x33238, 1568 0x33240, 0x33240, 1569 0x33248, 0x33250, 1570 0x3325c, 0x33264, 1571 0x33270, 0x332b8, 1572 0x332c0, 0x332e4, 1573 0x332f8, 0x33338, 1574 0x33340, 0x33340, 1575 0x33348, 0x33350, 1576 0x3335c, 0x33364, 1577 0x33370, 0x333b8, 1578 0x333c0, 0x333e4, 1579 0x333f8, 0x33428, 1580 0x33430, 0x33448, 1581 0x33460, 0x33468, 1582 0x33470, 0x3349c, 1583 0x334f0, 0x33528, 1584 0x33530, 0x33548, 1585 0x33560, 0x33568, 1586 0x33570, 0x3359c, 1587 0x335f0, 0x33638, 1588 0x33640, 0x33640, 1589 0x33648, 0x33650, 1590 0x3365c, 0x33664, 1591 0x33670, 0x336b8, 1592 0x336c0, 0x336e4, 1593 0x336f8, 0x33738, 1594 0x33740, 0x33740, 1595 0x33748, 0x33750, 1596 0x3375c, 0x33764, 1597 0x33770, 0x337b8, 1598 0x337c0, 0x337e4, 1599 0x337f8, 0x337fc, 1600 0x33814, 0x33814, 1601 0x3382c, 0x3382c, 1602 0x33880, 0x3388c, 1603 0x338e8, 0x338ec, 1604 0x33900, 0x33928, 1605 0x33930, 0x33948, 1606 0x33960, 0x33968, 1607 0x33970, 0x3399c, 1608 0x339f0, 0x33a38, 1609 0x33a40, 0x33a40, 1610 0x33a48, 0x33a50, 1611 0x33a5c, 0x33a64, 1612 0x33a70, 0x33ab8, 1613 0x33ac0, 0x33ae4, 1614 0x33af8, 0x33b10, 1615 0x33b28, 0x33b28, 1616 0x33b3c, 0x33b50, 1617 0x33bf0, 0x33c10, 1618 0x33c28, 0x33c28, 1619 0x33c3c, 0x33c50, 1620 0x33cf0, 0x33cfc, 1621 0x34000, 0x34030, 1622 0x34100, 0x34144, 1623 0x34190, 0x341a0, 1624 0x341a8, 0x341b8, 1625 0x341c4, 0x341c8, 1626 0x341d0, 0x341d0, 1627 0x34200, 0x34318, 1628 0x34400, 0x344b4, 1629 0x344c0, 0x3452c, 1630 0x34540, 0x3461c, 1631 0x34800, 0x34828, 1632 0x34834, 0x34834, 1633 0x348c0, 0x34908, 1634 0x34910, 0x349ac, 1635 0x34a00, 0x34a14, 1636 0x34a1c, 0x34a2c, 1637 0x34a44, 0x34a50, 1638 0x34a74, 0x34a74, 1639 0x34a7c, 0x34afc, 1640 0x34b08, 0x34c24, 1641 0x34d00, 0x34d00, 1642 0x34d08, 0x34d14, 1643 0x34d1c, 0x34d20, 1644 0x34d3c, 0x34d3c, 1645 0x34d48, 0x34d50, 1646 0x35200, 0x3520c, 1647 0x35220, 0x35220, 1648 0x35240, 0x35240, 1649 0x35600, 0x3560c, 1650 0x35a00, 0x35a1c, 1651 0x35e00, 0x35e20, 1652 0x35e38, 0x35e3c, 1653 0x35e80, 0x35e80, 1654 0x35e88, 0x35ea8, 1655 0x35eb0, 0x35eb4, 1656 0x35ec8, 0x35ed4, 1657 0x35fb8, 0x36004, 1658 0x36200, 0x36200, 1659 0x36208, 0x36240, 1660 0x36248, 0x36280, 1661 0x36288, 0x362c0, 1662 0x362c8, 0x362fc, 1663 0x36600, 0x36630, 1664 0x36a00, 0x36abc, 1665 0x36b00, 0x36b10, 1666 0x36b20, 0x36b30, 1667 0x36b40, 0x36b50, 1668 0x36b60, 0x36b70, 1669 0x37000, 0x37028, 1670 0x37030, 0x37048, 1671 0x37060, 0x37068, 1672 0x37070, 0x3709c, 1673 0x370f0, 0x37128, 1674 0x37130, 0x37148, 1675 0x37160, 0x37168, 1676 0x37170, 0x3719c, 1677 0x371f0, 0x37238, 1678 0x37240, 0x37240, 1679 0x37248, 0x37250, 1680 0x3725c, 0x37264, 1681 0x37270, 0x372b8, 1682 0x372c0, 0x372e4, 1683 0x372f8, 0x37338, 1684 0x37340, 0x37340, 1685 0x37348, 0x37350, 1686 0x3735c, 0x37364, 1687 0x37370, 0x373b8, 1688 0x373c0, 0x373e4, 1689 0x373f8, 0x37428, 1690 0x37430, 0x37448, 1691 0x37460, 0x37468, 1692 0x37470, 0x3749c, 1693 0x374f0, 0x37528, 1694 0x37530, 0x37548, 1695 0x37560, 0x37568, 1696 0x37570, 0x3759c, 1697 0x375f0, 0x37638, 1698 0x37640, 0x37640, 1699 0x37648, 0x37650, 1700 0x3765c, 0x37664, 1701 0x37670, 0x376b8, 1702 0x376c0, 0x376e4, 1703 0x376f8, 0x37738, 1704 0x37740, 0x37740, 1705 0x37748, 0x37750, 1706 0x3775c, 0x37764, 1707 0x37770, 0x377b8, 1708 0x377c0, 0x377e4, 1709 0x377f8, 0x377fc, 1710 0x37814, 0x37814, 1711 0x3782c, 0x3782c, 1712 0x37880, 0x3788c, 1713 0x378e8, 0x378ec, 1714 0x37900, 0x37928, 1715 0x37930, 0x37948, 1716 0x37960, 0x37968, 1717 0x37970, 0x3799c, 1718 0x379f0, 0x37a38, 1719 0x37a40, 0x37a40, 1720 0x37a48, 0x37a50, 1721 0x37a5c, 0x37a64, 1722 0x37a70, 0x37ab8, 1723 0x37ac0, 0x37ae4, 1724 0x37af8, 0x37b10, 1725 0x37b28, 0x37b28, 1726 0x37b3c, 0x37b50, 1727 0x37bf0, 0x37c10, 1728 0x37c28, 0x37c28, 1729 0x37c3c, 0x37c50, 1730 0x37cf0, 0x37cfc, 1731 0x38000, 0x38030, 1732 0x38100, 0x38144, 1733 0x38190, 0x381a0, 1734 0x381a8, 0x381b8, 1735 0x381c4, 0x381c8, 1736 0x381d0, 0x381d0, 1737 0x38200, 0x38318, 1738 0x38400, 0x384b4, 1739 0x384c0, 0x3852c, 1740 0x38540, 0x3861c, 1741 0x38800, 0x38828, 1742 0x38834, 0x38834, 1743 0x388c0, 0x38908, 1744 0x38910, 0x389ac, 1745 0x38a00, 0x38a14, 1746 0x38a1c, 0x38a2c, 1747 0x38a44, 0x38a50, 1748 0x38a74, 0x38a74, 1749 0x38a7c, 0x38afc, 1750 0x38b08, 0x38c24, 1751 0x38d00, 0x38d00, 1752 0x38d08, 0x38d14, 1753 0x38d1c, 0x38d20, 1754 0x38d3c, 0x38d3c, 1755 0x38d48, 0x38d50, 1756 0x39200, 0x3920c, 1757 0x39220, 0x39220, 1758 0x39240, 0x39240, 1759 0x39600, 0x3960c, 1760 0x39a00, 0x39a1c, 1761 0x39e00, 0x39e20, 1762 0x39e38, 0x39e3c, 1763 0x39e80, 0x39e80, 1764 0x39e88, 0x39ea8, 1765 0x39eb0, 0x39eb4, 1766 0x39ec8, 0x39ed4, 1767 0x39fb8, 0x3a004, 1768 0x3a200, 0x3a200, 1769 0x3a208, 0x3a240, 1770 0x3a248, 0x3a280, 1771 0x3a288, 0x3a2c0, 1772 0x3a2c8, 0x3a2fc, 1773 0x3a600, 0x3a630, 1774 0x3aa00, 0x3aabc, 1775 0x3ab00, 0x3ab10, 1776 0x3ab20, 0x3ab30, 1777 0x3ab40, 0x3ab50, 1778 0x3ab60, 0x3ab70, 1779 0x3b000, 0x3b028, 1780 0x3b030, 0x3b048, 1781 0x3b060, 0x3b068, 1782 0x3b070, 0x3b09c, 1783 0x3b0f0, 0x3b128, 1784 0x3b130, 0x3b148, 1785 0x3b160, 0x3b168, 1786 0x3b170, 0x3b19c, 1787 0x3b1f0, 0x3b238, 1788 0x3b240, 0x3b240, 1789 0x3b248, 0x3b250, 1790 0x3b25c, 0x3b264, 1791 0x3b270, 0x3b2b8, 1792 0x3b2c0, 0x3b2e4, 1793 0x3b2f8, 0x3b338, 1794 0x3b340, 0x3b340, 1795 0x3b348, 0x3b350, 1796 0x3b35c, 0x3b364, 1797 0x3b370, 0x3b3b8, 1798 0x3b3c0, 0x3b3e4, 1799 0x3b3f8, 0x3b428, 1800 0x3b430, 0x3b448, 1801 0x3b460, 0x3b468, 1802 0x3b470, 0x3b49c, 1803 0x3b4f0, 0x3b528, 1804 0x3b530, 0x3b548, 1805 0x3b560, 0x3b568, 1806 0x3b570, 0x3b59c, 1807 0x3b5f0, 0x3b638, 1808 0x3b640, 0x3b640, 1809 0x3b648, 0x3b650, 1810 0x3b65c, 0x3b664, 1811 0x3b670, 0x3b6b8, 1812 0x3b6c0, 0x3b6e4, 1813 0x3b6f8, 0x3b738, 1814 0x3b740, 0x3b740, 1815 0x3b748, 0x3b750, 1816 0x3b75c, 0x3b764, 1817 0x3b770, 0x3b7b8, 1818 0x3b7c0, 0x3b7e4, 1819 0x3b7f8, 0x3b7fc, 1820 0x3b814, 0x3b814, 1821 0x3b82c, 0x3b82c, 1822 0x3b880, 0x3b88c, 1823 0x3b8e8, 0x3b8ec, 1824 0x3b900, 0x3b928, 1825 0x3b930, 0x3b948, 1826 0x3b960, 0x3b968, 1827 0x3b970, 0x3b99c, 1828 0x3b9f0, 0x3ba38, 1829 0x3ba40, 0x3ba40, 1830 0x3ba48, 0x3ba50, 1831 0x3ba5c, 0x3ba64, 1832 0x3ba70, 0x3bab8, 1833 0x3bac0, 0x3bae4, 1834 0x3baf8, 0x3bb10, 1835 0x3bb28, 0x3bb28, 1836 0x3bb3c, 0x3bb50, 1837 0x3bbf0, 0x3bc10, 1838 0x3bc28, 0x3bc28, 1839 0x3bc3c, 0x3bc50, 1840 0x3bcf0, 0x3bcfc, 1841 0x3c000, 0x3c030, 1842 0x3c100, 0x3c144, 1843 0x3c190, 0x3c1a0, 1844 0x3c1a8, 0x3c1b8, 1845 0x3c1c4, 0x3c1c8, 1846 0x3c1d0, 0x3c1d0, 1847 0x3c200, 0x3c318, 1848 0x3c400, 0x3c4b4, 1849 0x3c4c0, 0x3c52c, 1850 0x3c540, 0x3c61c, 1851 0x3c800, 0x3c828, 1852 0x3c834, 0x3c834, 1853 0x3c8c0, 0x3c908, 1854 0x3c910, 0x3c9ac, 1855 0x3ca00, 0x3ca14, 1856 0x3ca1c, 0x3ca2c, 1857 0x3ca44, 0x3ca50, 1858 0x3ca74, 0x3ca74, 1859 0x3ca7c, 0x3cafc, 1860 0x3cb08, 0x3cc24, 1861 0x3cd00, 0x3cd00, 1862 0x3cd08, 0x3cd14, 1863 0x3cd1c, 0x3cd20, 1864 0x3cd3c, 0x3cd3c, 1865 0x3cd48, 0x3cd50, 1866 0x3d200, 0x3d20c, 1867 0x3d220, 0x3d220, 1868 0x3d240, 0x3d240, 1869 0x3d600, 0x3d60c, 1870 0x3da00, 0x3da1c, 1871 0x3de00, 0x3de20, 1872 0x3de38, 0x3de3c, 1873 0x3de80, 0x3de80, 1874 0x3de88, 0x3dea8, 1875 0x3deb0, 0x3deb4, 1876 0x3dec8, 0x3ded4, 1877 0x3dfb8, 0x3e004, 1878 0x3e200, 0x3e200, 1879 0x3e208, 0x3e240, 1880 0x3e248, 0x3e280, 1881 0x3e288, 0x3e2c0, 1882 0x3e2c8, 0x3e2fc, 1883 0x3e600, 0x3e630, 1884 0x3ea00, 0x3eabc, 1885 0x3eb00, 0x3eb10, 1886 0x3eb20, 0x3eb30, 1887 0x3eb40, 0x3eb50, 1888 0x3eb60, 0x3eb70, 1889 0x3f000, 0x3f028, 1890 0x3f030, 0x3f048, 1891 0x3f060, 0x3f068, 1892 0x3f070, 0x3f09c, 1893 0x3f0f0, 0x3f128, 1894 0x3f130, 0x3f148, 1895 0x3f160, 0x3f168, 1896 0x3f170, 0x3f19c, 1897 0x3f1f0, 0x3f238, 1898 0x3f240, 0x3f240, 1899 0x3f248, 0x3f250, 1900 0x3f25c, 0x3f264, 1901 0x3f270, 0x3f2b8, 1902 0x3f2c0, 0x3f2e4, 1903 0x3f2f8, 0x3f338, 1904 0x3f340, 0x3f340, 1905 0x3f348, 0x3f350, 1906 0x3f35c, 0x3f364, 1907 0x3f370, 0x3f3b8, 1908 0x3f3c0, 0x3f3e4, 1909 0x3f3f8, 0x3f428, 1910 0x3f430, 0x3f448, 1911 0x3f460, 0x3f468, 1912 0x3f470, 0x3f49c, 1913 0x3f4f0, 0x3f528, 1914 0x3f530, 0x3f548, 1915 0x3f560, 0x3f568, 1916 0x3f570, 0x3f59c, 1917 0x3f5f0, 0x3f638, 1918 0x3f640, 0x3f640, 1919 0x3f648, 0x3f650, 1920 0x3f65c, 0x3f664, 1921 0x3f670, 0x3f6b8, 1922 0x3f6c0, 0x3f6e4, 1923 0x3f6f8, 0x3f738, 1924 0x3f740, 0x3f740, 1925 0x3f748, 0x3f750, 1926 0x3f75c, 0x3f764, 1927 0x3f770, 0x3f7b8, 1928 0x3f7c0, 0x3f7e4, 1929 0x3f7f8, 0x3f7fc, 1930 0x3f814, 0x3f814, 1931 0x3f82c, 0x3f82c, 1932 0x3f880, 0x3f88c, 1933 0x3f8e8, 0x3f8ec, 1934 0x3f900, 0x3f928, 1935 0x3f930, 0x3f948, 1936 0x3f960, 0x3f968, 1937 0x3f970, 0x3f99c, 1938 0x3f9f0, 0x3fa38, 1939 0x3fa40, 0x3fa40, 1940 0x3fa48, 0x3fa50, 1941 0x3fa5c, 0x3fa64, 1942 0x3fa70, 0x3fab8, 1943 0x3fac0, 0x3fae4, 1944 0x3faf8, 0x3fb10, 1945 0x3fb28, 0x3fb28, 1946 0x3fb3c, 0x3fb50, 1947 0x3fbf0, 0x3fc10, 1948 0x3fc28, 0x3fc28, 1949 0x3fc3c, 0x3fc50, 1950 0x3fcf0, 0x3fcfc, 1951 0x40000, 0x4000c, 1952 0x40040, 0x40050, 1953 0x40060, 0x40068, 1954 0x4007c, 0x4008c, 1955 0x40094, 0x400b0, 1956 0x400c0, 0x40144, 1957 0x40180, 0x4018c, 1958 0x40200, 0x40254, 1959 0x40260, 0x40264, 1960 0x40270, 0x40288, 1961 0x40290, 0x40298, 1962 0x402ac, 0x402c8, 1963 0x402d0, 0x402e0, 1964 0x402f0, 0x402f0, 1965 0x40300, 0x4033c, 1966 0x403f8, 0x403fc, 1967 0x41304, 0x413c4, 1968 0x41400, 0x4140c, 1969 0x41414, 0x4141c, 1970 0x41480, 0x414d0, 1971 0x44000, 0x44054, 1972 0x4405c, 0x44078, 1973 0x440c0, 0x44174, 1974 0x44180, 0x441ac, 1975 0x441b4, 0x441b8, 1976 0x441c0, 0x44254, 1977 0x4425c, 0x44278, 1978 0x442c0, 0x44374, 1979 0x44380, 0x443ac, 1980 0x443b4, 0x443b8, 1981 0x443c0, 0x44454, 1982 0x4445c, 0x44478, 1983 0x444c0, 0x44574, 1984 0x44580, 0x445ac, 1985 0x445b4, 0x445b8, 1986 0x445c0, 0x44654, 1987 0x4465c, 0x44678, 1988 0x446c0, 0x44774, 1989 0x44780, 0x447ac, 1990 0x447b4, 0x447b8, 1991 0x447c0, 0x44854, 1992 0x4485c, 0x44878, 1993 0x448c0, 0x44974, 1994 0x44980, 0x449ac, 1995 0x449b4, 0x449b8, 1996 0x449c0, 0x449fc, 1997 0x45000, 0x45004, 1998 0x45010, 0x45030, 1999 0x45040, 0x45060, 2000 0x45068, 0x45068, 2001 0x45080, 0x45084, 2002 0x450a0, 0x450b0, 2003 0x45200, 0x45204, 2004 0x45210, 0x45230, 2005 0x45240, 0x45260, 2006 0x45268, 0x45268, 2007 0x45280, 0x45284, 2008 0x452a0, 0x452b0, 2009 0x460c0, 0x460e4, 2010 0x47000, 0x4703c, 2011 0x47044, 0x4708c, 2012 0x47200, 0x47250, 2013 0x47400, 0x47408, 2014 0x47414, 0x47420, 2015 0x47600, 0x47618, 2016 0x47800, 0x47814, 2017 0x48000, 0x4800c, 2018 0x48040, 0x48050, 2019 0x48060, 0x48068, 2020 0x4807c, 0x4808c, 2021 0x48094, 0x480b0, 2022 0x480c0, 0x48144, 2023 0x48180, 0x4818c, 2024 0x48200, 0x48254, 2025 0x48260, 0x48264, 2026 0x48270, 0x48288, 2027 0x48290, 0x48298, 2028 0x482ac, 0x482c8, 2029 0x482d0, 0x482e0, 2030 0x482f0, 0x482f0, 2031 0x48300, 0x4833c, 2032 0x483f8, 0x483fc, 2033 0x49304, 0x493c4, 2034 0x49400, 0x4940c, 2035 0x49414, 0x4941c, 2036 0x49480, 0x494d0, 2037 0x4c000, 0x4c054, 2038 0x4c05c, 0x4c078, 2039 0x4c0c0, 0x4c174, 2040 0x4c180, 0x4c1ac, 2041 0x4c1b4, 0x4c1b8, 2042 0x4c1c0, 0x4c254, 2043 0x4c25c, 0x4c278, 2044 0x4c2c0, 0x4c374, 2045 0x4c380, 0x4c3ac, 2046 0x4c3b4, 0x4c3b8, 2047 0x4c3c0, 0x4c454, 2048 0x4c45c, 0x4c478, 2049 0x4c4c0, 0x4c574, 2050 0x4c580, 0x4c5ac, 2051 0x4c5b4, 0x4c5b8, 2052 0x4c5c0, 0x4c654, 2053 0x4c65c, 0x4c678, 2054 0x4c6c0, 0x4c774, 2055 0x4c780, 0x4c7ac, 2056 0x4c7b4, 0x4c7b8, 2057 0x4c7c0, 0x4c854, 2058 0x4c85c, 0x4c878, 2059 0x4c8c0, 0x4c974, 2060 0x4c980, 0x4c9ac, 2061 0x4c9b4, 0x4c9b8, 2062 0x4c9c0, 0x4c9fc, 2063 0x4d000, 0x4d004, 2064 0x4d010, 0x4d030, 2065 0x4d040, 0x4d060, 2066 0x4d068, 0x4d068, 2067 0x4d080, 0x4d084, 2068 0x4d0a0, 0x4d0b0, 2069 0x4d200, 0x4d204, 2070 0x4d210, 0x4d230, 2071 0x4d240, 0x4d260, 2072 0x4d268, 0x4d268, 2073 0x4d280, 0x4d284, 2074 0x4d2a0, 0x4d2b0, 2075 0x4e0c0, 0x4e0e4, 2076 0x4f000, 0x4f03c, 2077 0x4f044, 0x4f08c, 2078 0x4f200, 0x4f250, 2079 0x4f400, 0x4f408, 2080 0x4f414, 0x4f420, 2081 0x4f600, 0x4f618, 2082 0x4f800, 0x4f814, 2083 0x50000, 0x50084, 2084 0x50090, 0x500cc, 2085 0x50400, 0x50400, 2086 0x50800, 0x50884, 2087 0x50890, 0x508cc, 2088 0x50c00, 0x50c00, 2089 0x51000, 0x5101c, 2090 0x51300, 0x51308, 2091 }; 2092 2093 static const unsigned int t5vf_reg_ranges[] = { 2094 VF_SGE_REG(A_SGE_VF_KDOORBELL), VF_SGE_REG(A_SGE_VF_GTS), 2095 VF_MPS_REG(A_MPS_VF_CTL), 2096 VF_MPS_REG(A_MPS_VF_STAT_RX_VF_ERR_FRAMES_H), 2097 VF_PL_REG(A_PL_VF_WHOAMI), VF_PL_REG(A_PL_VF_REVISION), 2098 VF_CIM_REG(A_CIM_VF_EXT_MAILBOX_CTRL), 2099 VF_CIM_REG(A_CIM_VF_EXT_MAILBOX_STATUS), 2100 FW_T4VF_MBDATA_BASE_ADDR, 2101 FW_T4VF_MBDATA_BASE_ADDR + 2102 ((NUM_CIM_PF_MAILBOX_DATA_INSTANCES - 1) * 4), 2103 }; 2104 2105 static const unsigned int t6_reg_ranges[] = { 2106 0x1008, 0x101c, 2107 0x1024, 0x10a8, 2108 0x10b4, 0x10f8, 2109 0x1100, 0x1114, 2110 0x111c, 0x112c, 2111 0x1138, 0x113c, 2112 0x1144, 0x114c, 2113 0x1180, 0x1184, 2114 0x1190, 0x1194, 2115 0x11a0, 0x11a4, 2116 0x11b0, 0x11c4, 2117 0x11fc, 0x123c, 2118 0x1254, 0x1274, 2119 0x1280, 0x133c, 2120 0x1800, 0x18fc, 2121 0x3000, 0x302c, 2122 0x3060, 0x30b0, 2123 0x30b8, 0x30d8, 2124 0x30e0, 0x30fc, 2125 0x3140, 0x357c, 2126 0x35a8, 0x35cc, 2127 0x35ec, 0x35ec, 2128 0x3600, 0x5624, 2129 0x56cc, 0x56ec, 2130 0x56f4, 0x5720, 2131 0x5728, 0x575c, 2132 0x580c, 0x5814, 2133 0x5890, 0x589c, 2134 0x58a4, 0x58ac, 2135 0x58b8, 0x58bc, 2136 0x5940, 0x595c, 2137 0x5980, 0x598c, 2138 0x59b0, 0x59c8, 2139 0x59d0, 0x59dc, 2140 0x59fc, 0x5a18, 2141 0x5a60, 0x5a6c, 2142 0x5a80, 0x5a8c, 2143 0x5a94, 0x5a9c, 2144 0x5b94, 0x5bfc, 2145 0x5c10, 0x5e48, 2146 0x5e50, 0x5e94, 2147 0x5ea0, 0x5eb0, 2148 0x5ec0, 0x5ec0, 2149 0x5ec8, 0x5ed0, 2150 0x5ee0, 0x5ee0, 2151 0x5ef0, 0x5ef0, 2152 0x5f00, 0x5f00, 2153 0x6000, 0x6020, 2154 0x6028, 0x6040, 2155 0x6058, 0x609c, 2156 0x60a8, 0x619c, 2157 0x7700, 0x7798, 2158 0x77c0, 0x7880, 2159 0x78cc, 0x78fc, 2160 0x7b00, 0x7b58, 2161 0x7b60, 0x7b84, 2162 0x7b8c, 0x7c54, 2163 0x7d00, 0x7d38, 2164 0x7d40, 0x7d84, 2165 0x7d8c, 0x7ddc, 2166 0x7de4, 0x7e04, 2167 0x7e10, 0x7e1c, 2168 0x7e24, 0x7e38, 2169 0x7e40, 0x7e44, 2170 0x7e4c, 0x7e78, 2171 0x7e80, 0x7edc, 2172 0x7ee8, 0x7efc, 2173 0x8dc0, 0x8de0, 2174 0x8df8, 0x8e04, 2175 0x8e10, 0x8e84, 2176 0x8ea0, 0x8f88, 2177 0x8fb8, 0x9058, 2178 0x9060, 0x9060, 2179 0x9068, 0x90f8, 2180 0x9100, 0x9124, 2181 0x9400, 0x9470, 2182 0x9600, 0x9600, 2183 0x9608, 0x9638, 2184 0x9640, 0x9704, 2185 0x9710, 0x971c, 2186 0x9800, 0x9808, 2187 0x9810, 0x9864, 2188 0x9c00, 0x9c6c, 2189 0x9c80, 0x9cec, 2190 0x9d00, 0x9d6c, 2191 0x9d80, 0x9dec, 2192 0x9e00, 0x9e6c, 2193 0x9e80, 0x9eec, 2194 0x9f00, 0x9f6c, 2195 0x9f80, 0xa020, 2196 0xd000, 0xd03c, 2197 0xd100, 0xd118, 2198 0xd200, 0xd214, 2199 0xd220, 0xd234, 2200 0xd240, 0xd254, 2201 0xd260, 0xd274, 2202 0xd280, 0xd294, 2203 0xd2a0, 0xd2b4, 2204 0xd2c0, 0xd2d4, 2205 0xd2e0, 0xd2f4, 2206 0xd300, 0xd31c, 2207 0xdfc0, 0xdfe0, 2208 0xe000, 0xf008, 2209 0xf010, 0xf018, 2210 0xf020, 0xf028, 2211 0x11000, 0x11014, 2212 0x11048, 0x1106c, 2213 0x11074, 0x11088, 2214 0x11098, 0x11120, 2215 0x1112c, 0x1117c, 2216 0x11190, 0x112e0, 2217 0x11300, 0x1130c, 2218 0x12000, 0x1206c, 2219 0x19040, 0x1906c, 2220 0x19078, 0x19080, 2221 0x1908c, 0x190e8, 2222 0x190f0, 0x190f8, 2223 0x19100, 0x19110, 2224 0x19120, 0x19124, 2225 0x19150, 0x19194, 2226 0x1919c, 0x191b0, 2227 0x191d0, 0x191e8, 2228 0x19238, 0x19290, 2229 0x192a4, 0x192b0, 2230 0x19348, 0x1934c, 2231 0x193f8, 0x19418, 2232 0x19420, 0x19428, 2233 0x19430, 0x19444, 2234 0x1944c, 0x1946c, 2235 0x19474, 0x19474, 2236 0x19490, 0x194cc, 2237 0x194f0, 0x194f8, 2238 0x19c00, 0x19c48, 2239 0x19c50, 0x19c80, 2240 0x19c94, 0x19c98, 2241 0x19ca0, 0x19cbc, 2242 0x19ce4, 0x19ce4, 2243 0x19cf0, 0x19cf8, 2244 0x19d00, 0x19d28, 2245 0x19d50, 0x19d78, 2246 0x19d94, 0x19d98, 2247 0x19da0, 0x19de0, 2248 0x19df0, 0x19e10, 2249 0x19e50, 0x19e6c, 2250 0x19ea0, 0x19ebc, 2251 0x19ec4, 0x19ef4, 2252 0x19f04, 0x19f2c, 2253 0x19f34, 0x19f34, 2254 0x19f40, 0x19f50, 2255 0x19f90, 0x19fac, 2256 0x19fc4, 0x19fc8, 2257 0x19fd0, 0x19fe4, 2258 0x1a000, 0x1a004, 2259 0x1a010, 0x1a06c, 2260 0x1a0b0, 0x1a0e4, 2261 0x1a0ec, 0x1a0f8, 2262 0x1a100, 0x1a108, 2263 0x1a114, 0x1a130, 2264 0x1a138, 0x1a1c4, 2265 0x1a1fc, 0x1a1fc, 2266 0x1e008, 0x1e00c, 2267 0x1e040, 0x1e044, 2268 0x1e04c, 0x1e04c, 2269 0x1e284, 0x1e290, 2270 0x1e2c0, 0x1e2c0, 2271 0x1e2e0, 0x1e2e0, 2272 0x1e300, 0x1e384, 2273 0x1e3c0, 0x1e3c8, 2274 0x1e408, 0x1e40c, 2275 0x1e440, 0x1e444, 2276 0x1e44c, 0x1e44c, 2277 0x1e684, 0x1e690, 2278 0x1e6c0, 0x1e6c0, 2279 0x1e6e0, 0x1e6e0, 2280 0x1e700, 0x1e784, 2281 0x1e7c0, 0x1e7c8, 2282 0x1e808, 0x1e80c, 2283 0x1e840, 0x1e844, 2284 0x1e84c, 0x1e84c, 2285 0x1ea84, 0x1ea90, 2286 0x1eac0, 0x1eac0, 2287 0x1eae0, 0x1eae0, 2288 0x1eb00, 0x1eb84, 2289 0x1ebc0, 0x1ebc8, 2290 0x1ec08, 0x1ec0c, 2291 0x1ec40, 0x1ec44, 2292 0x1ec4c, 0x1ec4c, 2293 0x1ee84, 0x1ee90, 2294 0x1eec0, 0x1eec0, 2295 0x1eee0, 0x1eee0, 2296 0x1ef00, 0x1ef84, 2297 0x1efc0, 0x1efc8, 2298 0x1f008, 0x1f00c, 2299 0x1f040, 0x1f044, 2300 0x1f04c, 0x1f04c, 2301 0x1f284, 0x1f290, 2302 0x1f2c0, 0x1f2c0, 2303 0x1f2e0, 0x1f2e0, 2304 0x1f300, 0x1f384, 2305 0x1f3c0, 0x1f3c8, 2306 0x1f408, 0x1f40c, 2307 0x1f440, 0x1f444, 2308 0x1f44c, 0x1f44c, 2309 0x1f684, 0x1f690, 2310 0x1f6c0, 0x1f6c0, 2311 0x1f6e0, 0x1f6e0, 2312 0x1f700, 0x1f784, 2313 0x1f7c0, 0x1f7c8, 2314 0x1f808, 0x1f80c, 2315 0x1f840, 0x1f844, 2316 0x1f84c, 0x1f84c, 2317 0x1fa84, 0x1fa90, 2318 0x1fac0, 0x1fac0, 2319 0x1fae0, 0x1fae0, 2320 0x1fb00, 0x1fb84, 2321 0x1fbc0, 0x1fbc8, 2322 0x1fc08, 0x1fc0c, 2323 0x1fc40, 0x1fc44, 2324 0x1fc4c, 0x1fc4c, 2325 0x1fe84, 0x1fe90, 2326 0x1fec0, 0x1fec0, 2327 0x1fee0, 0x1fee0, 2328 0x1ff00, 0x1ff84, 2329 0x1ffc0, 0x1ffc8, 2330 0x30000, 0x30030, 2331 0x30100, 0x30168, 2332 0x30190, 0x301a0, 2333 0x301a8, 0x301b8, 2334 0x301c4, 0x301c8, 2335 0x301d0, 0x301d0, 2336 0x30200, 0x30320, 2337 0x30400, 0x304b4, 2338 0x304c0, 0x3052c, 2339 0x30540, 0x3061c, 2340 0x30800, 0x308a0, 2341 0x308c0, 0x30908, 2342 0x30910, 0x309b8, 2343 0x30a00, 0x30a04, 2344 0x30a0c, 0x30a14, 2345 0x30a1c, 0x30a2c, 2346 0x30a44, 0x30a50, 2347 0x30a74, 0x30a74, 2348 0x30a7c, 0x30afc, 2349 0x30b08, 0x30c24, 2350 0x30d00, 0x30d14, 2351 0x30d1c, 0x30d3c, 2352 0x30d44, 0x30d4c, 2353 0x30d54, 0x30d74, 2354 0x30d7c, 0x30d7c, 2355 0x30de0, 0x30de0, 2356 0x30e00, 0x30ed4, 2357 0x30f00, 0x30fa4, 2358 0x30fc0, 0x30fc4, 2359 0x31000, 0x31004, 2360 0x31080, 0x310fc, 2361 0x31208, 0x31220, 2362 0x3123c, 0x31254, 2363 0x31300, 0x31300, 2364 0x31308, 0x3131c, 2365 0x31338, 0x3133c, 2366 0x31380, 0x31380, 2367 0x31388, 0x313a8, 2368 0x313b4, 0x313b4, 2369 0x31400, 0x31420, 2370 0x31438, 0x3143c, 2371 0x31480, 0x31480, 2372 0x314a8, 0x314a8, 2373 0x314b0, 0x314b4, 2374 0x314c8, 0x314d4, 2375 0x31a40, 0x31a4c, 2376 0x31af0, 0x31b20, 2377 0x31b38, 0x31b3c, 2378 0x31b80, 0x31b80, 2379 0x31ba8, 0x31ba8, 2380 0x31bb0, 0x31bb4, 2381 0x31bc8, 0x31bd4, 2382 0x32140, 0x3218c, 2383 0x321f0, 0x321f4, 2384 0x32200, 0x32200, 2385 0x32218, 0x32218, 2386 0x32400, 0x32400, 2387 0x32408, 0x3241c, 2388 0x32618, 0x32620, 2389 0x32664, 0x32664, 2390 0x326a8, 0x326a8, 2391 0x326ec, 0x326ec, 2392 0x32a00, 0x32abc, 2393 0x32b00, 0x32b18, 2394 0x32b20, 0x32b38, 2395 0x32b40, 0x32b58, 2396 0x32b60, 0x32b78, 2397 0x32c00, 0x32c00, 2398 0x32c08, 0x32c3c, 2399 0x33000, 0x3302c, 2400 0x33034, 0x33050, 2401 0x33058, 0x33058, 2402 0x33060, 0x3308c, 2403 0x3309c, 0x330ac, 2404 0x330c0, 0x330c0, 2405 0x330c8, 0x330d0, 2406 0x330d8, 0x330e0, 2407 0x330ec, 0x3312c, 2408 0x33134, 0x33150, 2409 0x33158, 0x33158, 2410 0x33160, 0x3318c, 2411 0x3319c, 0x331ac, 2412 0x331c0, 0x331c0, 2413 0x331c8, 0x331d0, 2414 0x331d8, 0x331e0, 2415 0x331ec, 0x33290, 2416 0x33298, 0x332c4, 2417 0x332e4, 0x33390, 2418 0x33398, 0x333c4, 2419 0x333e4, 0x3342c, 2420 0x33434, 0x33450, 2421 0x33458, 0x33458, 2422 0x33460, 0x3348c, 2423 0x3349c, 0x334ac, 2424 0x334c0, 0x334c0, 2425 0x334c8, 0x334d0, 2426 0x334d8, 0x334e0, 2427 0x334ec, 0x3352c, 2428 0x33534, 0x33550, 2429 0x33558, 0x33558, 2430 0x33560, 0x3358c, 2431 0x3359c, 0x335ac, 2432 0x335c0, 0x335c0, 2433 0x335c8, 0x335d0, 2434 0x335d8, 0x335e0, 2435 0x335ec, 0x33690, 2436 0x33698, 0x336c4, 2437 0x336e4, 0x33790, 2438 0x33798, 0x337c4, 2439 0x337e4, 0x337fc, 2440 0x33814, 0x33814, 2441 0x33854, 0x33868, 2442 0x33880, 0x3388c, 2443 0x338c0, 0x338d0, 2444 0x338e8, 0x338ec, 2445 0x33900, 0x3392c, 2446 0x33934, 0x33950, 2447 0x33958, 0x33958, 2448 0x33960, 0x3398c, 2449 0x3399c, 0x339ac, 2450 0x339c0, 0x339c0, 2451 0x339c8, 0x339d0, 2452 0x339d8, 0x339e0, 2453 0x339ec, 0x33a90, 2454 0x33a98, 0x33ac4, 2455 0x33ae4, 0x33b10, 2456 0x33b24, 0x33b28, 2457 0x33b38, 0x33b50, 2458 0x33bf0, 0x33c10, 2459 0x33c24, 0x33c28, 2460 0x33c38, 0x33c50, 2461 0x33cf0, 0x33cfc, 2462 0x34000, 0x34030, 2463 0x34100, 0x34168, 2464 0x34190, 0x341a0, 2465 0x341a8, 0x341b8, 2466 0x341c4, 0x341c8, 2467 0x341d0, 0x341d0, 2468 0x34200, 0x34320, 2469 0x34400, 0x344b4, 2470 0x344c0, 0x3452c, 2471 0x34540, 0x3461c, 2472 0x34800, 0x348a0, 2473 0x348c0, 0x34908, 2474 0x34910, 0x349b8, 2475 0x34a00, 0x34a04, 2476 0x34a0c, 0x34a14, 2477 0x34a1c, 0x34a2c, 2478 0x34a44, 0x34a50, 2479 0x34a74, 0x34a74, 2480 0x34a7c, 0x34afc, 2481 0x34b08, 0x34c24, 2482 0x34d00, 0x34d14, 2483 0x34d1c, 0x34d3c, 2484 0x34d44, 0x34d4c, 2485 0x34d54, 0x34d74, 2486 0x34d7c, 0x34d7c, 2487 0x34de0, 0x34de0, 2488 0x34e00, 0x34ed4, 2489 0x34f00, 0x34fa4, 2490 0x34fc0, 0x34fc4, 2491 0x35000, 0x35004, 2492 0x35080, 0x350fc, 2493 0x35208, 0x35220, 2494 0x3523c, 0x35254, 2495 0x35300, 0x35300, 2496 0x35308, 0x3531c, 2497 0x35338, 0x3533c, 2498 0x35380, 0x35380, 2499 0x35388, 0x353a8, 2500 0x353b4, 0x353b4, 2501 0x35400, 0x35420, 2502 0x35438, 0x3543c, 2503 0x35480, 0x35480, 2504 0x354a8, 0x354a8, 2505 0x354b0, 0x354b4, 2506 0x354c8, 0x354d4, 2507 0x35a40, 0x35a4c, 2508 0x35af0, 0x35b20, 2509 0x35b38, 0x35b3c, 2510 0x35b80, 0x35b80, 2511 0x35ba8, 0x35ba8, 2512 0x35bb0, 0x35bb4, 2513 0x35bc8, 0x35bd4, 2514 0x36140, 0x3618c, 2515 0x361f0, 0x361f4, 2516 0x36200, 0x36200, 2517 0x36218, 0x36218, 2518 0x36400, 0x36400, 2519 0x36408, 0x3641c, 2520 0x36618, 0x36620, 2521 0x36664, 0x36664, 2522 0x366a8, 0x366a8, 2523 0x366ec, 0x366ec, 2524 0x36a00, 0x36abc, 2525 0x36b00, 0x36b18, 2526 0x36b20, 0x36b38, 2527 0x36b40, 0x36b58, 2528 0x36b60, 0x36b78, 2529 0x36c00, 0x36c00, 2530 0x36c08, 0x36c3c, 2531 0x37000, 0x3702c, 2532 0x37034, 0x37050, 2533 0x37058, 0x37058, 2534 0x37060, 0x3708c, 2535 0x3709c, 0x370ac, 2536 0x370c0, 0x370c0, 2537 0x370c8, 0x370d0, 2538 0x370d8, 0x370e0, 2539 0x370ec, 0x3712c, 2540 0x37134, 0x37150, 2541 0x37158, 0x37158, 2542 0x37160, 0x3718c, 2543 0x3719c, 0x371ac, 2544 0x371c0, 0x371c0, 2545 0x371c8, 0x371d0, 2546 0x371d8, 0x371e0, 2547 0x371ec, 0x37290, 2548 0x37298, 0x372c4, 2549 0x372e4, 0x37390, 2550 0x37398, 0x373c4, 2551 0x373e4, 0x3742c, 2552 0x37434, 0x37450, 2553 0x37458, 0x37458, 2554 0x37460, 0x3748c, 2555 0x3749c, 0x374ac, 2556 0x374c0, 0x374c0, 2557 0x374c8, 0x374d0, 2558 0x374d8, 0x374e0, 2559 0x374ec, 0x3752c, 2560 0x37534, 0x37550, 2561 0x37558, 0x37558, 2562 0x37560, 0x3758c, 2563 0x3759c, 0x375ac, 2564 0x375c0, 0x375c0, 2565 0x375c8, 0x375d0, 2566 0x375d8, 0x375e0, 2567 0x375ec, 0x37690, 2568 0x37698, 0x376c4, 2569 0x376e4, 0x37790, 2570 0x37798, 0x377c4, 2571 0x377e4, 0x377fc, 2572 0x37814, 0x37814, 2573 0x37854, 0x37868, 2574 0x37880, 0x3788c, 2575 0x378c0, 0x378d0, 2576 0x378e8, 0x378ec, 2577 0x37900, 0x3792c, 2578 0x37934, 0x37950, 2579 0x37958, 0x37958, 2580 0x37960, 0x3798c, 2581 0x3799c, 0x379ac, 2582 0x379c0, 0x379c0, 2583 0x379c8, 0x379d0, 2584 0x379d8, 0x379e0, 2585 0x379ec, 0x37a90, 2586 0x37a98, 0x37ac4, 2587 0x37ae4, 0x37b10, 2588 0x37b24, 0x37b28, 2589 0x37b38, 0x37b50, 2590 0x37bf0, 0x37c10, 2591 0x37c24, 0x37c28, 2592 0x37c38, 0x37c50, 2593 0x37cf0, 0x37cfc, 2594 0x40040, 0x40040, 2595 0x40080, 0x40084, 2596 0x40100, 0x40100, 2597 0x40140, 0x401bc, 2598 0x40200, 0x40214, 2599 0x40228, 0x40228, 2600 0x40240, 0x40258, 2601 0x40280, 0x40280, 2602 0x40304, 0x40304, 2603 0x40330, 0x4033c, 2604 0x41304, 0x413c8, 2605 0x413d0, 0x413dc, 2606 0x413f0, 0x413f0, 2607 0x41400, 0x4140c, 2608 0x41414, 0x4141c, 2609 0x41480, 0x414d0, 2610 0x44000, 0x4407c, 2611 0x440c0, 0x441ac, 2612 0x441b4, 0x4427c, 2613 0x442c0, 0x443ac, 2614 0x443b4, 0x4447c, 2615 0x444c0, 0x445ac, 2616 0x445b4, 0x4467c, 2617 0x446c0, 0x447ac, 2618 0x447b4, 0x4487c, 2619 0x448c0, 0x449ac, 2620 0x449b4, 0x44a7c, 2621 0x44ac0, 0x44bac, 2622 0x44bb4, 0x44c7c, 2623 0x44cc0, 0x44dac, 2624 0x44db4, 0x44e7c, 2625 0x44ec0, 0x44fac, 2626 0x44fb4, 0x4507c, 2627 0x450c0, 0x451ac, 2628 0x451b4, 0x451fc, 2629 0x45800, 0x45804, 2630 0x45810, 0x45830, 2631 0x45840, 0x45860, 2632 0x45868, 0x45868, 2633 0x45880, 0x45884, 2634 0x458a0, 0x458b0, 2635 0x45a00, 0x45a04, 2636 0x45a10, 0x45a30, 2637 0x45a40, 0x45a60, 2638 0x45a68, 0x45a68, 2639 0x45a80, 0x45a84, 2640 0x45aa0, 0x45ab0, 2641 0x460c0, 0x460e4, 2642 0x47000, 0x4703c, 2643 0x47044, 0x4708c, 2644 0x47200, 0x47250, 2645 0x47400, 0x47408, 2646 0x47414, 0x47420, 2647 0x47600, 0x47618, 2648 0x47800, 0x47814, 2649 0x47820, 0x4782c, 2650 0x50000, 0x50084, 2651 0x50090, 0x500cc, 2652 0x50300, 0x50384, 2653 0x50400, 0x50400, 2654 0x50800, 0x50884, 2655 0x50890, 0x508cc, 2656 0x50b00, 0x50b84, 2657 0x50c00, 0x50c00, 2658 0x51000, 0x51020, 2659 0x51028, 0x510b0, 2660 0x51300, 0x51324, 2661 }; 2662 2663 static const unsigned int t6vf_reg_ranges[] = { 2664 VF_SGE_REG(A_SGE_VF_KDOORBELL), VF_SGE_REG(A_SGE_VF_GTS), 2665 VF_MPS_REG(A_MPS_VF_CTL), 2666 VF_MPS_REG(A_MPS_VF_STAT_RX_VF_ERR_FRAMES_H), 2667 VF_PL_REG(A_PL_VF_WHOAMI), VF_PL_REG(A_PL_VF_REVISION), 2668 VF_CIM_REG(A_CIM_VF_EXT_MAILBOX_CTRL), 2669 VF_CIM_REG(A_CIM_VF_EXT_MAILBOX_STATUS), 2670 FW_T6VF_MBDATA_BASE_ADDR, 2671 FW_T6VF_MBDATA_BASE_ADDR + 2672 ((NUM_CIM_PF_MAILBOX_DATA_INSTANCES - 1) * 4), 2673 }; 2674 2675 static const unsigned int t7_reg_ranges[] = { 2676 0x1008, 0x101c, 2677 0x1024, 0x10a8, 2678 0x10b4, 0x10f8, 2679 0x1100, 0x1114, 2680 0x111c, 0x112c, 2681 0x1138, 0x113c, 2682 0x1144, 0x115c, 2683 0x1180, 0x1184, 2684 0x1190, 0x1194, 2685 0x11a0, 0x11a4, 2686 0x11b0, 0x11d0, 2687 0x11fc, 0x1278, 2688 0x1280, 0x1368, 2689 0x1700, 0x172c, 2690 0x173c, 0x1760, 2691 0x1800, 0x18fc, 2692 0x3000, 0x3044, 2693 0x30a4, 0x30b0, 2694 0x30b8, 0x30d8, 2695 0x30e0, 0x30e8, 2696 0x3140, 0x357c, 2697 0x35a8, 0x35cc, 2698 0x35e0, 0x35ec, 2699 0x3600, 0x37fc, 2700 0x3804, 0x3818, 2701 0x3880, 0x388c, 2702 0x3900, 0x3904, 2703 0x3910, 0x3978, 2704 0x3980, 0x399c, 2705 0x4700, 0x4720, 2706 0x4728, 0x475c, 2707 0x480c, 0x4814, 2708 0x4890, 0x489c, 2709 0x48a4, 0x48ac, 2710 0x48b8, 0x48bc, 2711 0x4900, 0x4924, 2712 0x4ffc, 0x4ffc, 2713 0x5500, 0x5624, 2714 0x56c4, 0x56ec, 2715 0x56f4, 0x5720, 2716 0x5728, 0x575c, 2717 0x580c, 0x5814, 2718 0x5890, 0x589c, 2719 0x58a4, 0x58ac, 2720 0x58b8, 0x58bc, 2721 0x5940, 0x598c, 2722 0x59b0, 0x59c8, 2723 0x59d0, 0x59dc, 2724 0x59fc, 0x5a18, 2725 0x5a60, 0x5a6c, 2726 0x5a80, 0x5a8c, 2727 0x5a94, 0x5a9c, 2728 0x5b94, 0x5bec, 2729 0x5bf8, 0x5bfc, 2730 0x5c10, 0x5c40, 2731 0x5c4c, 0x5e48, 2732 0x5e50, 0x5e94, 2733 0x5ea0, 0x5eb0, 2734 0x5ec0, 0x5ec0, 2735 0x5ec8, 0x5ed0, 2736 0x5ee0, 0x5ee0, 2737 0x5ef0, 0x5ef0, 2738 0x5f00, 0x5f04, 2739 0x5f0c, 0x5f10, 2740 0x5f20, 0x5f78, 2741 0x5f84, 0x5f88, 2742 0x5f90, 0x5fd8, 2743 0x6000, 0x6020, 2744 0x6028, 0x6030, 2745 0x6044, 0x609c, 2746 0x60a8, 0x60ac, 2747 0x60b8, 0x60ec, 2748 0x6100, 0x6104, 2749 0x6118, 0x611c, 2750 0x6150, 0x6150, 2751 0x6180, 0x61b8, 2752 0x7700, 0x77a8, 2753 0x77b0, 0x7888, 2754 0x78cc, 0x7970, 2755 0x7b00, 0x7b00, 2756 0x7b08, 0x7b0c, 2757 0x7b24, 0x7b84, 2758 0x7b8c, 0x7c2c, 2759 0x7c34, 0x7c40, 2760 0x7c48, 0x7c68, 2761 0x7c70, 0x7c7c, 2762 0x7d00, 0x7ddc, 2763 0x7de4, 0x7e38, 2764 0x7e40, 0x7e44, 2765 0x7e4c, 0x7e74, 2766 0x7e80, 0x7ee0, 2767 0x7ee8, 0x7f0c, 2768 0x7f20, 0x7f5c, 2769 0x8dc0, 0x8de8, 2770 0x8df8, 0x8e04, 2771 0x8e10, 0x8e30, 2772 0x8e7c, 0x8ee8, 2773 0x8f88, 0x8f88, 2774 0x8f90, 0x8fb0, 2775 0x8fb8, 0x9058, 2776 0x9074, 0x90f8, 2777 0x9100, 0x912c, 2778 0x9138, 0x9188, 2779 0x9400, 0x9414, 2780 0x9430, 0x9440, 2781 0x9454, 0x9454, 2782 0x945c, 0x947c, 2783 0x9498, 0x94b8, 2784 0x9600, 0x9600, 2785 0x9608, 0x9638, 2786 0x9640, 0x9704, 2787 0x9710, 0x971c, 2788 0x9800, 0x9804, 2789 0x9854, 0x9854, 2790 0x9c00, 0x9c6c, 2791 0x9c80, 0x9cec, 2792 0x9d00, 0x9d6c, 2793 0x9d80, 0x9dec, 2794 0x9e00, 0x9e6c, 2795 0x9e80, 0x9eec, 2796 0x9f00, 0x9f6c, 2797 0x9f80, 0x9fec, 2798 0xa000, 0xa06c, 2799 0xa080, 0xa0ec, 2800 0xa100, 0xa16c, 2801 0xa180, 0xa1ec, 2802 0xa200, 0xa26c, 2803 0xa280, 0xa2ec, 2804 0xa300, 0xa36c, 2805 0xa380, 0xa458, 2806 0xa460, 0xa4f8, 2807 0xd000, 0xd03c, 2808 0xd100, 0xd134, 2809 0xd200, 0xd214, 2810 0xd220, 0xd234, 2811 0xd240, 0xd254, 2812 0xd260, 0xd274, 2813 0xd280, 0xd294, 2814 0xd2a0, 0xd2b4, 2815 0xd2c0, 0xd2d4, 2816 0xd2e0, 0xd2f4, 2817 0xd300, 0xd31c, 2818 0xdfc0, 0xdfe0, 2819 0xe000, 0xe00c, 2820 0xf000, 0xf008, 2821 0xf010, 0xf06c, 2822 0x11000, 0x11014, 2823 0x11048, 0x11120, 2824 0x11130, 0x11144, 2825 0x11174, 0x11178, 2826 0x11190, 0x111a0, 2827 0x111e4, 0x112f0, 2828 0x11300, 0x1133c, 2829 0x11408, 0x1146c, 2830 0x12000, 0x12004, 2831 0x12060, 0x122c4, 2832 0x19040, 0x1906c, 2833 0x19078, 0x19080, 2834 0x1908c, 0x190e8, 2835 0x190f0, 0x190f8, 2836 0x19100, 0x19110, 2837 0x19120, 0x19124, 2838 0x19150, 0x19194, 2839 0x1919c, 0x191a0, 2840 0x191ac, 0x191c8, 2841 0x191d0, 0x191e4, 2842 0x19250, 0x19250, 2843 0x19258, 0x19268, 2844 0x19278, 0x19278, 2845 0x19280, 0x192b0, 2846 0x192bc, 0x192f0, 2847 0x19300, 0x19308, 2848 0x19310, 0x19318, 2849 0x19320, 0x19328, 2850 0x19330, 0x19330, 2851 0x19348, 0x1934c, 2852 0x193f8, 0x19428, 2853 0x19430, 0x19444, 2854 0x1944c, 0x1946c, 2855 0x19474, 0x1947c, 2856 0x19488, 0x194cc, 2857 0x194f0, 0x194f8, 2858 0x19c00, 0x19c48, 2859 0x19c50, 0x19c80, 2860 0x19c94, 0x19c98, 2861 0x19ca0, 0x19cdc, 2862 0x19ce4, 0x19cf8, 2863 0x19d00, 0x19d30, 2864 0x19d50, 0x19d80, 2865 0x19d94, 0x19d98, 2866 0x19da0, 0x19de0, 2867 0x19df0, 0x19e10, 2868 0x19e50, 0x19e6c, 2869 0x19ea0, 0x19ebc, 2870 0x19ec4, 0x19ef4, 2871 0x19f04, 0x19f2c, 2872 0x19f34, 0x19f34, 2873 0x19f40, 0x19f50, 2874 0x19f90, 0x19fb4, 2875 0x19fbc, 0x19fbc, 2876 0x19fc4, 0x19fc8, 2877 0x19fd0, 0x19fe4, 2878 0x1a000, 0x1a004, 2879 0x1a010, 0x1a06c, 2880 0x1a0b0, 0x1a0e4, 2881 0x1a0ec, 0x1a108, 2882 0x1a114, 0x1a130, 2883 0x1a138, 0x1a1c4, 2884 0x1a1fc, 0x1a29c, 2885 0x1a2a8, 0x1a2b8, 2886 0x1a2c0, 0x1a388, 2887 0x1a398, 0x1a3ac, 2888 0x1e008, 0x1e00c, 2889 0x1e040, 0x1e044, 2890 0x1e04c, 0x1e04c, 2891 0x1e284, 0x1e290, 2892 0x1e2c0, 0x1e2c0, 2893 0x1e2e0, 0x1e2e4, 2894 0x1e300, 0x1e384, 2895 0x1e3c0, 0x1e3c8, 2896 0x1e408, 0x1e40c, 2897 0x1e440, 0x1e444, 2898 0x1e44c, 0x1e44c, 2899 0x1e684, 0x1e690, 2900 0x1e6c0, 0x1e6c0, 2901 0x1e6e0, 0x1e6e4, 2902 0x1e700, 0x1e784, 2903 0x1e7c0, 0x1e7c8, 2904 0x1e808, 0x1e80c, 2905 0x1e840, 0x1e844, 2906 0x1e84c, 0x1e84c, 2907 0x1ea84, 0x1ea90, 2908 0x1eac0, 0x1eac0, 2909 0x1eae0, 0x1eae4, 2910 0x1eb00, 0x1eb84, 2911 0x1ebc0, 0x1ebc8, 2912 0x1ec08, 0x1ec0c, 2913 0x1ec40, 0x1ec44, 2914 0x1ec4c, 0x1ec4c, 2915 0x1ee84, 0x1ee90, 2916 0x1eec0, 0x1eec0, 2917 0x1eee0, 0x1eee4, 2918 0x1ef00, 0x1ef84, 2919 0x1efc0, 0x1efc8, 2920 0x1f008, 0x1f00c, 2921 0x1f040, 0x1f044, 2922 0x1f04c, 0x1f04c, 2923 0x1f284, 0x1f290, 2924 0x1f2c0, 0x1f2c0, 2925 0x1f2e0, 0x1f2e4, 2926 0x1f300, 0x1f384, 2927 0x1f3c0, 0x1f3c8, 2928 0x1f408, 0x1f40c, 2929 0x1f440, 0x1f444, 2930 0x1f44c, 0x1f44c, 2931 0x1f684, 0x1f690, 2932 0x1f6c0, 0x1f6c0, 2933 0x1f6e0, 0x1f6e4, 2934 0x1f700, 0x1f784, 2935 0x1f7c0, 0x1f7c8, 2936 0x1f808, 0x1f80c, 2937 0x1f840, 0x1f844, 2938 0x1f84c, 0x1f84c, 2939 0x1fa84, 0x1fa90, 2940 0x1fac0, 0x1fac0, 2941 0x1fae0, 0x1fae4, 2942 0x1fb00, 0x1fb84, 2943 0x1fbc0, 0x1fbc8, 2944 0x1fc08, 0x1fc0c, 2945 0x1fc40, 0x1fc44, 2946 0x1fc4c, 0x1fc4c, 2947 0x1fe84, 0x1fe90, 2948 0x1fec0, 0x1fec0, 2949 0x1fee0, 0x1fee4, 2950 0x1ff00, 0x1ff84, 2951 0x1ffc0, 0x1ffc8, 2952 0x30000, 0x30038, 2953 0x30100, 0x3017c, 2954 0x30190, 0x301a0, 2955 0x301a8, 0x301b8, 2956 0x301c4, 0x301c8, 2957 0x301d0, 0x301e0, 2958 0x30200, 0x30344, 2959 0x30400, 0x304b4, 2960 0x304c0, 0x3052c, 2961 0x30540, 0x3065c, 2962 0x30800, 0x30848, 2963 0x30850, 0x308a8, 2964 0x308b8, 0x308c0, 2965 0x308cc, 0x308dc, 2966 0x30900, 0x30904, 2967 0x3090c, 0x30914, 2968 0x3091c, 0x30928, 2969 0x30930, 0x3093c, 2970 0x30944, 0x30948, 2971 0x30954, 0x30974, 2972 0x3097c, 0x30980, 2973 0x30a00, 0x30a20, 2974 0x30a38, 0x30a3c, 2975 0x30a50, 0x30a50, 2976 0x30a80, 0x30a80, 2977 0x30a88, 0x30aa8, 2978 0x30ab0, 0x30ab4, 2979 0x30ac8, 0x30ad4, 2980 0x30b28, 0x30b84, 2981 0x30b98, 0x30bb8, 2982 0x30c98, 0x30d14, 2983 0x31000, 0x31020, 2984 0x31038, 0x3103c, 2985 0x31050, 0x31050, 2986 0x31080, 0x31080, 2987 0x31088, 0x310a8, 2988 0x310b0, 0x310b4, 2989 0x310c8, 0x310d4, 2990 0x31128, 0x31184, 2991 0x31198, 0x311b8, 2992 0x32000, 0x32038, 2993 0x32100, 0x3217c, 2994 0x32190, 0x321a0, 2995 0x321a8, 0x321b8, 2996 0x321c4, 0x321c8, 2997 0x321d0, 0x321e0, 2998 0x32200, 0x32344, 2999 0x32400, 0x324b4, 3000 0x324c0, 0x3252c, 3001 0x32540, 0x3265c, 3002 0x32800, 0x32848, 3003 0x32850, 0x328a8, 3004 0x328b8, 0x328c0, 3005 0x328cc, 0x328dc, 3006 0x32900, 0x32904, 3007 0x3290c, 0x32914, 3008 0x3291c, 0x32928, 3009 0x32930, 0x3293c, 3010 0x32944, 0x32948, 3011 0x32954, 0x32974, 3012 0x3297c, 0x32980, 3013 0x32a00, 0x32a20, 3014 0x32a38, 0x32a3c, 3015 0x32a50, 0x32a50, 3016 0x32a80, 0x32a80, 3017 0x32a88, 0x32aa8, 3018 0x32ab0, 0x32ab4, 3019 0x32ac8, 0x32ad4, 3020 0x32b28, 0x32b84, 3021 0x32b98, 0x32bb8, 3022 0x32c98, 0x32d14, 3023 0x33000, 0x33020, 3024 0x33038, 0x3303c, 3025 0x33050, 0x33050, 3026 0x33080, 0x33080, 3027 0x33088, 0x330a8, 3028 0x330b0, 0x330b4, 3029 0x330c8, 0x330d4, 3030 0x33128, 0x33184, 3031 0x33198, 0x331b8, 3032 0x34000, 0x34038, 3033 0x34100, 0x3417c, 3034 0x34190, 0x341a0, 3035 0x341a8, 0x341b8, 3036 0x341c4, 0x341c8, 3037 0x341d0, 0x341e0, 3038 0x34200, 0x34344, 3039 0x34400, 0x344b4, 3040 0x344c0, 0x3452c, 3041 0x34540, 0x3465c, 3042 0x34800, 0x34848, 3043 0x34850, 0x348a8, 3044 0x348b8, 0x348c0, 3045 0x348cc, 0x348dc, 3046 0x34900, 0x34904, 3047 0x3490c, 0x34914, 3048 0x3491c, 0x34928, 3049 0x34930, 0x3493c, 3050 0x34944, 0x34948, 3051 0x34954, 0x34974, 3052 0x3497c, 0x34980, 3053 0x34a00, 0x34a20, 3054 0x34a38, 0x34a3c, 3055 0x34a50, 0x34a50, 3056 0x34a80, 0x34a80, 3057 0x34a88, 0x34aa8, 3058 0x34ab0, 0x34ab4, 3059 0x34ac8, 0x34ad4, 3060 0x34b28, 0x34b84, 3061 0x34b98, 0x34bb8, 3062 0x34c98, 0x34d14, 3063 0x35000, 0x35020, 3064 0x35038, 0x3503c, 3065 0x35050, 0x35050, 3066 0x35080, 0x35080, 3067 0x35088, 0x350a8, 3068 0x350b0, 0x350b4, 3069 0x350c8, 0x350d4, 3070 0x35128, 0x35184, 3071 0x35198, 0x351b8, 3072 0x36000, 0x36038, 3073 0x36100, 0x3617c, 3074 0x36190, 0x361a0, 3075 0x361a8, 0x361b8, 3076 0x361c4, 0x361c8, 3077 0x361d0, 0x361e0, 3078 0x36200, 0x36344, 3079 0x36400, 0x364b4, 3080 0x364c0, 0x3652c, 3081 0x36540, 0x3665c, 3082 0x36800, 0x36848, 3083 0x36850, 0x368a8, 3084 0x368b8, 0x368c0, 3085 0x368cc, 0x368dc, 3086 0x36900, 0x36904, 3087 0x3690c, 0x36914, 3088 0x3691c, 0x36928, 3089 0x36930, 0x3693c, 3090 0x36944, 0x36948, 3091 0x36954, 0x36974, 3092 0x3697c, 0x36980, 3093 0x36a00, 0x36a20, 3094 0x36a38, 0x36a3c, 3095 0x36a50, 0x36a50, 3096 0x36a80, 0x36a80, 3097 0x36a88, 0x36aa8, 3098 0x36ab0, 0x36ab4, 3099 0x36ac8, 0x36ad4, 3100 0x36b28, 0x36b84, 3101 0x36b98, 0x36bb8, 3102 0x36c98, 0x36d14, 3103 0x37000, 0x37020, 3104 0x37038, 0x3703c, 3105 0x37050, 0x37050, 3106 0x37080, 0x37080, 3107 0x37088, 0x370a8, 3108 0x370b0, 0x370b4, 3109 0x370c8, 0x370d4, 3110 0x37128, 0x37184, 3111 0x37198, 0x371b8, 3112 0x38000, 0x380b0, 3113 0x380b8, 0x38130, 3114 0x38140, 0x38140, 3115 0x38150, 0x38154, 3116 0x38160, 0x381c4, 3117 0x381d0, 0x38204, 3118 0x3820c, 0x38214, 3119 0x3821c, 0x3822c, 3120 0x38244, 0x38244, 3121 0x38254, 0x38274, 3122 0x3827c, 0x38280, 3123 0x38300, 0x38304, 3124 0x3830c, 0x38314, 3125 0x3831c, 0x3832c, 3126 0x38344, 0x38344, 3127 0x38354, 0x38374, 3128 0x3837c, 0x38380, 3129 0x38400, 0x38424, 3130 0x38438, 0x3843c, 3131 0x38480, 0x38480, 3132 0x384a8, 0x384a8, 3133 0x384b0, 0x384b4, 3134 0x384c8, 0x38514, 3135 0x38600, 0x3860c, 3136 0x3861c, 0x38624, 3137 0x38900, 0x38924, 3138 0x38938, 0x3893c, 3139 0x38980, 0x38980, 3140 0x389a8, 0x389a8, 3141 0x389b0, 0x389b4, 3142 0x389c8, 0x38a14, 3143 0x38b00, 0x38b0c, 3144 0x38b1c, 0x38b24, 3145 0x38e00, 0x38e00, 3146 0x38e18, 0x38e20, 3147 0x38e38, 0x38e40, 3148 0x38e58, 0x38e60, 3149 0x38e78, 0x38e80, 3150 0x38e98, 0x38ea0, 3151 0x38eb8, 0x38ec0, 3152 0x38ed8, 0x38ee0, 3153 0x38ef8, 0x38f08, 3154 0x38f10, 0x38f2c, 3155 0x38f80, 0x38ffc, 3156 0x39080, 0x39080, 3157 0x39088, 0x39090, 3158 0x39100, 0x39108, 3159 0x39120, 0x39128, 3160 0x39140, 0x39148, 3161 0x39160, 0x39168, 3162 0x39180, 0x39188, 3163 0x391a0, 0x391a8, 3164 0x391c0, 0x391c8, 3165 0x391e0, 0x391e8, 3166 0x39200, 0x39200, 3167 0x39208, 0x39240, 3168 0x39300, 0x39300, 3169 0x39308, 0x39340, 3170 0x39400, 0x39400, 3171 0x39408, 0x39440, 3172 0x39500, 0x39500, 3173 0x39508, 0x39540, 3174 0x39600, 0x39600, 3175 0x39608, 0x39640, 3176 0x39700, 0x39700, 3177 0x39708, 0x39740, 3178 0x39800, 0x39800, 3179 0x39808, 0x39840, 3180 0x39900, 0x39900, 3181 0x39908, 0x39940, 3182 0x39a00, 0x39a04, 3183 0x39a10, 0x39a14, 3184 0x39a1c, 0x39aa8, 3185 0x39b00, 0x39ecc, 3186 0x3a000, 0x3a004, 3187 0x3a050, 0x3a084, 3188 0x3a090, 0x3a09c, 3189 0x3a93c, 0x3a93c, 3190 0x3b93c, 0x3b93c, 3191 0x3c93c, 0x3c93c, 3192 0x3d93c, 0x3d93c, 3193 0x3e000, 0x3e020, 3194 0x3e03c, 0x3e05c, 3195 0x3e100, 0x3e120, 3196 0x3e13c, 0x3e15c, 3197 0x3e200, 0x3e220, 3198 0x3e23c, 0x3e25c, 3199 0x3e300, 0x3e320, 3200 0x3e33c, 0x3e35c, 3201 0x3f000, 0x3f034, 3202 0x3f100, 0x3f130, 3203 0x3f200, 0x3f218, 3204 0x44000, 0x44014, 3205 0x44020, 0x44028, 3206 0x44030, 0x44030, 3207 0x44100, 0x44114, 3208 0x44120, 0x44128, 3209 0x44130, 0x44130, 3210 0x44200, 0x44214, 3211 0x44220, 0x44228, 3212 0x44230, 0x44230, 3213 0x44300, 0x44314, 3214 0x44320, 0x44328, 3215 0x44330, 0x44330, 3216 0x44400, 0x44414, 3217 0x44420, 0x44428, 3218 0x44430, 0x44430, 3219 0x44500, 0x44514, 3220 0x44520, 0x44528, 3221 0x44530, 0x44530, 3222 0x44714, 0x44718, 3223 0x44730, 0x44730, 3224 0x447c0, 0x447c0, 3225 0x447f0, 0x447f0, 3226 0x447f8, 0x447fc, 3227 0x45000, 0x45014, 3228 0x45020, 0x45028, 3229 0x45030, 0x45030, 3230 0x45100, 0x45114, 3231 0x45120, 0x45128, 3232 0x45130, 0x45130, 3233 0x45200, 0x45214, 3234 0x45220, 0x45228, 3235 0x45230, 0x45230, 3236 0x45300, 0x45314, 3237 0x45320, 0x45328, 3238 0x45330, 0x45330, 3239 0x45400, 0x45414, 3240 0x45420, 0x45428, 3241 0x45430, 0x45430, 3242 0x45500, 0x45514, 3243 0x45520, 0x45528, 3244 0x45530, 0x45530, 3245 0x45714, 0x45718, 3246 0x45730, 0x45730, 3247 0x457c0, 0x457c0, 3248 0x457f0, 0x457f0, 3249 0x457f8, 0x457fc, 3250 0x46000, 0x46010, 3251 0x46020, 0x46034, 3252 0x46040, 0x46050, 3253 0x46060, 0x46088, 3254 0x47000, 0x4709c, 3255 0x470c0, 0x470d4, 3256 0x47100, 0x471a8, 3257 0x471b0, 0x471e8, 3258 0x47200, 0x47210, 3259 0x4721c, 0x47230, 3260 0x47238, 0x47238, 3261 0x47240, 0x472ac, 3262 0x472d0, 0x472f4, 3263 0x47300, 0x47310, 3264 0x47318, 0x47348, 3265 0x47350, 0x47354, 3266 0x47380, 0x47388, 3267 0x47390, 0x47394, 3268 0x47400, 0x47448, 3269 0x47450, 0x47458, 3270 0x47500, 0x4751c, 3271 0x47530, 0x4754c, 3272 0x47560, 0x4757c, 3273 0x47590, 0x475ac, 3274 0x47600, 0x47630, 3275 0x47640, 0x47644, 3276 0x47660, 0x4769c, 3277 0x47700, 0x47710, 3278 0x47740, 0x47750, 3279 0x4775c, 0x4779c, 3280 0x477b0, 0x477bc, 3281 0x477c4, 0x477c8, 3282 0x477d4, 0x477fc, 3283 0x48000, 0x48004, 3284 0x48018, 0x4801c, 3285 0x49304, 0x49320, 3286 0x4932c, 0x4932c, 3287 0x49334, 0x493f0, 3288 0x49400, 0x49410, 3289 0x49460, 0x494f4, 3290 0x50000, 0x50084, 3291 0x50090, 0x500cc, 3292 0x50300, 0x50384, 3293 0x50400, 0x50404, 3294 0x50800, 0x50884, 3295 0x50890, 0x508cc, 3296 0x50b00, 0x50b84, 3297 0x50c00, 0x50c04, 3298 0x51000, 0x51020, 3299 0x51028, 0x510c4, 3300 0x51104, 0x51108, 3301 0x51200, 0x51274, 3302 0x51300, 0x51324, 3303 0x51400, 0x51548, 3304 0x51550, 0x51554, 3305 0x5155c, 0x51584, 3306 0x5158c, 0x515c8, 3307 0x515f0, 0x515f4, 3308 0x58000, 0x58004, 3309 0x58018, 0x5801c, 3310 0x59304, 0x59320, 3311 0x5932c, 0x5932c, 3312 0x59334, 0x593f0, 3313 0x59400, 0x59410, 3314 0x59460, 0x594f4, 3315 }; 3316 3317 u32 *buf_end = (u32 *)(buf + buf_size); 3318 const unsigned int *reg_ranges; 3319 int reg_ranges_size, range; 3320 unsigned int chip_version = chip_id(adap); 3321 3322 /* 3323 * Select the right set of register ranges to dump depending on the 3324 * adapter chip type. 3325 */ 3326 switch (chip_version) { 3327 case CHELSIO_T4: 3328 if (adap->flags & IS_VF) { 3329 reg_ranges = t4vf_reg_ranges; 3330 reg_ranges_size = ARRAY_SIZE(t4vf_reg_ranges); 3331 } else { 3332 reg_ranges = t4_reg_ranges; 3333 reg_ranges_size = ARRAY_SIZE(t4_reg_ranges); 3334 } 3335 break; 3336 3337 case CHELSIO_T5: 3338 if (adap->flags & IS_VF) { 3339 reg_ranges = t5vf_reg_ranges; 3340 reg_ranges_size = ARRAY_SIZE(t5vf_reg_ranges); 3341 } else { 3342 reg_ranges = t5_reg_ranges; 3343 reg_ranges_size = ARRAY_SIZE(t5_reg_ranges); 3344 } 3345 break; 3346 3347 case CHELSIO_T6: 3348 if (adap->flags & IS_VF) { 3349 reg_ranges = t6vf_reg_ranges; 3350 reg_ranges_size = ARRAY_SIZE(t6vf_reg_ranges); 3351 } else { 3352 reg_ranges = t6_reg_ranges; 3353 reg_ranges_size = ARRAY_SIZE(t6_reg_ranges); 3354 } 3355 break; 3356 3357 case CHELSIO_T7: 3358 if (adap->flags & IS_VF) { 3359 reg_ranges = t6vf_reg_ranges; 3360 reg_ranges_size = ARRAY_SIZE(t6vf_reg_ranges); 3361 } else { 3362 reg_ranges = t7_reg_ranges; 3363 reg_ranges_size = ARRAY_SIZE(t7_reg_ranges); 3364 } 3365 break; 3366 3367 default: 3368 CH_ERR(adap, 3369 "Unsupported chip version %d\n", chip_version); 3370 return; 3371 } 3372 3373 /* 3374 * Clear the register buffer and insert the appropriate register 3375 * values selected by the above register ranges. 3376 */ 3377 memset(buf, 0, buf_size); 3378 for (range = 0; range < reg_ranges_size; range += 2) { 3379 unsigned int reg = reg_ranges[range]; 3380 unsigned int last_reg = reg_ranges[range + 1]; 3381 u32 *bufp = (u32 *)(buf + reg); 3382 3383 /* 3384 * Iterate across the register range filling in the register 3385 * buffer but don't write past the end of the register buffer. 3386 */ 3387 while (reg <= last_reg && bufp < buf_end) { 3388 *bufp++ = t4_read_reg(adap, reg); 3389 reg += sizeof(u32); 3390 } 3391 } 3392 } 3393 3394 /* 3395 * Partial EEPROM Vital Product Data structure. The VPD starts with one ID 3396 * header followed by one or more VPD-R sections, each with its own header. 3397 */ 3398 struct t4_vpd_hdr { 3399 u8 id_tag; 3400 u8 id_len[2]; 3401 u8 id_data[ID_LEN]; 3402 }; 3403 3404 struct t4_vpdr_hdr { 3405 u8 vpdr_tag; 3406 u8 vpdr_len[2]; 3407 }; 3408 3409 /* 3410 * EEPROM reads take a few tens of us while writes can take a bit over 5 ms. 3411 */ 3412 #define EEPROM_DELAY 10 /* 10us per poll spin */ 3413 #define EEPROM_MAX_POLL 5000 /* x 5000 == 50ms */ 3414 3415 #define EEPROM_STAT_ADDR 0x7bfc 3416 #define VPD_SIZE 0x800 3417 #define VPD_BASE 0x400 3418 #define VPD_BASE_OLD 0 3419 #define VPD_LEN 1024 3420 #define VPD_INFO_FLD_HDR_SIZE 3 3421 #define CHELSIO_VPD_UNIQUE_ID 0x82 3422 3423 /* 3424 * Small utility function to wait till any outstanding VPD Access is complete. 3425 * We have a per-adapter state variable "VPD Busy" to indicate when we have a 3426 * VPD Access in flight. This allows us to handle the problem of having a 3427 * previous VPD Access time out and prevent an attempt to inject a new VPD 3428 * Request before any in-flight VPD reguest has completed. 3429 */ 3430 static int t4_seeprom_wait(struct adapter *adapter) 3431 { 3432 unsigned int base = adapter->params.pci.vpd_cap_addr; 3433 int max_poll; 3434 3435 /* 3436 * If no VPD Access is in flight, we can just return success right 3437 * away. 3438 */ 3439 if (!adapter->vpd_busy) 3440 return 0; 3441 3442 /* 3443 * Poll the VPD Capability Address/Flag register waiting for it 3444 * to indicate that the operation is complete. 3445 */ 3446 max_poll = EEPROM_MAX_POLL; 3447 do { 3448 u16 val; 3449 3450 udelay(EEPROM_DELAY); 3451 t4_os_pci_read_cfg2(adapter, base + PCI_VPD_ADDR, &val); 3452 3453 /* 3454 * If the operation is complete, mark the VPD as no longer 3455 * busy and return success. 3456 */ 3457 if ((val & PCI_VPD_ADDR_F) == adapter->vpd_flag) { 3458 adapter->vpd_busy = 0; 3459 return 0; 3460 } 3461 } while (--max_poll); 3462 3463 /* 3464 * Failure! Note that we leave the VPD Busy status set in order to 3465 * avoid pushing a new VPD Access request into the VPD Capability till 3466 * the current operation eventually succeeds. It's a bug to issue a 3467 * new request when an existing request is in flight and will result 3468 * in corrupt hardware state. 3469 */ 3470 return -ETIMEDOUT; 3471 } 3472 3473 /** 3474 * t4_seeprom_read - read a serial EEPROM location 3475 * @adapter: adapter to read 3476 * @addr: EEPROM virtual address 3477 * @data: where to store the read data 3478 * 3479 * Read a 32-bit word from a location in serial EEPROM using the card's PCI 3480 * VPD capability. Note that this function must be called with a virtual 3481 * address. 3482 */ 3483 int t4_seeprom_read(struct adapter *adapter, u32 addr, u32 *data) 3484 { 3485 unsigned int base = adapter->params.pci.vpd_cap_addr; 3486 int ret; 3487 3488 /* 3489 * VPD Accesses must alway be 4-byte aligned! 3490 */ 3491 if (addr >= EEPROMVSIZE || (addr & 3)) 3492 return -EINVAL; 3493 3494 /* 3495 * Wait for any previous operation which may still be in flight to 3496 * complete. 3497 */ 3498 ret = t4_seeprom_wait(adapter); 3499 if (ret) { 3500 CH_ERR(adapter, "VPD still busy from previous operation\n"); 3501 return ret; 3502 } 3503 3504 /* 3505 * Issue our new VPD Read request, mark the VPD as being busy and wait 3506 * for our request to complete. If it doesn't complete, note the 3507 * error and return it to our caller. Note that we do not reset the 3508 * VPD Busy status! 3509 */ 3510 t4_os_pci_write_cfg2(adapter, base + PCI_VPD_ADDR, (u16)addr); 3511 adapter->vpd_busy = 1; 3512 adapter->vpd_flag = PCI_VPD_ADDR_F; 3513 ret = t4_seeprom_wait(adapter); 3514 if (ret) { 3515 CH_ERR(adapter, "VPD read of address %#x failed\n", addr); 3516 return ret; 3517 } 3518 3519 /* 3520 * Grab the returned data, swizzle it into our endianness and 3521 * return success. 3522 */ 3523 t4_os_pci_read_cfg4(adapter, base + PCI_VPD_DATA, data); 3524 *data = le32_to_cpu(*data); 3525 return 0; 3526 } 3527 3528 /** 3529 * t4_seeprom_write - write a serial EEPROM location 3530 * @adapter: adapter to write 3531 * @addr: virtual EEPROM address 3532 * @data: value to write 3533 * 3534 * Write a 32-bit word to a location in serial EEPROM using the card's PCI 3535 * VPD capability. Note that this function must be called with a virtual 3536 * address. 3537 */ 3538 int t4_seeprom_write(struct adapter *adapter, u32 addr, u32 data) 3539 { 3540 unsigned int base = adapter->params.pci.vpd_cap_addr; 3541 int ret; 3542 u32 stats_reg; 3543 int max_poll; 3544 3545 /* 3546 * VPD Accesses must alway be 4-byte aligned! 3547 */ 3548 if (addr >= EEPROMVSIZE || (addr & 3)) 3549 return -EINVAL; 3550 3551 /* 3552 * Wait for any previous operation which may still be in flight to 3553 * complete. 3554 */ 3555 ret = t4_seeprom_wait(adapter); 3556 if (ret) { 3557 CH_ERR(adapter, "VPD still busy from previous operation\n"); 3558 return ret; 3559 } 3560 3561 /* 3562 * Issue our new VPD Read request, mark the VPD as being busy and wait 3563 * for our request to complete. If it doesn't complete, note the 3564 * error and return it to our caller. Note that we do not reset the 3565 * VPD Busy status! 3566 */ 3567 t4_os_pci_write_cfg4(adapter, base + PCI_VPD_DATA, 3568 cpu_to_le32(data)); 3569 t4_os_pci_write_cfg2(adapter, base + PCI_VPD_ADDR, 3570 (u16)addr | PCI_VPD_ADDR_F); 3571 adapter->vpd_busy = 1; 3572 adapter->vpd_flag = 0; 3573 ret = t4_seeprom_wait(adapter); 3574 if (ret) { 3575 CH_ERR(adapter, "VPD write of address %#x failed\n", addr); 3576 return ret; 3577 } 3578 3579 /* 3580 * Reset PCI_VPD_DATA register after a transaction and wait for our 3581 * request to complete. If it doesn't complete, return error. 3582 */ 3583 t4_os_pci_write_cfg4(adapter, base + PCI_VPD_DATA, 0); 3584 max_poll = EEPROM_MAX_POLL; 3585 do { 3586 udelay(EEPROM_DELAY); 3587 t4_seeprom_read(adapter, EEPROM_STAT_ADDR, &stats_reg); 3588 } while ((stats_reg & 0x1) && --max_poll); 3589 if (!max_poll) 3590 return -ETIMEDOUT; 3591 3592 /* Return success! */ 3593 return 0; 3594 } 3595 3596 /** 3597 * t4_eeprom_ptov - translate a physical EEPROM address to virtual 3598 * @phys_addr: the physical EEPROM address 3599 * @fn: the PCI function number 3600 * @sz: size of function-specific area 3601 * 3602 * Translate a physical EEPROM address to virtual. The first 1K is 3603 * accessed through virtual addresses starting at 31K, the rest is 3604 * accessed through virtual addresses starting at 0. 3605 * 3606 * The mapping is as follows: 3607 * [0..1K) -> [31K..32K) 3608 * [1K..1K+A) -> [ES-A..ES) 3609 * [1K+A..ES) -> [0..ES-A-1K) 3610 * 3611 * where A = @fn * @sz, and ES = EEPROM size. 3612 */ 3613 int t4_eeprom_ptov(unsigned int phys_addr, unsigned int fn, unsigned int sz) 3614 { 3615 fn *= sz; 3616 if (phys_addr < 1024) 3617 return phys_addr + (31 << 10); 3618 if (phys_addr < 1024 + fn) 3619 return EEPROMSIZE - fn + phys_addr - 1024; 3620 if (phys_addr < EEPROMSIZE) 3621 return phys_addr - 1024 - fn; 3622 return -EINVAL; 3623 } 3624 3625 /** 3626 * t4_seeprom_wp - enable/disable EEPROM write protection 3627 * @adapter: the adapter 3628 * @enable: whether to enable or disable write protection 3629 * 3630 * Enables or disables write protection on the serial EEPROM. 3631 */ 3632 int t4_seeprom_wp(struct adapter *adapter, int enable) 3633 { 3634 return t4_seeprom_write(adapter, EEPROM_STAT_ADDR, enable ? 0xc : 0); 3635 } 3636 3637 /** 3638 * get_vpd_keyword_val - Locates an information field keyword in the VPD 3639 * @vpd: Pointer to buffered vpd data structure 3640 * @kw: The keyword to search for 3641 * @region: VPD region to search (starting from 0) 3642 * 3643 * Returns the value of the information field keyword or 3644 * -ENOENT otherwise. 3645 */ 3646 static int get_vpd_keyword_val(const u8 *vpd, const char *kw, int region) 3647 { 3648 int i, tag; 3649 unsigned int offset, len; 3650 const struct t4_vpdr_hdr *vpdr; 3651 3652 offset = sizeof(struct t4_vpd_hdr); 3653 vpdr = (const void *)(vpd + offset); 3654 tag = vpdr->vpdr_tag; 3655 len = (u16)vpdr->vpdr_len[0] + ((u16)vpdr->vpdr_len[1] << 8); 3656 while (region--) { 3657 offset += sizeof(struct t4_vpdr_hdr) + len; 3658 vpdr = (const void *)(vpd + offset); 3659 if (++tag != vpdr->vpdr_tag) 3660 return -ENOENT; 3661 len = (u16)vpdr->vpdr_len[0] + ((u16)vpdr->vpdr_len[1] << 8); 3662 } 3663 offset += sizeof(struct t4_vpdr_hdr); 3664 3665 if (offset + len > VPD_LEN) { 3666 return -ENOENT; 3667 } 3668 3669 for (i = offset; i + VPD_INFO_FLD_HDR_SIZE <= offset + len;) { 3670 if (memcmp(vpd + i , kw , 2) == 0){ 3671 i += VPD_INFO_FLD_HDR_SIZE; 3672 return i; 3673 } 3674 3675 i += VPD_INFO_FLD_HDR_SIZE + vpd[i+2]; 3676 } 3677 3678 return -ENOENT; 3679 } 3680 3681 3682 /** 3683 * get_vpd_params - read VPD parameters from VPD EEPROM 3684 * @adapter: adapter to read 3685 * @p: where to store the parameters 3686 * @vpd: caller provided temporary space to read the VPD into 3687 * 3688 * Reads card parameters stored in VPD EEPROM. 3689 */ 3690 static int get_vpd_params(struct adapter *adapter, struct vpd_params *p, 3691 uint16_t device_id, u32 *buf) 3692 { 3693 int i, ret, addr; 3694 int ec, sn, pn, na, md; 3695 u8 csum; 3696 const u8 *vpd = (const u8 *)buf; 3697 3698 /* 3699 * Card information normally starts at VPD_BASE but early cards had 3700 * it at 0. 3701 */ 3702 ret = t4_seeprom_read(adapter, VPD_BASE, buf); 3703 if (ret) 3704 return (ret); 3705 3706 /* 3707 * The VPD shall have a unique identifier specified by the PCI SIG. 3708 * For chelsio adapters, the identifier is 0x82. The first byte of a VPD 3709 * shall be CHELSIO_VPD_UNIQUE_ID (0x82). The VPD programming software 3710 * is expected to automatically put this entry at the 3711 * beginning of the VPD. 3712 */ 3713 addr = *vpd == CHELSIO_VPD_UNIQUE_ID ? VPD_BASE : VPD_BASE_OLD; 3714 3715 for (i = 0; i < VPD_LEN; i += 4) { 3716 ret = t4_seeprom_read(adapter, addr + i, buf++); 3717 if (ret) 3718 return ret; 3719 } 3720 3721 #define FIND_VPD_KW(var,name) do { \ 3722 var = get_vpd_keyword_val(vpd, name, 0); \ 3723 if (var < 0) { \ 3724 CH_ERR(adapter, "missing VPD keyword " name "\n"); \ 3725 return -EINVAL; \ 3726 } \ 3727 } while (0) 3728 3729 FIND_VPD_KW(i, "RV"); 3730 for (csum = 0; i >= 0; i--) 3731 csum += vpd[i]; 3732 3733 if (csum) { 3734 CH_ERR(adapter, 3735 "corrupted VPD EEPROM, actual csum %u\n", csum); 3736 return -EINVAL; 3737 } 3738 3739 FIND_VPD_KW(ec, "EC"); 3740 FIND_VPD_KW(sn, "SN"); 3741 FIND_VPD_KW(pn, "PN"); 3742 FIND_VPD_KW(na, "NA"); 3743 #undef FIND_VPD_KW 3744 3745 memcpy(p->id, vpd + offsetof(struct t4_vpd_hdr, id_data), ID_LEN); 3746 strstrip(p->id); 3747 memcpy(p->ec, vpd + ec, EC_LEN); 3748 strstrip(p->ec); 3749 i = vpd[sn - VPD_INFO_FLD_HDR_SIZE + 2]; 3750 memcpy(p->sn, vpd + sn, min(i, SERNUM_LEN)); 3751 strstrip(p->sn); 3752 i = vpd[pn - VPD_INFO_FLD_HDR_SIZE + 2]; 3753 memcpy(p->pn, vpd + pn, min(i, PN_LEN)); 3754 strstrip((char *)p->pn); 3755 i = vpd[na - VPD_INFO_FLD_HDR_SIZE + 2]; 3756 memcpy(p->na, vpd + na, min(i, MACADDR_LEN)); 3757 strstrip((char *)p->na); 3758 3759 if (device_id & 0x80) 3760 return 0; /* Custom card */ 3761 3762 md = get_vpd_keyword_val(vpd, "VF", 1); 3763 if (md < 0) { 3764 snprintf(p->md, sizeof(p->md), "unknown"); 3765 } else { 3766 i = vpd[md - VPD_INFO_FLD_HDR_SIZE + 2]; 3767 memcpy(p->md, vpd + md, min(i, MD_LEN)); 3768 strstrip((char *)p->md); 3769 } 3770 3771 return 0; 3772 } 3773 3774 /* Flash Layout {start sector, # of sectors} for T4/T5/T6 adapters */ 3775 static const struct t4_flash_loc_entry t4_flash_loc_arr[] = { 3776 [FLASH_LOC_EXP_ROM] = { 0, 6 }, 3777 [FLASH_LOC_IBFT] = { 6, 1 }, 3778 [FLASH_LOC_BOOTCFG] = { 7, 1 }, 3779 [FLASH_LOC_FW] = { 8, 16 }, 3780 [FLASH_LOC_FWBOOTSTRAP] = { 27, 1 }, 3781 [FLASH_LOC_ISCSI_CRASH] = { 29, 1 }, 3782 [FLASH_LOC_FCOE_CRASH] = { 30, 1 }, 3783 [FLASH_LOC_CFG] = { 31, 1 }, 3784 [FLASH_LOC_CUDBG] = { 32, 32 }, 3785 [FLASH_LOC_BOOT_AREA] = { 0, 8 }, /* Spans complete Boot Area */ 3786 [FLASH_LOC_END] = { 64, 0 }, 3787 }; 3788 3789 /* Flash Layout {start sector, # of sectors} for T7 adapters */ 3790 static const struct t4_flash_loc_entry t7_flash_loc_arr[] = { 3791 [FLASH_LOC_VPD] = { 0, 1 }, 3792 [FLASH_LOC_FWBOOTSTRAP] = { 1, 1 }, 3793 [FLASH_LOC_FW] = { 2, 29 }, 3794 [FLASH_LOC_CFG] = { 31, 1 }, 3795 [FLASH_LOC_EXP_ROM] = { 32, 15 }, 3796 [FLASH_LOC_IBFT] = { 47, 1 }, 3797 [FLASH_LOC_BOOTCFG] = { 48, 1 }, 3798 [FLASH_LOC_DPU_BOOT] = { 49, 13 }, 3799 [FLASH_LOC_ISCSI_CRASH] = { 62, 1 }, 3800 [FLASH_LOC_FCOE_CRASH] = { 63, 1 }, 3801 [FLASH_LOC_VPD_BACKUP] = { 64, 1 }, 3802 [FLASH_LOC_FWBOOTSTRAP_BACKUP] = { 65, 1 }, 3803 [FLASH_LOC_FW_BACKUP] = { 66, 29 }, 3804 [FLASH_LOC_CFG_BACK] = { 95, 1 }, 3805 [FLASH_LOC_CUDBG] = { 96, 48 }, 3806 [FLASH_LOC_CHIP_DUMP] = { 144, 48 }, 3807 [FLASH_LOC_DPU_AREA] = { 192, 64 }, 3808 [FLASH_LOC_BOOT_AREA] = { 32, 17 }, /* Spans complete UEFI/PXE Boot Area */ 3809 [FLASH_LOC_END] = { 256, 0 }, 3810 }; 3811 3812 int 3813 t4_flash_loc_start(struct adapter *adap, enum t4_flash_loc loc, 3814 unsigned int *lenp) 3815 { 3816 const struct t4_flash_loc_entry *l = chip_id(adap) >= CHELSIO_T7 ? 3817 &t7_flash_loc_arr[loc] : &t4_flash_loc_arr[loc]; 3818 3819 if (lenp != NULL) 3820 *lenp = FLASH_MAX_SIZE(l->nsecs); 3821 return (FLASH_START(l->start_sec)); 3822 } 3823 3824 /* serial flash and firmware constants and flash config file constants */ 3825 enum { 3826 SF_ATTEMPTS = 10, /* max retries for SF operations */ 3827 3828 /* flash command opcodes */ 3829 SF_PROG_PAGE = 2, /* program 256B page */ 3830 SF_WR_DISABLE = 4, /* disable writes */ 3831 SF_RD_STATUS = 5, /* read status register */ 3832 SF_WR_ENABLE = 6, /* enable writes */ 3833 SF_RD_DATA_FAST = 0xb, /* read flash */ 3834 SF_RD_ID = 0x9f, /* read ID */ 3835 SF_ERASE_SECTOR = 0xd8, /* erase 64KB sector */ 3836 }; 3837 3838 /** 3839 * sf1_read - read data from the serial flash 3840 * @adapter: the adapter 3841 * @byte_cnt: number of bytes to read 3842 * @cont: whether another operation will be chained 3843 * @lock: whether to lock SF for PL access only 3844 * @valp: where to store the read data 3845 * 3846 * Reads up to 4 bytes of data from the serial flash. The location of 3847 * the read needs to be specified prior to calling this by issuing the 3848 * appropriate commands to the serial flash. 3849 */ 3850 static int sf1_read(struct adapter *adapter, unsigned int byte_cnt, int cont, 3851 int lock, u32 *valp) 3852 { 3853 int ret; 3854 uint32_t op; 3855 3856 if (!byte_cnt || byte_cnt > 4) 3857 return -EINVAL; 3858 if (t4_read_reg(adapter, A_SF_OP) & F_BUSY) 3859 return -EBUSY; 3860 op = V_SF_LOCK(lock) | V_CONT(cont) | V_BYTECNT(byte_cnt - 1); 3861 if (chip_id(adapter) >= CHELSIO_T7) 3862 op |= F_QUADREADDISABLE; 3863 t4_write_reg(adapter, A_SF_OP, op); 3864 ret = t4_wait_op_done(adapter, A_SF_OP, F_BUSY, 0, SF_ATTEMPTS, 5); 3865 if (!ret) 3866 *valp = t4_read_reg(adapter, A_SF_DATA); 3867 return ret; 3868 } 3869 3870 /** 3871 * sf1_write - write data to the serial flash 3872 * @adapter: the adapter 3873 * @byte_cnt: number of bytes to write 3874 * @cont: whether another operation will be chained 3875 * @lock: whether to lock SF for PL access only 3876 * @val: value to write 3877 * 3878 * Writes up to 4 bytes of data to the serial flash. The location of 3879 * the write needs to be specified prior to calling this by issuing the 3880 * appropriate commands to the serial flash. 3881 */ 3882 static int sf1_write(struct adapter *adapter, unsigned int byte_cnt, int cont, 3883 int lock, u32 val) 3884 { 3885 if (!byte_cnt || byte_cnt > 4) 3886 return -EINVAL; 3887 if (t4_read_reg(adapter, A_SF_OP) & F_BUSY) 3888 return -EBUSY; 3889 t4_write_reg(adapter, A_SF_DATA, val); 3890 t4_write_reg(adapter, A_SF_OP, V_SF_LOCK(lock) | 3891 V_CONT(cont) | V_BYTECNT(byte_cnt - 1) | V_OP(1)); 3892 return t4_wait_op_done(adapter, A_SF_OP, F_BUSY, 0, SF_ATTEMPTS, 5); 3893 } 3894 3895 /** 3896 * flash_wait_op - wait for a flash operation to complete 3897 * @adapter: the adapter 3898 * @attempts: max number of polls of the status register 3899 * @delay: delay between polls in ms 3900 * 3901 * Wait for a flash operation to complete by polling the status register. 3902 */ 3903 static int flash_wait_op(struct adapter *adapter, int attempts, int delay) 3904 { 3905 int ret; 3906 u32 status; 3907 3908 while (1) { 3909 if ((ret = sf1_write(adapter, 1, 1, 1, SF_RD_STATUS)) != 0 || 3910 (ret = sf1_read(adapter, 1, 0, 1, &status)) != 0) 3911 return ret; 3912 if (!(status & 1)) 3913 return 0; 3914 if (--attempts == 0) 3915 return -EAGAIN; 3916 if (delay) 3917 msleep(delay); 3918 } 3919 } 3920 3921 /** 3922 * t4_read_flash - read words from serial flash 3923 * @adapter: the adapter 3924 * @addr: the start address for the read 3925 * @nwords: how many 32-bit words to read 3926 * @data: where to store the read data 3927 * @byte_oriented: whether to store data as bytes or as words 3928 * 3929 * Read the specified number of 32-bit words from the serial flash. 3930 * If @byte_oriented is set the read data is stored as a byte array 3931 * (i.e., big-endian), otherwise as 32-bit words in the platform's 3932 * natural endianness. 3933 */ 3934 int t4_read_flash(struct adapter *adapter, unsigned int addr, 3935 unsigned int nwords, u32 *data, int byte_oriented) 3936 { 3937 int ret; 3938 3939 if (addr + nwords * sizeof(u32) > adapter->params.sf_size || (addr & 3)) 3940 return -EINVAL; 3941 3942 addr = swab32(addr) | SF_RD_DATA_FAST; 3943 3944 if ((ret = sf1_write(adapter, 4, 1, 0, addr)) != 0 || 3945 (ret = sf1_read(adapter, 1, 1, 0, data)) != 0) 3946 return ret; 3947 3948 for ( ; nwords; nwords--, data++) { 3949 ret = sf1_read(adapter, 4, nwords > 1, nwords == 1, data); 3950 if (nwords == 1) 3951 t4_write_reg(adapter, A_SF_OP, 0); /* unlock SF */ 3952 if (ret) 3953 return ret; 3954 if (byte_oriented) 3955 *data = (__force __u32)(cpu_to_be32(*data)); 3956 } 3957 return 0; 3958 } 3959 3960 /** 3961 * t4_write_flash - write up to a page of data to the serial flash 3962 * @adapter: the adapter 3963 * @addr: the start address to write 3964 * @n: length of data to write in bytes 3965 * @data: the data to write 3966 * @byte_oriented: whether to store data as bytes or as words 3967 * 3968 * Writes up to a page of data (256 bytes) to the serial flash starting 3969 * at the given address. All the data must be written to the same page. 3970 * If @byte_oriented is set the write data is stored as byte stream 3971 * (i.e. matches what on disk), otherwise in big-endian. 3972 */ 3973 int t4_write_flash(struct adapter *adapter, unsigned int addr, 3974 unsigned int n, const u8 *data, int byte_oriented) 3975 { 3976 int ret; 3977 u32 buf[SF_PAGE_SIZE / 4]; 3978 unsigned int i, c, left, val, offset = addr & 0xff; 3979 3980 if (addr >= adapter->params.sf_size || offset + n > SF_PAGE_SIZE) 3981 return -EINVAL; 3982 3983 val = swab32(addr) | SF_PROG_PAGE; 3984 3985 if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 || 3986 (ret = sf1_write(adapter, 4, 1, 1, val)) != 0) 3987 goto unlock; 3988 3989 for (left = n; left; left -= c) { 3990 c = min(left, 4U); 3991 for (val = 0, i = 0; i < c; ++i) 3992 val = (val << 8) + *data++; 3993 3994 if (!byte_oriented) 3995 val = cpu_to_be32(val); 3996 3997 ret = sf1_write(adapter, c, c != left, 1, val); 3998 if (ret) 3999 goto unlock; 4000 } 4001 ret = flash_wait_op(adapter, 8, 1); 4002 if (ret) 4003 goto unlock; 4004 4005 t4_write_reg(adapter, A_SF_OP, 0); /* unlock SF */ 4006 4007 /* Read the page to verify the write succeeded */ 4008 ret = t4_read_flash(adapter, addr & ~0xff, ARRAY_SIZE(buf), buf, 4009 byte_oriented); 4010 if (ret) 4011 return ret; 4012 4013 if (memcmp(data - n, (u8 *)buf + offset, n)) { 4014 CH_ERR(adapter, 4015 "failed to correctly write the flash page at %#x\n", 4016 addr); 4017 return -EIO; 4018 } 4019 return 0; 4020 4021 unlock: 4022 t4_write_reg(adapter, A_SF_OP, 0); /* unlock SF */ 4023 return ret; 4024 } 4025 4026 /** 4027 * t4_get_fw_version - read the firmware version 4028 * @adapter: the adapter 4029 * @vers: where to place the version 4030 * 4031 * Reads the FW version from flash. 4032 */ 4033 int t4_get_fw_version(struct adapter *adapter, u32 *vers) 4034 { 4035 const int start = t4_flash_loc_start(adapter, FLASH_LOC_FW, NULL); 4036 4037 return t4_read_flash(adapter, start + offsetof(struct fw_hdr, fw_ver), 4038 1, vers, 0); 4039 } 4040 4041 /** 4042 * t4_get_fw_hdr - read the firmware header 4043 * @adapter: the adapter 4044 * @hdr: where to place the version 4045 * 4046 * Reads the FW header from flash into caller provided buffer. 4047 */ 4048 int t4_get_fw_hdr(struct adapter *adapter, struct fw_hdr *hdr) 4049 { 4050 const int start = t4_flash_loc_start(adapter, FLASH_LOC_FW, NULL); 4051 4052 return t4_read_flash(adapter, start, sizeof (*hdr) / sizeof (uint32_t), 4053 (uint32_t *)hdr, 1); 4054 } 4055 4056 /** 4057 * t4_get_bs_version - read the firmware bootstrap version 4058 * @adapter: the adapter 4059 * @vers: where to place the version 4060 * 4061 * Reads the FW Bootstrap version from flash. 4062 */ 4063 int t4_get_bs_version(struct adapter *adapter, u32 *vers) 4064 { 4065 const int start = t4_flash_loc_start(adapter, FLASH_LOC_FWBOOTSTRAP, 4066 NULL); 4067 4068 return t4_read_flash(adapter, start + offsetof(struct fw_hdr, fw_ver), 4069 1, vers, 0); 4070 } 4071 4072 /** 4073 * t4_get_tp_version - read the TP microcode version 4074 * @adapter: the adapter 4075 * @vers: where to place the version 4076 * 4077 * Reads the TP microcode version from flash. 4078 */ 4079 int t4_get_tp_version(struct adapter *adapter, u32 *vers) 4080 { 4081 const int start = t4_flash_loc_start(adapter, FLASH_LOC_FW, NULL); 4082 4083 return t4_read_flash(adapter, start + 4084 offsetof(struct fw_hdr, tp_microcode_ver), 1, vers, 0); 4085 } 4086 4087 /** 4088 * t4_get_exprom_version - return the Expansion ROM version (if any) 4089 * @adapter: the adapter 4090 * @vers: where to place the version 4091 * 4092 * Reads the Expansion ROM header from FLASH and returns the version 4093 * number (if present) through the @vers return value pointer. We return 4094 * this in the Firmware Version Format since it's convenient. Return 4095 * 0 on success, -ENOENT if no Expansion ROM is present. 4096 */ 4097 int t4_get_exprom_version(struct adapter *adapter, u32 *vers) 4098 { 4099 struct exprom_header { 4100 unsigned char hdr_arr[16]; /* must start with 0x55aa */ 4101 unsigned char hdr_ver[4]; /* Expansion ROM version */ 4102 } *hdr; 4103 u32 exprom_header_buf[DIV_ROUND_UP(sizeof(struct exprom_header), 4104 sizeof(u32))]; 4105 int ret; 4106 const int start = t4_flash_loc_start(adapter, FLASH_LOC_EXP_ROM, NULL); 4107 4108 ret = t4_read_flash(adapter, start, ARRAY_SIZE(exprom_header_buf), 4109 exprom_header_buf, 0); 4110 if (ret) 4111 return ret; 4112 4113 hdr = (struct exprom_header *)exprom_header_buf; 4114 if (hdr->hdr_arr[0] != 0x55 || hdr->hdr_arr[1] != 0xaa) 4115 return -ENOENT; 4116 4117 *vers = (V_FW_HDR_FW_VER_MAJOR(hdr->hdr_ver[0]) | 4118 V_FW_HDR_FW_VER_MINOR(hdr->hdr_ver[1]) | 4119 V_FW_HDR_FW_VER_MICRO(hdr->hdr_ver[2]) | 4120 V_FW_HDR_FW_VER_BUILD(hdr->hdr_ver[3])); 4121 return 0; 4122 } 4123 4124 /** 4125 * t4_get_scfg_version - return the Serial Configuration version 4126 * @adapter: the adapter 4127 * @vers: where to place the version 4128 * 4129 * Reads the Serial Configuration Version via the Firmware interface 4130 * (thus this can only be called once we're ready to issue Firmware 4131 * commands). The format of the Serial Configuration version is 4132 * adapter specific. Returns 0 on success, an error on failure. 4133 * 4134 * Note that early versions of the Firmware didn't include the ability 4135 * to retrieve the Serial Configuration version, so we zero-out the 4136 * return-value parameter in that case to avoid leaving it with 4137 * garbage in it. 4138 * 4139 * Also note that the Firmware will return its cached copy of the Serial 4140 * Initialization Revision ID, not the actual Revision ID as written in 4141 * the Serial EEPROM. This is only an issue if a new VPD has been written 4142 * and the Firmware/Chip haven't yet gone through a RESET sequence. So 4143 * it's best to defer calling this routine till after a FW_RESET_CMD has 4144 * been issued if the Host Driver will be performing a full adapter 4145 * initialization. 4146 */ 4147 int t4_get_scfg_version(struct adapter *adapter, u32 *vers) 4148 { 4149 u32 scfgrev_param; 4150 int ret; 4151 4152 scfgrev_param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | 4153 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_SCFGREV)); 4154 ret = t4_query_params(adapter, adapter->mbox, adapter->pf, 0, 4155 1, &scfgrev_param, vers); 4156 if (ret) 4157 *vers = 0; 4158 return ret; 4159 } 4160 4161 /** 4162 * t4_get_vpd_version - return the VPD version 4163 * @adapter: the adapter 4164 * @vers: where to place the version 4165 * 4166 * Reads the VPD via the Firmware interface (thus this can only be called 4167 * once we're ready to issue Firmware commands). The format of the 4168 * VPD version is adapter specific. Returns 0 on success, an error on 4169 * failure. 4170 * 4171 * Note that early versions of the Firmware didn't include the ability 4172 * to retrieve the VPD version, so we zero-out the return-value parameter 4173 * in that case to avoid leaving it with garbage in it. 4174 * 4175 * Also note that the Firmware will return its cached copy of the VPD 4176 * Revision ID, not the actual Revision ID as written in the Serial 4177 * EEPROM. This is only an issue if a new VPD has been written and the 4178 * Firmware/Chip haven't yet gone through a RESET sequence. So it's best 4179 * to defer calling this routine till after a FW_RESET_CMD has been issued 4180 * if the Host Driver will be performing a full adapter initialization. 4181 */ 4182 int t4_get_vpd_version(struct adapter *adapter, u32 *vers) 4183 { 4184 u32 vpdrev_param; 4185 int ret; 4186 4187 vpdrev_param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | 4188 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_VPDREV)); 4189 ret = t4_query_params(adapter, adapter->mbox, adapter->pf, 0, 4190 1, &vpdrev_param, vers); 4191 if (ret) 4192 *vers = 0; 4193 return ret; 4194 } 4195 4196 /** 4197 * t4_get_version_info - extract various chip/firmware version information 4198 * @adapter: the adapter 4199 * 4200 * Reads various chip/firmware version numbers and stores them into the 4201 * adapter Adapter Parameters structure. If any of the efforts fails 4202 * the first failure will be returned, but all of the version numbers 4203 * will be read. 4204 */ 4205 int t4_get_version_info(struct adapter *adapter) 4206 { 4207 int ret = 0; 4208 4209 #define FIRST_RET(__getvinfo) \ 4210 do { \ 4211 int __ret = __getvinfo; \ 4212 if (__ret && !ret) \ 4213 ret = __ret; \ 4214 } while (0) 4215 4216 FIRST_RET(t4_get_fw_version(adapter, &adapter->params.fw_vers)); 4217 FIRST_RET(t4_get_bs_version(adapter, &adapter->params.bs_vers)); 4218 FIRST_RET(t4_get_tp_version(adapter, &adapter->params.tp_vers)); 4219 FIRST_RET(t4_get_exprom_version(adapter, &adapter->params.er_vers)); 4220 FIRST_RET(t4_get_scfg_version(adapter, &adapter->params.scfg_vers)); 4221 FIRST_RET(t4_get_vpd_version(adapter, &adapter->params.vpd_vers)); 4222 4223 #undef FIRST_RET 4224 4225 return ret; 4226 } 4227 4228 /** 4229 * t4_flash_erase_sectors - erase a range of flash sectors 4230 * @adapter: the adapter 4231 * @start: the first sector to erase 4232 * @end: the last sector to erase 4233 * 4234 * Erases the sectors in the given inclusive range. 4235 */ 4236 int t4_flash_erase_sectors(struct adapter *adapter, int start, int end) 4237 { 4238 int ret = 0; 4239 4240 if (end >= adapter->params.sf_nsec) 4241 return -EINVAL; 4242 4243 while (start <= end) { 4244 if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 || 4245 (ret = sf1_write(adapter, 4, 0, 1, 4246 SF_ERASE_SECTOR | (start << 8))) != 0 || 4247 (ret = flash_wait_op(adapter, 14, 500)) != 0) { 4248 CH_ERR(adapter, 4249 "erase of flash sector %d failed, error %d\n", 4250 start, ret); 4251 break; 4252 } 4253 start++; 4254 } 4255 t4_write_reg(adapter, A_SF_OP, 0); /* unlock SF */ 4256 return ret; 4257 } 4258 4259 /** 4260 * t4_flash_cfg_addr - return the address of the flash configuration file 4261 * @adapter: the adapter 4262 * 4263 * Return the address within the flash where the Firmware Configuration 4264 * File is stored, or an error if the device FLASH is too small to contain 4265 * a Firmware Configuration File. 4266 */ 4267 int t4_flash_cfg_addr(struct adapter *adapter, unsigned int *lenp) 4268 { 4269 unsigned int len = 0; 4270 const int cfg_start = t4_flash_loc_start(adapter, FLASH_LOC_CFG, &len); 4271 4272 /* 4273 * If the device FLASH isn't large enough to hold a Firmware 4274 * Configuration File, return an error. 4275 */ 4276 if (adapter->params.sf_size < cfg_start + len) 4277 return -ENOSPC; 4278 if (lenp != NULL) 4279 *lenp = len; 4280 return (cfg_start); 4281 } 4282 4283 /* 4284 * Return TRUE if the specified firmware matches the adapter. I.e. T4 4285 * firmware for T4 adapters, T5 firmware for T5 adapters, etc. We go ahead 4286 * and emit an error message for mismatched firmware to save our caller the 4287 * effort ... 4288 */ 4289 static int t4_fw_matches_chip(struct adapter *adap, 4290 const struct fw_hdr *hdr) 4291 { 4292 /* 4293 * The expression below will return FALSE for any unsupported adapter 4294 * which will keep us "honest" in the future ... 4295 */ 4296 if ((is_t4(adap) && hdr->chip == FW_HDR_CHIP_T4) || 4297 (is_t5(adap) && hdr->chip == FW_HDR_CHIP_T5) || 4298 (is_t6(adap) && hdr->chip == FW_HDR_CHIP_T6) || 4299 (is_t7(adap) && hdr->chip == FW_HDR_CHIP_T7)) 4300 return 1; 4301 4302 CH_ERR(adap, 4303 "FW image (%d) is not suitable for this adapter (%d)\n", 4304 hdr->chip, chip_id(adap)); 4305 return 0; 4306 } 4307 4308 /** 4309 * t4_load_fw - download firmware 4310 * @adap: the adapter 4311 * @fw_data: the firmware image to write 4312 * @size: image size 4313 * 4314 * Write the supplied firmware image to the card's serial flash. 4315 */ 4316 int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size) 4317 { 4318 u32 csum; 4319 int ret, addr; 4320 unsigned int i; 4321 u8 first_page[SF_PAGE_SIZE]; 4322 const u32 *p = (const u32 *)fw_data; 4323 const struct fw_hdr *hdr = (const struct fw_hdr *)fw_data; 4324 unsigned int fw_start_sec; 4325 unsigned int fw_start; 4326 unsigned int fw_size; 4327 enum t4_flash_loc loc; 4328 4329 loc = ntohl(hdr->magic) == FW_HDR_MAGIC_BOOTSTRAP ? 4330 FLASH_LOC_FWBOOTSTRAP : FLASH_LOC_FW; 4331 fw_start = t4_flash_loc_start(adap, loc, &fw_size); 4332 fw_start_sec = fw_start / SF_SEC_SIZE; 4333 4334 if (!size) { 4335 CH_ERR(adap, "FW image has no data\n"); 4336 return -EINVAL; 4337 } 4338 if (size & 511) { 4339 CH_ERR(adap, 4340 "FW image size not multiple of 512 bytes\n"); 4341 return -EINVAL; 4342 } 4343 if ((unsigned int) be16_to_cpu(hdr->len512) * 512 != size) { 4344 CH_ERR(adap, 4345 "FW image size differs from size in FW header\n"); 4346 return -EINVAL; 4347 } 4348 if (size > fw_size) { 4349 CH_ERR(adap, "FW image too large, max is %u bytes\n", 4350 fw_size); 4351 return -EFBIG; 4352 } 4353 if (!t4_fw_matches_chip(adap, hdr)) 4354 return -EINVAL; 4355 4356 for (csum = 0, i = 0; i < size / sizeof(csum); i++) 4357 csum += be32_to_cpu(p[i]); 4358 4359 if (csum != 0xffffffff) { 4360 CH_ERR(adap, 4361 "corrupted firmware image, checksum %#x\n", csum); 4362 return -EINVAL; 4363 } 4364 4365 i = DIV_ROUND_UP(size, SF_SEC_SIZE); /* # of sectors spanned */ 4366 ret = t4_flash_erase_sectors(adap, fw_start_sec, fw_start_sec + i - 1); 4367 if (ret) 4368 goto out; 4369 4370 /* 4371 * We write the correct version at the end so the driver can see a bad 4372 * version if the FW write fails. Start by writing a copy of the 4373 * first page with a bad version. 4374 */ 4375 memcpy(first_page, fw_data, SF_PAGE_SIZE); 4376 ((struct fw_hdr *)first_page)->fw_ver = cpu_to_be32(0xffffffff); 4377 ret = t4_write_flash(adap, fw_start, SF_PAGE_SIZE, first_page, 1); 4378 if (ret) 4379 goto out; 4380 4381 addr = fw_start; 4382 for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) { 4383 addr += SF_PAGE_SIZE; 4384 fw_data += SF_PAGE_SIZE; 4385 ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, fw_data, 1); 4386 if (ret) 4387 goto out; 4388 } 4389 4390 ret = t4_write_flash(adap, 4391 fw_start + offsetof(struct fw_hdr, fw_ver), 4392 sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver, 1); 4393 out: 4394 if (ret) 4395 CH_ERR(adap, "firmware download failed, error %d\n", 4396 ret); 4397 return ret; 4398 } 4399 4400 /** 4401 * t4_fwcache - firmware cache operation 4402 * @adap: the adapter 4403 * @op : the operation (flush or flush and invalidate) 4404 */ 4405 int t4_fwcache(struct adapter *adap, enum fw_params_param_dev_fwcache op) 4406 { 4407 struct fw_params_cmd c; 4408 4409 memset(&c, 0, sizeof(c)); 4410 c.op_to_vfn = 4411 cpu_to_be32(V_FW_CMD_OP(FW_PARAMS_CMD) | 4412 F_FW_CMD_REQUEST | F_FW_CMD_WRITE | 4413 V_FW_PARAMS_CMD_PFN(adap->pf) | 4414 V_FW_PARAMS_CMD_VFN(0)); 4415 c.retval_len16 = cpu_to_be32(FW_LEN16(c)); 4416 c.param[0].mnem = 4417 cpu_to_be32(V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | 4418 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_FWCACHE)); 4419 c.param[0].val = cpu_to_be32(op); 4420 4421 return t4_wr_mbox(adap, adap->mbox, &c, sizeof(c), NULL); 4422 } 4423 4424 void t4_cim_read_pif_la(struct adapter *adap, u32 *pif_req, u32 *pif_rsp, 4425 unsigned int *pif_req_wrptr, 4426 unsigned int *pif_rsp_wrptr) 4427 { 4428 int i, j; 4429 u32 cfg, val, req, rsp; 4430 4431 cfg = t4_read_reg(adap, A_CIM_DEBUGCFG); 4432 if (cfg & F_LADBGEN) 4433 t4_write_reg(adap, A_CIM_DEBUGCFG, cfg ^ F_LADBGEN); 4434 4435 val = t4_read_reg(adap, A_CIM_DEBUGSTS); 4436 req = G_POLADBGWRPTR(val); 4437 rsp = G_PILADBGWRPTR(val); 4438 if (pif_req_wrptr) 4439 *pif_req_wrptr = req; 4440 if (pif_rsp_wrptr) 4441 *pif_rsp_wrptr = rsp; 4442 4443 for (i = 0; i < CIM_PIFLA_SIZE; i++) { 4444 for (j = 0; j < 6; j++) { 4445 t4_write_reg(adap, A_CIM_DEBUGCFG, V_POLADBGRDPTR(req) | 4446 V_PILADBGRDPTR(rsp)); 4447 *pif_req++ = t4_read_reg(adap, A_CIM_PO_LA_DEBUGDATA); 4448 *pif_rsp++ = t4_read_reg(adap, A_CIM_PI_LA_DEBUGDATA); 4449 req++; 4450 rsp++; 4451 } 4452 req = (req + 2) & M_POLADBGRDPTR; 4453 rsp = (rsp + 2) & M_PILADBGRDPTR; 4454 } 4455 t4_write_reg(adap, A_CIM_DEBUGCFG, cfg); 4456 } 4457 4458 void t4_cim_read_ma_la(struct adapter *adap, u32 *ma_req, u32 *ma_rsp) 4459 { 4460 u32 cfg; 4461 int i, j, idx; 4462 4463 cfg = t4_read_reg(adap, A_CIM_DEBUGCFG); 4464 if (cfg & F_LADBGEN) 4465 t4_write_reg(adap, A_CIM_DEBUGCFG, cfg ^ F_LADBGEN); 4466 4467 for (i = 0; i < CIM_MALA_SIZE; i++) { 4468 for (j = 0; j < 5; j++) { 4469 idx = 8 * i + j; 4470 t4_write_reg(adap, A_CIM_DEBUGCFG, V_POLADBGRDPTR(idx) | 4471 V_PILADBGRDPTR(idx)); 4472 *ma_req++ = t4_read_reg(adap, A_CIM_PO_LA_MADEBUGDATA); 4473 *ma_rsp++ = t4_read_reg(adap, A_CIM_PI_LA_MADEBUGDATA); 4474 } 4475 } 4476 t4_write_reg(adap, A_CIM_DEBUGCFG, cfg); 4477 } 4478 4479 void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf) 4480 { 4481 unsigned int i, j; 4482 4483 for (i = 0; i < 8; i++) { 4484 u32 *p = la_buf + i; 4485 4486 t4_write_reg(adap, A_ULP_RX_LA_CTL, i); 4487 j = t4_read_reg(adap, A_ULP_RX_LA_WRPTR); 4488 t4_write_reg(adap, A_ULP_RX_LA_RDPTR, j); 4489 for (j = 0; j < ULPRX_LA_SIZE; j++, p += 8) 4490 *p = t4_read_reg(adap, A_ULP_RX_LA_RDDATA); 4491 } 4492 } 4493 4494 /** 4495 * fwcaps16_to_caps32 - convert 16-bit Port Capabilities to 32-bits 4496 * @caps16: a 16-bit Port Capabilities value 4497 * 4498 * Returns the equivalent 32-bit Port Capabilities value. 4499 */ 4500 static uint32_t fwcaps16_to_caps32(uint16_t caps16) 4501 { 4502 uint32_t caps32 = 0; 4503 4504 #define CAP16_TO_CAP32(__cap) \ 4505 do { \ 4506 if (caps16 & FW_PORT_CAP_##__cap) \ 4507 caps32 |= FW_PORT_CAP32_##__cap; \ 4508 } while (0) 4509 4510 CAP16_TO_CAP32(SPEED_100M); 4511 CAP16_TO_CAP32(SPEED_1G); 4512 CAP16_TO_CAP32(SPEED_25G); 4513 CAP16_TO_CAP32(SPEED_10G); 4514 CAP16_TO_CAP32(SPEED_40G); 4515 CAP16_TO_CAP32(SPEED_100G); 4516 CAP16_TO_CAP32(FC_RX); 4517 CAP16_TO_CAP32(FC_TX); 4518 CAP16_TO_CAP32(ANEG); 4519 CAP16_TO_CAP32(FORCE_PAUSE); 4520 CAP16_TO_CAP32(MDIAUTO); 4521 CAP16_TO_CAP32(MDISTRAIGHT); 4522 CAP16_TO_CAP32(FEC_RS); 4523 CAP16_TO_CAP32(FEC_BASER_RS); 4524 CAP16_TO_CAP32(802_3_PAUSE); 4525 CAP16_TO_CAP32(802_3_ASM_DIR); 4526 4527 #undef CAP16_TO_CAP32 4528 4529 return caps32; 4530 } 4531 4532 /** 4533 * fwcaps32_to_caps16 - convert 32-bit Port Capabilities to 16-bits 4534 * @caps32: a 32-bit Port Capabilities value 4535 * 4536 * Returns the equivalent 16-bit Port Capabilities value. Note that 4537 * not all 32-bit Port Capabilities can be represented in the 16-bit 4538 * Port Capabilities and some fields/values may not make it. 4539 */ 4540 static uint16_t fwcaps32_to_caps16(uint32_t caps32) 4541 { 4542 uint16_t caps16 = 0; 4543 4544 #define CAP32_TO_CAP16(__cap) \ 4545 do { \ 4546 if (caps32 & FW_PORT_CAP32_##__cap) \ 4547 caps16 |= FW_PORT_CAP_##__cap; \ 4548 } while (0) 4549 4550 CAP32_TO_CAP16(SPEED_100M); 4551 CAP32_TO_CAP16(SPEED_1G); 4552 CAP32_TO_CAP16(SPEED_10G); 4553 CAP32_TO_CAP16(SPEED_25G); 4554 CAP32_TO_CAP16(SPEED_40G); 4555 CAP32_TO_CAP16(SPEED_100G); 4556 CAP32_TO_CAP16(FC_RX); 4557 CAP32_TO_CAP16(FC_TX); 4558 CAP32_TO_CAP16(802_3_PAUSE); 4559 CAP32_TO_CAP16(802_3_ASM_DIR); 4560 CAP32_TO_CAP16(ANEG); 4561 CAP32_TO_CAP16(FORCE_PAUSE); 4562 CAP32_TO_CAP16(MDIAUTO); 4563 CAP32_TO_CAP16(MDISTRAIGHT); 4564 CAP32_TO_CAP16(FEC_RS); 4565 CAP32_TO_CAP16(FEC_BASER_RS); 4566 4567 #undef CAP32_TO_CAP16 4568 4569 return caps16; 4570 } 4571 4572 static int8_t fwcap_to_fec(uint32_t caps, bool unset_means_none) 4573 { 4574 int8_t fec = 0; 4575 4576 if ((caps & V_FW_PORT_CAP32_FEC(M_FW_PORT_CAP32_FEC)) == 0) 4577 return (unset_means_none ? FEC_NONE : 0); 4578 4579 if (caps & FW_PORT_CAP32_FEC_RS) 4580 fec |= FEC_RS; 4581 if (caps & FW_PORT_CAP32_FEC_BASER_RS) 4582 fec |= FEC_BASER_RS; 4583 if (caps & FW_PORT_CAP32_FEC_NO_FEC) 4584 fec |= FEC_NONE; 4585 4586 return (fec); 4587 } 4588 4589 /* 4590 * Note that 0 is not translated to NO_FEC. 4591 */ 4592 static uint32_t fec_to_fwcap(int8_t fec) 4593 { 4594 uint32_t caps = 0; 4595 4596 /* Only real FECs allowed. */ 4597 MPASS((fec & ~M_FW_PORT_CAP32_FEC) == 0); 4598 4599 if (fec & FEC_RS) 4600 caps |= FW_PORT_CAP32_FEC_RS; 4601 if (fec & FEC_BASER_RS) 4602 caps |= FW_PORT_CAP32_FEC_BASER_RS; 4603 if (fec & FEC_NONE) 4604 caps |= FW_PORT_CAP32_FEC_NO_FEC; 4605 4606 return (caps); 4607 } 4608 4609 /** 4610 * t4_link_l1cfg - apply link configuration to MAC/PHY 4611 * @phy: the PHY to setup 4612 * @mac: the MAC to setup 4613 * @lc: the requested link configuration 4614 * 4615 * Set up a port's MAC and PHY according to a desired link configuration. 4616 * - If the PHY can auto-negotiate first decide what to advertise, then 4617 * enable/disable auto-negotiation as desired, and reset. 4618 * - If the PHY does not auto-negotiate just reset it. 4619 * - If auto-negotiation is off set the MAC to the proper speed/duplex/FC, 4620 * otherwise do it later based on the outcome of auto-negotiation. 4621 */ 4622 int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port, 4623 struct link_config *lc) 4624 { 4625 struct fw_port_cmd c; 4626 unsigned int mdi = V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO); 4627 unsigned int aneg, fc, fec, speed, rcap; 4628 4629 fc = 0; 4630 if (lc->requested_fc & PAUSE_RX) 4631 fc |= FW_PORT_CAP32_FC_RX; 4632 if (lc->requested_fc & PAUSE_TX) 4633 fc |= FW_PORT_CAP32_FC_TX; 4634 if (!(lc->requested_fc & PAUSE_AUTONEG)) 4635 fc |= FW_PORT_CAP32_FORCE_PAUSE; 4636 4637 if (lc->requested_aneg == AUTONEG_DISABLE) 4638 aneg = 0; 4639 else if (lc->requested_aneg == AUTONEG_ENABLE) 4640 aneg = FW_PORT_CAP32_ANEG; 4641 else 4642 aneg = lc->pcaps & FW_PORT_CAP32_ANEG; 4643 4644 if (aneg) { 4645 speed = lc->pcaps & 4646 V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED); 4647 } else if (lc->requested_speed != 0) 4648 speed = speed_to_fwcap(lc->requested_speed); 4649 else 4650 speed = fwcap_top_speed(lc->pcaps); 4651 4652 fec = 0; 4653 if (fec_supported(speed)) { 4654 int force_fec; 4655 4656 if (lc->pcaps & FW_PORT_CAP32_FORCE_FEC) 4657 force_fec = lc->force_fec; 4658 else 4659 force_fec = 0; 4660 4661 if (lc->requested_fec == FEC_AUTO) { 4662 if (force_fec > 0) { 4663 /* 4664 * Must use FORCE_FEC even though requested FEC 4665 * is AUTO. Set all the FEC bits valid for the 4666 * speed and let the firmware pick one. 4667 */ 4668 fec |= FW_PORT_CAP32_FORCE_FEC; 4669 if (speed & FW_PORT_CAP32_SPEED_25G) { 4670 fec |= FW_PORT_CAP32_FEC_RS; 4671 fec |= FW_PORT_CAP32_FEC_BASER_RS; 4672 fec |= FW_PORT_CAP32_FEC_NO_FEC; 4673 } else { 4674 fec |= FW_PORT_CAP32_FEC_RS; 4675 fec |= FW_PORT_CAP32_FEC_NO_FEC; 4676 } 4677 } else { 4678 /* 4679 * Set only 1b. Old firmwares can't deal with 4680 * multiple bits and new firmwares are free to 4681 * ignore this and try whatever FECs they want 4682 * because we aren't setting FORCE_FEC here. 4683 */ 4684 fec |= fec_to_fwcap(lc->fec_hint); 4685 MPASS(powerof2(fec)); 4686 4687 /* 4688 * Override the hint if the FEC is not valid for 4689 * the potential top speed. Request the best 4690 * FEC at that speed instead. 4691 */ 4692 if ((speed & FW_PORT_CAP32_SPEED_25G) == 0 && 4693 fec == FW_PORT_CAP32_FEC_BASER_RS) { 4694 fec = FW_PORT_CAP32_FEC_RS; 4695 } 4696 } 4697 } else { 4698 /* 4699 * User has explicitly requested some FEC(s). Set 4700 * FORCE_FEC unless prohibited from using it. 4701 */ 4702 if (force_fec != 0) 4703 fec |= FW_PORT_CAP32_FORCE_FEC; 4704 fec |= fec_to_fwcap(lc->requested_fec & 4705 M_FW_PORT_CAP32_FEC); 4706 if (lc->requested_fec & FEC_MODULE) 4707 fec |= fec_to_fwcap(lc->fec_hint); 4708 } 4709 4710 /* 4711 * This is for compatibility with old firmwares. The original 4712 * way to request NO_FEC was to not set any of the FEC bits. New 4713 * firmwares understand this too. 4714 */ 4715 if (fec == FW_PORT_CAP32_FEC_NO_FEC) 4716 fec = 0; 4717 } 4718 4719 /* Force AN on for BT cards. */ 4720 if (isset(&adap->bt_map, port)) 4721 aneg = lc->pcaps & FW_PORT_CAP32_ANEG; 4722 4723 rcap = aneg | speed | fc | fec; 4724 if ((rcap | lc->pcaps) != lc->pcaps) { 4725 #ifdef INVARIANTS 4726 CH_WARN(adap, "rcap 0x%08x, pcap 0x%08x, removed 0x%x\n", rcap, 4727 lc->pcaps, rcap & (rcap ^ lc->pcaps)); 4728 #endif 4729 rcap &= lc->pcaps; 4730 } 4731 rcap |= mdi; 4732 4733 memset(&c, 0, sizeof(c)); 4734 c.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | 4735 F_FW_CMD_REQUEST | F_FW_CMD_EXEC | 4736 V_FW_PORT_CMD_PORTID(port)); 4737 if (adap->params.port_caps32) { 4738 c.action_to_len16 = 4739 cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG32) | 4740 FW_LEN16(c)); 4741 c.u.l1cfg32.rcap32 = cpu_to_be32(rcap); 4742 } else { 4743 c.action_to_len16 = 4744 cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | 4745 FW_LEN16(c)); 4746 c.u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(rcap)); 4747 } 4748 4749 lc->requested_caps = rcap; 4750 return t4_wr_mbox_ns(adap, mbox, &c, sizeof(c), NULL); 4751 } 4752 4753 /** 4754 * t4_restart_aneg - restart autonegotiation 4755 * @adap: the adapter 4756 * @mbox: mbox to use for the FW command 4757 * @port: the port id 4758 * 4759 * Restarts autonegotiation for the selected port. 4760 */ 4761 int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port) 4762 { 4763 struct fw_port_cmd c; 4764 4765 memset(&c, 0, sizeof(c)); 4766 c.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | 4767 F_FW_CMD_REQUEST | F_FW_CMD_EXEC | 4768 V_FW_PORT_CMD_PORTID(port)); 4769 c.action_to_len16 = 4770 cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | 4771 FW_LEN16(c)); 4772 c.u.l1cfg.rcap = cpu_to_be32(FW_PORT_CAP_ANEG); 4773 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 4774 } 4775 4776 struct intr_details { 4777 u32 mask; 4778 const char *msg; 4779 }; 4780 4781 struct intr_action { 4782 u32 mask; 4783 int arg; 4784 bool (*action)(struct adapter *, int, int); 4785 }; 4786 4787 struct intr_info { 4788 const char *name; /* name of the INT_CAUSE register */ 4789 int cause_reg; /* INT_CAUSE register */ 4790 int enable_reg; /* INT_ENABLE register */ 4791 u32 fatal; /* bits that are fatal */ 4792 int flags; /* hints */ 4793 const struct intr_details *details; 4794 const struct intr_action *actions; 4795 }; 4796 4797 /* Helper to clear interrupts that have IHF_CLR_DELAYED. */ 4798 static void 4799 clear_int_cause_reg(struct adapter *sc, const struct intr_info *ii, int flags) 4800 { 4801 u32 cause, ucause; 4802 4803 cause = ucause = t4_read_reg(sc, ii->cause_reg); 4804 if (cause == 0) 4805 return; 4806 flags |= ii->flags; 4807 if (flags & IHF_IGNORE_IF_DISABLED) 4808 ucause &= t4_read_reg(sc, ii->enable_reg); 4809 if (flags & IHF_CLR_ALL_SET) { 4810 t4_write_reg(sc, ii->cause_reg, cause); 4811 (void)t4_read_reg(sc, ii->cause_reg); 4812 } else if (ucause != 0 && flags & IHF_CLR_ALL_UNIGNORED) { 4813 t4_write_reg(sc, ii->cause_reg, ucause); 4814 (void)t4_read_reg(sc, ii->cause_reg); 4815 } 4816 } 4817 4818 static inline char 4819 intr_alert_char(u32 cause, u32 enable, u32 fatal) 4820 { 4821 if (cause & fatal) 4822 return ('!'); 4823 if (cause & enable) 4824 return ('*'); 4825 return ('-'); 4826 } 4827 4828 static void 4829 show_intr_info(struct adapter *sc, const struct intr_info *ii, uint32_t cause, 4830 uint32_t ucause, uint32_t enabled, uint32_t fatal, int flags) 4831 { 4832 uint32_t leftover, msgbits; 4833 const struct intr_details *details; 4834 char alert; 4835 const bool verbose = flags & IHF_VERBOSE; 4836 4837 if (verbose || ucause != 0 || flags & IHF_RUN_ALL_ACTIONS) { 4838 alert = intr_alert_char(cause, enabled, fatal); 4839 CH_ALERT(sc, "%c %s 0x%x = 0x%08x, E 0x%08x, F 0x%08x\n", alert, 4840 ii->name, ii->cause_reg, cause, enabled, ii->fatal); 4841 } 4842 4843 leftover = verbose ? cause : ucause; 4844 for (details = ii->details; details && details->mask != 0; details++) { 4845 msgbits = details->mask & leftover; 4846 if (msgbits == 0) 4847 continue; 4848 alert = intr_alert_char(msgbits, enabled, fatal); 4849 CH_ALERT(sc, " %c [0x%08x] %s\n", alert, msgbits, details->msg); 4850 leftover &= ~msgbits; 4851 } 4852 if (leftover != 0 && leftover != (verbose ? cause : ucause)) { 4853 alert = intr_alert_char(leftover, enabled, fatal); 4854 CH_ALERT(sc, " %c [0x%08x]\n", alert, leftover); 4855 } 4856 } 4857 4858 /* 4859 * Returns true for fatal error. 4860 */ 4861 static bool 4862 t4_handle_intr(struct adapter *sc, const struct intr_info *ii, uint32_t acause, 4863 int flags) 4864 { 4865 uint32_t cause, ucause, enabled, fatal; 4866 bool rc; 4867 const struct intr_action *action; 4868 4869 cause = t4_read_reg(sc, ii->cause_reg); 4870 enabled = t4_read_reg(sc, ii->enable_reg); 4871 flags |= ii->flags; 4872 fatal = ii->fatal & cause; 4873 if (flags & IHF_FATAL_IFF_ENABLED) 4874 fatal &= enabled; 4875 ucause = cause; 4876 if (flags & IHF_IGNORE_IF_DISABLED) 4877 ucause &= enabled; 4878 if (!(flags & IHF_NO_SHOW)) 4879 show_intr_info(sc, ii, cause, ucause, enabled, fatal, flags); 4880 4881 rc = fatal != 0; 4882 for (action = ii->actions; action && action->mask != 0; action++) { 4883 if (action->action == NULL) 4884 continue; 4885 if (action->mask & (ucause | acause) || 4886 flags & IHF_RUN_ALL_ACTIONS) { 4887 bool rc1 = (action->action)(sc, action->arg, flags); 4888 if (action->mask & ucause) 4889 rc |= rc1; 4890 } 4891 } 4892 4893 /* Clear here unless delayed clear is requested. */ 4894 if (cause != 0 && (flags & IHF_CLR_DELAYED) == 0) { 4895 if (flags & IHF_CLR_ALL_SET) { 4896 t4_write_reg(sc, ii->cause_reg, cause); 4897 (void)t4_read_reg(sc, ii->cause_reg); 4898 } else if (ucause != 0 && flags & IHF_CLR_ALL_UNIGNORED) { 4899 t4_write_reg(sc, ii->cause_reg, ucause); 4900 (void)t4_read_reg(sc, ii->cause_reg); 4901 } 4902 } 4903 4904 return (rc); 4905 } 4906 4907 /* 4908 * Interrupt handler for the PCIE module. 4909 */ 4910 static bool pcie_intr_handler(struct adapter *adap, int arg, int flags) 4911 { 4912 static const struct intr_details sysbus_intr_details[] = { 4913 { F_RNPP, "RXNP array parity error" }, 4914 { F_RPCP, "RXPC array parity error" }, 4915 { F_RCIP, "RXCIF array parity error" }, 4916 { F_RCCP, "Rx completions control array parity error" }, 4917 { F_RFTP, "RXFT array parity error" }, 4918 { 0 } 4919 }; 4920 static const struct intr_info sysbus_intr_info = { 4921 .name = "PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS", 4922 .cause_reg = A_PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS, 4923 .enable_reg = A_PCIE_CORE_UTL_SYSTEM_BUS_AGENT_INTERRUPT_ENABLE, 4924 .fatal = F_RFTP | F_RCCP | F_RCIP | F_RPCP | F_RNPP, 4925 .flags = 0, 4926 .details = sysbus_intr_details, 4927 .actions = NULL, 4928 }; 4929 static const struct intr_details pcie_port_intr_details[] = { 4930 { F_TPCP, "TXPC array parity error" }, 4931 { F_TNPP, "TXNP array parity error" }, 4932 { F_TFTP, "TXFT array parity error" }, 4933 { F_TCAP, "TXCA array parity error" }, 4934 { F_TCIP, "TXCIF array parity error" }, 4935 { F_RCAP, "RXCA array parity error" }, 4936 { F_OTDD, "outbound request TLP discarded" }, 4937 { F_RDPE, "Rx data parity error" }, 4938 { F_TDUE, "Tx uncorrectable data error" }, 4939 { 0 } 4940 }; 4941 static const struct intr_info pcie_port_intr_info = { 4942 .name = "PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS", 4943 .cause_reg = A_PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, 4944 .enable_reg = A_PCIE_CORE_UTL_PCI_EXPRESS_PORT_INTERRUPT_ENABLE, 4945 .fatal = F_TPCP | F_TNPP | F_TFTP | F_TCAP | F_TCIP | F_RCAP | 4946 F_OTDD | F_RDPE | F_TDUE, 4947 .flags = 0, 4948 .details = pcie_port_intr_details, 4949 .actions = NULL, 4950 }; 4951 static const struct intr_details pcie_intr_details[] = { 4952 { F_MSIADDRLPERR, "MSI AddrL parity error" }, 4953 { F_MSIADDRHPERR, "MSI AddrH parity error" }, 4954 { F_MSIDATAPERR, "MSI data parity error" }, 4955 { F_MSIXADDRLPERR, "MSI-X AddrL parity error" }, 4956 { F_MSIXADDRHPERR, "MSI-X AddrH parity error" }, 4957 { F_MSIXDATAPERR, "MSI-X data parity error" }, 4958 { F_MSIXDIPERR, "MSI-X DI parity error" }, 4959 { F_PIOCPLPERR, "PCIe PIO completion FIFO parity error" }, 4960 { F_PIOREQPERR, "PCIe PIO request FIFO parity error" }, 4961 { F_TARTAGPERR, "PCIe target tag FIFO parity error" }, 4962 { F_CCNTPERR, "PCIe CMD channel count parity error" }, 4963 { F_CREQPERR, "PCIe CMD channel request parity error" }, 4964 { F_CRSPPERR, "PCIe CMD channel response parity error" }, 4965 { F_DCNTPERR, "PCIe DMA channel count parity error" }, 4966 { F_DREQPERR, "PCIe DMA channel request parity error" }, 4967 { F_DRSPPERR, "PCIe DMA channel response parity error" }, 4968 { F_HCNTPERR, "PCIe HMA channel count parity error" }, 4969 { F_HREQPERR, "PCIe HMA channel request parity error" }, 4970 { F_HRSPPERR, "PCIe HMA channel response parity error" }, 4971 { F_CFGSNPPERR, "PCIe config snoop FIFO parity error" }, 4972 { F_FIDPERR, "PCIe FID parity error" }, 4973 { F_INTXCLRPERR, "PCIe INTx clear parity error" }, 4974 { F_MATAGPERR, "PCIe MA tag parity error" }, 4975 { F_PIOTAGPERR, "PCIe PIO tag parity error" }, 4976 { F_RXCPLPERR, "PCIe Rx completion parity error" }, 4977 { F_RXWRPERR, "PCIe Rx write parity error" }, 4978 { F_RPLPERR, "PCIe replay buffer parity error" }, 4979 { F_PCIESINT, "PCIe core secondary fault" }, 4980 { F_PCIEPINT, "PCIe core primary fault" }, 4981 { F_UNXSPLCPLERR, "PCIe unexpected split completion error" }, 4982 { 0 } 4983 }; 4984 static const struct intr_details t5_pcie_intr_details[] = { 4985 { F_IPGRPPERR, "Parity errors observed by IP" }, 4986 { F_NONFATALERR, "PCIe non-fatal error" }, 4987 { F_READRSPERR, "Outbound read error" }, 4988 { F_TRGT1GRPPERR, "PCIe TRGT1 group FIFOs parity error" }, 4989 { F_IPSOTPERR, "PCIe IP SOT buffer SRAM parity error" }, 4990 { F_IPRETRYPERR, "PCIe IP replay buffer parity error" }, 4991 { F_IPRXDATAGRPPERR, "PCIe IP Rx data group SRAMs parity error" }, 4992 { F_IPRXHDRGRPPERR, "PCIe IP Rx header group SRAMs parity error" }, 4993 { F_PIOTAGQPERR, "PIO tag queue FIFO parity error" }, 4994 { F_MAGRPPERR, "MA group FIFO parity error" }, 4995 { F_VFIDPERR, "VFID SRAM parity error" }, 4996 { F_FIDPERR, "FID SRAM parity error" }, 4997 { F_CFGSNPPERR, "config snoop FIFO parity error" }, 4998 { F_HRSPPERR, "HMA channel response data SRAM parity error" }, 4999 { F_HREQRDPERR, "HMA channel read request SRAM parity error" }, 5000 { F_HREQWRPERR, "HMA channel write request SRAM parity error" }, 5001 { F_DRSPPERR, "DMA channel response data SRAM parity error" }, 5002 { F_DREQRDPERR, "DMA channel write request SRAM parity error" }, 5003 { F_CRSPPERR, "CMD channel response data SRAM parity error" }, 5004 { F_CREQRDPERR, "CMD channel read request SRAM parity error" }, 5005 { F_MSTTAGQPERR, "PCIe master tag queue SRAM parity error" }, 5006 { F_TGTTAGQPERR, "PCIe target tag queue FIFO parity error" }, 5007 { F_PIOREQGRPPERR, "PIO request group FIFOs parity error" }, 5008 { F_PIOCPLGRPPERR, "PIO completion group FIFOs parity error" }, 5009 { F_MSIXDIPERR, "MSI-X DI SRAM parity error" }, 5010 { F_MSIXDATAPERR, "MSI-X data SRAM parity error" }, 5011 { F_MSIXADDRHPERR, "MSI-X AddrH SRAM parity error" }, 5012 { F_MSIXADDRLPERR, "MSI-X AddrL SRAM parity error" }, 5013 { F_MSIXSTIPERR, "MSI-X STI SRAM parity error" }, 5014 { F_MSTTIMEOUTPERR, "Master timeout FIFO parity error" }, 5015 { F_MSTGRPPERR, "Master response read queue SRAM parity error" }, 5016 { 0 } 5017 }; 5018 struct intr_info pcie_intr_info = { 5019 .name = "PCIE_INT_CAUSE", 5020 .cause_reg = A_PCIE_INT_CAUSE, 5021 .enable_reg = A_PCIE_INT_ENABLE, 5022 .fatal = 0xffffffff, 5023 .flags = IHF_FATAL_IFF_ENABLED, 5024 .details = NULL, 5025 .actions = NULL, 5026 }; 5027 static const struct intr_details pcie_intr_cause_ext_details[] = { 5028 { F_IPFORMQPERR, "PCIe IP FormQ Buffer PERR" }, 5029 { F_IPFORMQCERR, "PCIe IP FormQ Buffer CERR" }, 5030 { F_TRGT1GRPCERR, "TRGT1 Group FIFOs CERR" }, 5031 { F_IPSOTCERR, "PCIe IP SOT Buffer SRAM CERR" }, 5032 { F_IPRETRYCERR, "PCIe IP Replay Buffer CERR" }, 5033 { F_IPRXDATAGRPCERR, "PCIe IP Rx Data Group SRAMs CERR" }, 5034 { F_IPRXHDRGRPCERR, "PCIe IP Rx Header Group SRAMs CERR" }, 5035 { F_A0ARBRSPORDFIFOPERR, "A0 Arbiter Response Order FIFO Parity Error" }, 5036 { F_HRSPCERR, "Master HMA Channel Response Data SRAM CERR" }, 5037 { F_HREQRDCERR, "Master HMA Channel Read Request SRAM CERR" }, 5038 { F_HREQWRCERR, "Master HMA Channel Write Request SRAM CERR" }, 5039 { F_DRSPCERR, "Master DMA Channel Response Data SRAM CERR" }, 5040 { F_DREQRDCERR, "Master DMA Channel Read Request SRAM CERR" }, 5041 { F_DREQWRCERR, "Master DMA Channel Write Request SRAM CERR" }, 5042 { F_CRSPCERR, "Master CMD Channel Response Data SRAM CERR" }, 5043 { F_ARSPPERR, "Master ARM Channel Response Data SRAM PERR" }, 5044 { F_AREQRDPERR, "Master ARM Channel Read Request SRAM PERR" }, 5045 { F_AREQWRPERR, "Master ARM Channel Write Request SRAM PERR" }, 5046 { F_PIOREQGRPCERR, "PIO Request Group FIFOs CERR" }, 5047 { F_ARSPCERR, "Master ARM Channel Response Data SRAM CERR" }, 5048 { F_AREQRDCERR, "Master ARM Channel Read Request SRAM CERR" }, 5049 { F_AREQWRCERR, "Master ARM Channel Write Request SRAM CERR" }, 5050 { F_MARSPPERR, "INIC MA Ctrl and Data Rsp Perr" }, 5051 { F_INICMAWDATAORDPERR, "INIC Ma Arb Write Ord Data Fifo Perr" }, 5052 { F_EMUPERR, "CFG EMU SRAM PERR" }, 5053 { F_ERRSPPERR, "CFG EMU SRAM CERR" }, 5054 { F_MSTGRPCERR, "Master Data Path and Response Read Queue SRAM CERR" }, 5055 { 0 } 5056 }; 5057 struct intr_info pcie_int_cause_ext = { 5058 .name = "PCIE_INT_CAUSE_EXT", 5059 .cause_reg = A_PCIE_INT_CAUSE_EXT, 5060 .enable_reg = A_PCIE_INT_ENABLE_EXT, 5061 .fatal = 0, 5062 .flags = 0, 5063 .details = pcie_intr_cause_ext_details, 5064 .actions = NULL, 5065 }; 5066 static const struct intr_details pcie_intr_cause_x8_details[] = { 5067 { F_X8TGTGRPPERR, "x8 TGT Group FIFOs parity error" }, 5068 { F_X8IPSOTPERR, "PCIe x8 IP SOT Buffer SRAM PERR" }, 5069 { F_X8IPRETRYPERR, "PCIe x8 IP Replay Buffer PERR" }, 5070 { F_X8IPRXDATAGRPPERR, "PCIe x8 IP Rx Data Group SRAMs PERR" }, 5071 { F_X8IPRXHDRGRPPERR, "PCIe x8 IP Rx Header Group SRAMs PERR" }, 5072 { F_X8IPCORECERR, "x8 IP SOT, Retry, RxData, RxHdr SRAM CERR" }, 5073 { F_X8MSTGRPPERR, "x8 Master Data Path and Response Read Queue SRAM PERR" }, 5074 { F_X8MSTGRPCERR, "x8 Master Data Path and Response Read Queue SRAM CERR" }, 5075 { 0 } 5076 }; 5077 struct intr_info pcie_int_cause_x8 = { 5078 .name = "PCIE_INT_CAUSE_X8", 5079 .cause_reg = A_PCIE_INT_CAUSE_X8, 5080 .enable_reg = A_PCIE_INT_ENABLE_X8, 5081 .fatal = 0, 5082 .flags = 0, 5083 .details = pcie_intr_cause_x8_details, 5084 .actions = NULL, 5085 }; 5086 bool fatal = false; 5087 5088 if (is_t4(adap)) { 5089 fatal |= t4_handle_intr(adap, &sysbus_intr_info, 0, flags); 5090 fatal |= t4_handle_intr(adap, &pcie_port_intr_info, 0, flags); 5091 5092 pcie_intr_info.details = pcie_intr_details; 5093 } else { 5094 pcie_intr_info.details = t5_pcie_intr_details; 5095 } 5096 fatal |= t4_handle_intr(adap, &pcie_intr_info, 0, flags); 5097 if (chip_id(adap) > CHELSIO_T6) { 5098 fatal |= t4_handle_intr(adap, &pcie_int_cause_ext, 0, flags); 5099 fatal |= t4_handle_intr(adap, &pcie_int_cause_x8, 0, flags); 5100 } 5101 5102 return (fatal); 5103 } 5104 5105 /* 5106 * TP interrupt handler. 5107 */ 5108 static bool tp_intr_handler(struct adapter *adap, int arg, int flags) 5109 { 5110 static const struct intr_details tp_intr_details[] = { 5111 { 0x3fffffff, "TP parity error" }, 5112 { F_FLMTXFLSTEMPTY, "TP out of Tx pages" }, 5113 { 0 } 5114 }; 5115 static const struct intr_details t7_tp_intr_details[] = { 5116 { F_FLMTXFLSTEMPTY, "Offload memory manager Tx free list empty" }, 5117 { F_TPCERR, "TP modules flagged Correctable Error" }, 5118 { F_OTHERPERR, "TP Other modules (Core, TM, FLM, MMGR, DB) Parity Error" }, 5119 { F_TPEING1PERR, "TP-ESide Ingress1 Parity Error" }, 5120 { F_TPEING0PERR, "TP-ESide Ingress0 Parity Error" }, 5121 { F_TPEEGPERR, "TP-ESide Egress Parity Error" }, 5122 { F_TPCPERR, "TP-CSide Parity Error" }, 5123 { 0 } 5124 }; 5125 struct intr_info tp_intr_info = { 5126 .name = "TP_INT_CAUSE", 5127 .cause_reg = A_TP_INT_CAUSE, 5128 .enable_reg = A_TP_INT_ENABLE, 5129 .fatal = 0x7fffffff, 5130 .flags = IHF_FATAL_IFF_ENABLED | IHF_CLR_DELAYED, 5131 .details = NULL, 5132 .actions = NULL, 5133 }; 5134 static const struct intr_details tp_cerr_cause_details[] = { 5135 { F_TPCEGDATAFIFO, "TPCSide Egress Data FIFO" }, 5136 { F_TPCLBKDATAFIFO, "TPCSide Loopback Data FIFO" }, 5137 { F_RSSLKPSRAM, "RSS Lookup SRAM" }, 5138 { F_SRQSRAM, "SRQ SRAM" }, 5139 { F_ARPDASRAM, "ARP DA SRAM" }, 5140 { F_ARPSASRAM, "ARP SA SRAM" }, 5141 { F_ARPGRESRAM, "ARP GRE SRAM" }, 5142 { F_ARPIPSECSRAM1, "ARP IPSec SRAM0" }, 5143 { F_ARPIPSECSRAM0, "ARP IPSec SRAM1" }, 5144 { 0 } 5145 }; 5146 static const struct intr_info tp_cerr_cause = { 5147 .name = "TP_CERR_CAUSE", 5148 .cause_reg = A_TP_CERR_CAUSE, 5149 .enable_reg = A_TP_CERR_ENABLE, 5150 .fatal = 0xffffffff, 5151 .flags = IHF_FATAL_IFF_ENABLED, 5152 .details = tp_cerr_cause_details, 5153 .actions = NULL, 5154 }; 5155 static const struct intr_details tp_c_perr_details[] = { 5156 { F_DMXFIFOOVFL, "Demux FIFO Overflow" }, 5157 { F_URX2TPCDDPINTF, "ULPRX to TPC DDP Interface and FIFO" }, 5158 { F_TPCDISPTOKENFIFO, "TPC Dispatch Token FIFO" }, 5159 { F_TPCDISPCPLFIFO3, "TPC Dispatch CPL FIFO Ch3" }, 5160 { F_TPCDISPCPLFIFO2, "TPC Dispatch CPL FIFO Ch2" }, 5161 { F_TPCDISPCPLFIFO1, "TPC Dispatch CPL FIFO Ch1" }, 5162 { F_TPCDISPCPLFIFO0, "TPC Dispatch CPL FIFO Ch0" }, 5163 { F_URXPLDINTFCRC3, "ULPRX to TPC Payload Interface CRC Error Ch3" }, 5164 { F_URXPLDINTFCRC2, "ULPRX to TPC Payload Interface CRC Error Ch2" }, 5165 { F_URXPLDINTFCRC1, "ULPRX to TPC Payload Interface CRC Error Ch1" }, 5166 { F_URXPLDINTFCRC0, "ULPRX to TPC Payload Interface CRC Error Ch0" }, 5167 { F_DMXDBFIFO, "Demux DB FIFO" }, 5168 { F_DMXDBSRAM, "Demux DB SRAM" }, 5169 { F_DMXCPLFIFO, "Demux CPL FIFO" }, 5170 { F_DMXCPLSRAM, "Demux CPL SRAM" }, 5171 { F_DMXCSUMFIFO, "Demux Checksum FIFO" }, 5172 { F_DMXLENFIFO, "Demux Length FIFO" }, 5173 { F_DMXCHECKFIFO, "Demux Check CRC16 FIFO" }, 5174 { F_DMXWINFIFO, "Demux Winner FIFO" }, 5175 { F_EGTOKENFIFO, "Egress Token FIFO Parity Error" }, 5176 { F_EGDATAFIFO, "Egress FIFO Parity Error" }, 5177 { F_UTX2TPCINTF3, "ULPTX to TPC Interface Parity Error Ch3" }, 5178 { F_UTX2TPCINTF2, "ULPTX to TPC Interface Parity Error Ch2" }, 5179 { F_UTX2TPCINTF1, "ULPTX to TPC Interface Parity Error Ch1" }, 5180 { F_UTX2TPCINTF0, "ULPTX to TPC Interface Parity Error Ch0" }, 5181 { F_LBKTOKENFIFO, "Loopback Token FIFO Parity Error" }, 5182 { F_LBKDATAFIFO, "Loopback FIFO Parity Error" }, 5183 { 0 } 5184 }; 5185 static const struct intr_info tp_c_perr_cause = { 5186 .name = "TP_C_PERR_CAUSE", 5187 .cause_reg = A_TP_C_PERR_CAUSE, 5188 .enable_reg = A_TP_C_PERR_ENABLE, 5189 .fatal = 0xffffffff, 5190 .flags = IHF_FATAL_IFF_ENABLED, 5191 .details = tp_c_perr_details, 5192 .actions = NULL, 5193 }; 5194 static const struct intr_details tp_e_eg_perr_details[] = { 5195 { F_MPSLPBKTOKENFIFO, "MPS Loopback Token FIFO parity error" }, 5196 { F_MPSMACTOKENFIFO, "MPS MAC Token FIFO parity error" }, 5197 { F_DISPIPSECFIFO3, "Ch3 Dispatch IPSec FIFO parity error" }, 5198 { F_DISPTCPFIFO3, "Ch3 Dispatch TCP FIFO parity error" }, 5199 { F_DISPIPFIFO3, "Ch3 Dispatch IP FIFO parity error" }, 5200 { F_DISPETHFIFO3, "Ch3 Dispatch ETH FIFO parity error" }, 5201 { F_DISPGREFIFO3, "Ch3 Dispatch GRE FIFO parity error" }, 5202 { F_DISPCPL5FIFO3, "Ch3 Dispatch CPL5 FIFO parity error" }, 5203 { F_DISPIPSECFIFO2, "Ch2 Dispatch IPSec FIFO parity error" }, 5204 { F_DISPTCPFIFO2, "Ch2 Dispatch TCP FIFO parity error" }, 5205 { F_DISPIPFIFO2, "Ch2 Dispatch IP FIFO parity error" }, 5206 { F_DISPETHFIFO2, "Ch2 Dispatch ETH FIFO parity error" }, 5207 { F_DISPGREFIFO2, "Ch2 Dispatch GRE FIFO parity error" }, 5208 { F_DISPCPL5FIFO2, "Ch2 Dispatch CPL5 FIFO parity error" }, 5209 { F_DISPIPSECFIFO1, "Ch1 Dispatch IPSec FIFO parity error" }, 5210 { F_DISPTCPFIFO1, "Ch1 Dispatch TCP FIFO parity error" }, 5211 { F_DISPIPFIFO1, "Ch1 Dispatch IP FIFO parity error" }, 5212 { F_DISPETHFIFO1, "Ch1 Dispatch ETH FIFO parity error" }, 5213 { F_DISPGREFIFO1, "Ch1 Dispatch GRE FIFO parity error" }, 5214 { F_DISPCPL5FIFO1, "Ch1 Dispatch CPL5 FIFO parity error" }, 5215 { F_DISPIPSECFIFO0, "Ch0 Dispatch IPSec FIFO parity error" }, 5216 { F_DISPTCPFIFO0, "Ch0 Dispatch TCP FIFO parity error" }, 5217 { F_DISPIPFIFO0, "Ch0 Dispatch IP FIFO parity error" }, 5218 { F_DISPETHFIFO0, "Ch0 Dispatch ETH FIFO parity error" }, 5219 { F_DISPGREFIFO0, "Ch0 Dispatch GRE FIFO parity error" }, 5220 { F_DISPCPL5FIFO0, "Ch0 Dispatch CPL5 FIFO parity error" }, 5221 { 0 } 5222 }; 5223 static const struct intr_info tp_e_eg_perr_cause = { 5224 .name = "TP_E_EG_PERR_CAUSE", 5225 .cause_reg = A_TP_E_EG_PERR_CAUSE, 5226 .enable_reg = A_TP_E_EG_PERR_ENABLE, 5227 .fatal = 0xffffffff, 5228 .flags = IHF_FATAL_IFF_ENABLED, 5229 .details = tp_e_eg_perr_details, 5230 .actions = NULL, 5231 }; 5232 static const struct intr_details tp_e_in0_perr_details[] = { 5233 { F_DMXISSFIFO, "Demux ISS FIFO parity error" }, 5234 { F_DMXERRFIFO, "Demux Error FIFO parity error" }, 5235 { F_DMXATTFIFO, "Demux Attributes FIFO parity error" }, 5236 { F_DMXTCPFIFO, "Demux TCP Fields FIFO parity error" }, 5237 { F_DMXMPAFIFO, "Demux MPA FIFO parity error" }, 5238 { F_DMXOPTFIFO, "Demux TCP Options FIFO parity error" }, 5239 { F_INGTOKENFIFO, "Demux Ingress Token FIFO parity error" }, 5240 { F_DMXPLDCHKOVFL1, "Ch1 PLD TxCheck FIFO Overflow" }, 5241 { F_DMXPLDCHKFIFO1, "Ch1 PLD TxCheck FIFO parity error" }, 5242 { F_DMXOPTFIFO1, "Ch1 Options buffer parity error" }, 5243 { F_DMXMPAFIFO1, "Ch1 MPA FIFO parity error" }, 5244 { F_DMXDBFIFO1, "Ch1 DB FIFO parity error" }, 5245 { F_DMXATTFIFO1, "Ch1 Attribute FIFO parity error" }, 5246 { F_DMXISSFIFO1, "Ch1 ISS FIFO parity error" }, 5247 { F_DMXTCPFIFO1, "Ch1 TCP Fields FIFO parity error" }, 5248 { F_DMXERRFIFO1, "Ch1 Error FIFO parity error" }, 5249 { F_MPS2TPINTF1, "Ch1 MPS2TP Interface parity error" }, 5250 { F_DMXPLDCHKOVFL0, "Ch0 PLD TxCheck FIFO Overflow" }, 5251 { F_DMXPLDCHKFIFO0, "Ch0 PLD TxCheck FIFO parity error" }, 5252 { F_DMXOPTFIFO0, "Ch0 Options buffer parity error" }, 5253 { F_DMXMPAFIFO0, "Ch0 MPA FIFO parity error" }, 5254 { F_DMXDBFIFO0, "Ch0 DB FIFO parity error" }, 5255 { F_DMXATTFIFO0, "Ch0 Attribute FIFO parity error" }, 5256 { F_DMXISSFIFO0, "Ch0 ISS FIFO parity error" }, 5257 { F_DMXTCPFIFO0, "Ch0 TCP Fields FIFO parity error" }, 5258 { F_DMXERRFIFO0, "Ch0 Error FIFO parity error" }, 5259 { F_MPS2TPINTF0, "Ch0 MPS2TP Interface parity error" }, 5260 { 0 } 5261 }; 5262 static const struct intr_info tp_e_in0_perr_cause = { 5263 .name = "TP_E_IN0_PERR_CAUSE", 5264 .cause_reg = A_TP_E_IN0_PERR_CAUSE, 5265 .enable_reg = A_TP_E_IN0_PERR_ENABLE, 5266 .fatal = 0xffffffff, 5267 .flags = IHF_FATAL_IFF_ENABLED, 5268 .details = tp_e_in0_perr_details, 5269 .actions = NULL, 5270 }; 5271 static const struct intr_details tp_e_in1_perr_details[] = { 5272 { F_DMXPLDCHKOVFL3, "Ch3 PLD TxCheck FIFO Overflow" }, 5273 { F_DMXPLDCHKFIFO3, "Ch3 PLD TxCheck FIFO parity error" }, 5274 { F_DMXOPTFIFO3, "Ch3 Options buffer parity error" }, 5275 { F_DMXMPAFIFO3, "Ch3 MPA FIFO parity error" }, 5276 { F_DMXDBFIFO3, "Ch3 DB FIFO parity error" }, 5277 { F_DMXATTFIFO3, "Ch3 Attribute FIFO parity error" }, 5278 { F_DMXISSFIFO3, "Ch3 ISS FIFO parity error" }, 5279 { F_DMXTCPFIFO3, "Ch3 TCP Fields FIFO parity error" }, 5280 { F_DMXERRFIFO3, "Ch3 Error FIFO parity error" }, 5281 { F_MPS2TPINTF3, "Ch3 MPS2TP Interface parity error" }, 5282 { F_DMXPLDCHKOVFL2, "Ch2 PLD TxCheck FIFO Overflow" }, 5283 { F_DMXPLDCHKFIFO2, "Ch2 PLD TxCheck FIFO parity error" }, 5284 { F_DMXOPTFIFO2, "Ch2 Options buffer parity error" }, 5285 { F_DMXMPAFIFO2, "Ch2 MPA FIFO parity error" }, 5286 { F_DMXDBFIFO2, "Ch2 DB FIFO parity error" }, 5287 { F_DMXATTFIFO2, "Ch2 Attribute FIFO parity error" }, 5288 { F_DMXISSFIFO2, "Ch2 ISS FIFO parity error" }, 5289 { F_DMXTCPFIFO2, "Ch2 TCP Fields FIFO parity error" }, 5290 { F_DMXERRFIFO2, "Ch2 Error FIFO parity error" }, 5291 { F_MPS2TPINTF2, "Ch2 MPS2TP Interface parity error" }, 5292 { 0 } 5293 }; 5294 static const struct intr_info tp_e_in1_perr_cause = { 5295 .name = "TP_E_IN1_PERR_CAUSE", 5296 .cause_reg = A_TP_E_IN1_PERR_CAUSE, 5297 .enable_reg = A_TP_E_IN1_PERR_ENABLE, 5298 .fatal = 0xffffffff, 5299 .flags = IHF_FATAL_IFF_ENABLED, 5300 .details = tp_e_in1_perr_details, 5301 .actions = NULL, 5302 }; 5303 static const struct intr_details tp_other_perr_details[] = { 5304 { F_DMARBTPERR, "DMARBT MA Rsp Interface parity Error" }, 5305 { F_MMGRCACHEDATASRAM, "TP MMGR Cache Data SRAM" }, 5306 { F_MMGRCACHETAGFIFO, "TP MMGR Cache Tag FIFO" }, 5307 { F_DBL2TLUTPERR, "TP DB Lookup Table" }, 5308 { F_DBTXTIDPERR, "TP DB FIFOs" }, 5309 { F_DBEXTPERR, "TP DB Extended Opcode FIFO" }, 5310 { F_DBOPPERR, "TP DB Opcode FIFO" }, 5311 { F_TMCACHEPERR, "TP TM Cache SRAM" }, 5312 { F_TPPROTOSRAM, "TP Protocol SRAM" }, 5313 { F_HSPSRAM, "HighSpeed SRAM" }, 5314 { F_RATEGRPSRAM, "Rate Group SRAM" }, 5315 { F_TXFBSEQFIFO, "Tx Feedback Sequence Number FIFO" }, 5316 { F_CMDATASRAM, "Cache Data SRAM" }, 5317 { F_CMTAGFIFO, "Cache Tag FIFO" }, 5318 { F_RFCOPFIFO, "RCF Opcode FIFO" }, 5319 { F_DELINVFIFO, "Delete Invalid FIFO" }, 5320 { F_RSSCFGSRAM, "RSS Config or Round-Robin SRAM" }, 5321 { F_RSSKEYSRAM, "RSS Key SRAM" }, 5322 { F_RSSLKPSRAM, "RSS Lookup SRAM" }, 5323 { F_SRQSRAM, "SRQ SRAM" }, 5324 { F_ARPDASRAM, "ARP DA SRAM" }, 5325 { F_ARPSASRAM, "ARP SA SRAM" }, 5326 { F_ARPGRESRAM, "ARP GRE SRAM" }, 5327 { F_ARPIPSECSRAM1, "ARP IPSec SRAM0" }, 5328 { F_ARPIPSECSRAM0, "ARP IPSec SRAM1" }, 5329 { 0 } 5330 }; 5331 static const struct intr_info tp_o_perr_cause = { 5332 .name = "TP_O_PERR_CAUSE", 5333 .cause_reg = A_TP_O_PERR_CAUSE, 5334 .enable_reg = A_TP_O_PERR_ENABLE, 5335 .fatal = 0xffffffff, 5336 .flags = IHF_FATAL_IFF_ENABLED, 5337 .details = tp_other_perr_details, 5338 .actions = NULL, 5339 }; 5340 bool fatal; 5341 5342 if (chip_id(adap) > CHELSIO_T6) { 5343 tp_intr_info.details = t7_tp_intr_details; 5344 fatal = t4_handle_intr(adap, &tp_intr_info, 0, flags); 5345 fatal |= t4_handle_intr(adap, &tp_cerr_cause, 0, flags); 5346 fatal |= t4_handle_intr(adap, &tp_c_perr_cause, 0, flags); 5347 fatal |= t4_handle_intr(adap, &tp_e_eg_perr_cause, 0, flags); 5348 fatal |= t4_handle_intr(adap, &tp_e_in0_perr_cause, 0, flags); 5349 fatal |= t4_handle_intr(adap, &tp_e_in1_perr_cause, 0, flags); 5350 fatal |= t4_handle_intr(adap, &tp_o_perr_cause, 0, flags); 5351 } else { 5352 tp_intr_info.details = tp_intr_details; 5353 fatal = t4_handle_intr(adap, &tp_intr_info, 0, flags); 5354 } 5355 clear_int_cause_reg(adap, &tp_intr_info, flags); 5356 5357 return (fatal); 5358 } 5359 5360 /* 5361 * SGE interrupt handler. 5362 */ 5363 static bool sge_intr_handler(struct adapter *adap, int arg, int flags) 5364 { 5365 static const struct intr_details sge_int1_details[] = { 5366 { F_PERR_FLM_CREDITFIFO, "SGE FLM credit FIFO parity error" }, 5367 { F_PERR_IMSG_HINT_FIFO, "SGE IMSG hint FIFO parity error" }, 5368 { F_PERR_HEADERSPLIT_FIFO3 | F_PERR_HEADERSPLIT_FIFO2, 5369 "SGE header split FIFO parity error" }, 5370 { F_PERR_PAYLOAD_FIFO3 | F_PERR_PAYLOAD_FIFO2, 5371 "SGE payload FIFO parity error" }, 5372 { F_PERR_PC_RSP, "SGE PC response parity error" }, 5373 { F_PERR_PC_REQ, "SGE PC request parity error" }, 5374 { 0x003c0000, "SGE DBP PC response FIFO parity error" }, 5375 { F_PERR_DMARBT, "SGE DMA RBT parity error" }, 5376 { F_PERR_FLM_DBPFIFO, "SGE FLM DBP FIFO parity error" }, 5377 { F_PERR_FLM_MCREQ_FIFO, "SGE FLM MC request FIFO parity error" }, 5378 { F_PERR_FLM_HINTFIFO, "SGE FLM hint FIFO parity error" }, 5379 { 0x00003c00, "SGE align control FIFO parity error" }, 5380 { 0x000003c0, "SGE EDMA FIFO parity error" }, 5381 { 0x0000003c, "SGE PD FIFO parity error" }, 5382 { F_PERR_ING_CTXT_MIFRSP, "SGE Ingress context MIF response parity error" }, 5383 { F_PERR_EGR_CTXT_MIFRSP, "SGE Egress context MIF response parity error" }, 5384 { 0 } 5385 }; 5386 static const struct intr_info sge_int1_info = { 5387 .name = "SGE_INT_CAUSE1", 5388 .cause_reg = A_SGE_INT_CAUSE1, 5389 .enable_reg = A_SGE_INT_ENABLE1, 5390 .fatal = 0xffffffff, 5391 .flags = IHF_FATAL_IFF_ENABLED, 5392 .details = sge_int1_details, 5393 .actions = NULL, 5394 }; 5395 static const struct intr_details t7_sge_int2_details[] = { 5396 { F_TF_FIFO_PERR, "SGE TF FIFO parity error" }, 5397 { F_PERR_EGR_DBP_TX_COAL, "SGE egress DBP TX coal parity error" }, 5398 { F_PERR_DBP_FL_FIFO, "SGE DBP FL FIFO parity error" }, 5399 { F_DEQ_LL_PERR, "SGE linked list SRAM parity error" }, 5400 { F_ENQ_PERR, "SGE enq tag SRAM parity error" }, 5401 { F_DEQ_OUT_PERR, "SGE tbuf deq output FIFO parity error" }, 5402 { F_BUF_PERR, "SGE tbuf main buffer parity error" }, 5403 { F_PERR_CONM_SRAM, "SGE CONM SRAM parity error" }, 5404 { F_PERR_ISW_IDMA3_FIFO | F_PERR_ISW_IDMA2_FIFO | 5405 F_PERR_ISW_IDMA1_FIFO | F_PERR_ISW_IDMA0_FIFO, 5406 "SGE ISW IDMA FIFO parity error" }, 5407 { F_PERR_ISW_DBP_FIFO, "SGE ISW DBP FIFO parity error" }, 5408 { F_PERR_ISW_GTS_FIFO, "SGE ISW GTS FIFO parity error" }, 5409 { F_PERR_ITP_EVR, "SGE ITP EVR parity error" }, 5410 { F_PERR_FLM_CNTXMEM, "SGE FLM context memory parity error" }, 5411 { F_PERR_FLM_L1CACHE, "SGE FLM L1 cache parity error" }, 5412 { F_SGE_IPP_FIFO_PERR, "SGE IPP FIFO parity error" }, 5413 { F_PERR_DBP_HP_FIFO, "SGE DBP HP FIFO parity error" }, 5414 { F_PERR_DB_FIFO, "SGE doorbell FIFO parity error" }, 5415 { F_PERR_ING_CTXT_CACHE | F_PERR_EGR_CTXT_CACHE, 5416 "SGE context cache parity error" }, 5417 { F_PERR_BASE_SIZE, "SGE base size parity error" }, 5418 { 0 } 5419 }; 5420 static const struct intr_details t6_sge_int2_details[] = { 5421 { F_PERR_DBP_HINT_FL_FIFO, "SGE DBP hint FL FIFO parity error" }, 5422 { F_PERR_EGR_DBP_TX_COAL, "SGE egress DBP TX coal parity error" }, 5423 { F_PERR_DBP_FL_FIFO, "SGE DBP FL FIFO parity error" }, 5424 { F_DEQ_LL_PERR, "SGE tbuf dequeue linked list SRAM parity error" }, 5425 { F_ENQ_PERR, "SGE tbuf enqueue tag SRAM parity error" }, 5426 { F_DEQ_OUT_PERR, "SGE tbuf dequeue output FIFO parity error" }, 5427 { F_BUF_PERR, "SGE tbuf main buffer parity error" }, 5428 { F_PERR_CONM_SRAM, "SGE CONM SRAM parity error" }, 5429 { F_PERR_ISW_IDMA1_FIFO, "SGE ISW IDMA FIFO parity error" }, 5430 { F_PERR_ISW_IDMA0_FIFO, "SGE ISW IDMA FIFO parity error" }, 5431 { F_PERR_ISW_DBP_FIFO, "SGE ISW DBP FIFO parity error" }, 5432 { F_PERR_ISW_GTS_FIFO, "SGE ISW GTS FIFO parity error" }, 5433 { F_PERR_ITP_EVR, "SGE ITP EVR parity error" }, 5434 { F_PERR_FLM_CNTXMEM, "SGE FLM context memory parity error" }, 5435 { F_PERR_FLM_L1CACHE, "SGE FLM L1 cache parity error" }, 5436 { F_PERR_DBP_HINT_FIFO, "SGE DBP hint FIFO parity error" }, 5437 { F_PERR_DBP_HP_FIFO, "SGE DBP high priority FIFO parity error" }, 5438 { F_PERR_DB_FIFO, "SGE DBP merge DB FIFO parity error" }, 5439 { F_PERR_ING_CTXT_CACHE, "SGE ingress context cache parity error" }, 5440 { F_PERR_EGR_CTXT_CACHE, "SGE egress context cache parity error" }, 5441 { F_PERR_BASE_SIZE, "SGE base size parity error" }, 5442 { 0 } 5443 }; 5444 struct intr_info sge_int2_info = { 5445 .name = "SGE_INT_CAUSE2", 5446 .cause_reg = A_SGE_INT_CAUSE2, 5447 .enable_reg = A_SGE_INT_ENABLE2, 5448 .fatal = 0xffffffff, 5449 .flags = IHF_FATAL_IFF_ENABLED, 5450 .details = NULL, 5451 .actions = NULL, 5452 }; 5453 static const struct intr_details sge_int3_details[] = { 5454 { F_ERR_FLM_DBP, 5455 "DBP pointer delivery for invalid context or QID" }, 5456 { F_ERR_FLM_IDMA1 | F_ERR_FLM_IDMA0, 5457 "Invalid QID or header request by IDMA" }, 5458 { F_ERR_FLM_HINT, "FLM hint is for invalid context or QID" }, 5459 { F_ERR_PCIE_ERROR3, "SGE PCIe error for DBP thread 3" }, 5460 { F_ERR_PCIE_ERROR2, "SGE PCIe error for DBP thread 2" }, 5461 { F_ERR_PCIE_ERROR1, "SGE PCIe error for DBP thread 1" }, 5462 { F_ERR_PCIE_ERROR0, "SGE PCIe error for DBP thread 0" }, 5463 { F_ERR_TIMER_ABOVE_MAX_QID, 5464 "SGE GTS with timer 0-5 for IQID > 1023" }, 5465 { F_ERR_CPL_EXCEED_IQE_SIZE, 5466 "SGE received CPL exceeding IQE size" }, 5467 { F_ERR_INVALID_CIDX_INC, "SGE GTS CIDX increment too large" }, 5468 { F_ERR_ITP_TIME_PAUSED, "SGE ITP error" }, 5469 { F_ERR_CPL_OPCODE_0, "SGE received 0-length CPL" }, 5470 { F_ERR_DROPPED_DB, "SGE DB dropped" }, 5471 { F_ERR_DATA_CPL_ON_HIGH_QID1 | F_ERR_DATA_CPL_ON_HIGH_QID0, 5472 "SGE IQID > 1023 received CPL for FL" }, 5473 { F_ERR_BAD_DB_PIDX3 | F_ERR_BAD_DB_PIDX2 | F_ERR_BAD_DB_PIDX1 | 5474 F_ERR_BAD_DB_PIDX0, "SGE DBP pidx increment too large" }, 5475 { F_ERR_ING_PCIE_CHAN, "SGE Ingress PCIe channel mismatch" }, 5476 { F_ERR_ING_CTXT_PRIO, 5477 "Ingress context manager priority user error" }, 5478 { F_ERR_EGR_CTXT_PRIO, 5479 "Egress context manager priority user error" }, 5480 { F_DBFIFO_HP_INT, "High priority DB FIFO threshold reached" }, 5481 { F_DBFIFO_LP_INT, "Low priority DB FIFO threshold reached" }, 5482 { F_REG_ADDRESS_ERR, "Undefined SGE register accessed" }, 5483 { F_INGRESS_SIZE_ERR, "SGE illegal ingress QID" }, 5484 { F_EGRESS_SIZE_ERR, "SGE illegal egress QID" }, 5485 { 0x0000000f, "SGE context access for invalid queue" }, 5486 { 0 } 5487 }; 5488 static const struct intr_details t6_sge_int3_details[] = { 5489 { F_ERR_FLM_DBP, 5490 "DBP pointer delivery for invalid context or QID" }, 5491 { F_ERR_FLM_IDMA1 | F_ERR_FLM_IDMA0, 5492 "Invalid QID or header request by IDMA" }, 5493 { F_ERR_FLM_HINT, "FLM hint is for invalid context or QID" }, 5494 { F_ERR_PCIE_ERROR3, "SGE PCIe error for DBP thread 3" }, 5495 { F_ERR_PCIE_ERROR2, "SGE PCIe error for DBP thread 2" }, 5496 { F_ERR_PCIE_ERROR1, "SGE PCIe error for DBP thread 1" }, 5497 { F_ERR_PCIE_ERROR0, "SGE PCIe error for DBP thread 0" }, 5498 { F_ERR_TIMER_ABOVE_MAX_QID, 5499 "SGE GTS with timer 0-5 for IQID > 1023" }, 5500 { F_ERR_CPL_EXCEED_IQE_SIZE, 5501 "SGE received CPL exceeding IQE size" }, 5502 { F_ERR_INVALID_CIDX_INC, "SGE GTS CIDX increment too large" }, 5503 { F_ERR_ITP_TIME_PAUSED, "SGE ITP error" }, 5504 { F_ERR_CPL_OPCODE_0, "SGE received 0-length CPL" }, 5505 { F_ERR_DROPPED_DB, "SGE DB dropped" }, 5506 { F_ERR_DATA_CPL_ON_HIGH_QID1 | F_ERR_DATA_CPL_ON_HIGH_QID0, 5507 "SGE IQID > 1023 received CPL for FL" }, 5508 { F_ERR_BAD_DB_PIDX3 | F_ERR_BAD_DB_PIDX2 | F_ERR_BAD_DB_PIDX1 | 5509 F_ERR_BAD_DB_PIDX0, "SGE DBP pidx increment too large" }, 5510 { F_ERR_ING_PCIE_CHAN, "SGE Ingress PCIe channel mismatch" }, 5511 { F_ERR_ING_CTXT_PRIO, 5512 "Ingress context manager priority user error" }, 5513 { F_ERR_EGR_CTXT_PRIO, 5514 "Egress context manager priority user error" }, 5515 { F_DBP_TBUF_FULL, "SGE DBP tbuf full" }, 5516 { F_FATAL_WRE_LEN, 5517 "SGE WRE packet less than advertized length" }, 5518 { F_REG_ADDRESS_ERR, "Undefined SGE register accessed" }, 5519 { F_INGRESS_SIZE_ERR, "SGE illegal ingress QID" }, 5520 { F_EGRESS_SIZE_ERR, "SGE illegal egress QID" }, 5521 { 0x0000000f, "SGE context access for invalid queue" }, 5522 { 0 } 5523 }; 5524 struct intr_info sge_int3_info = { 5525 .name = "SGE_INT_CAUSE3", 5526 .cause_reg = A_SGE_INT_CAUSE3, 5527 .enable_reg = A_SGE_INT_ENABLE3, 5528 .fatal = F_ERR_CPL_EXCEED_IQE_SIZE, 5529 .flags = 0, 5530 .details = NULL, 5531 .actions = NULL, 5532 }; 5533 static const struct intr_details sge_int4_details[] = { 5534 { F_ERR_ISHIFT_UR1 | F_ERR_ISHIFT_UR0, "SGE ishift underrun" }, 5535 { F_BAR2_EGRESS_LEN_OR_ADDR_ERR, "SGE BAR2 PL access length or alignment error" }, 5536 { F_ERR_CPL_EXCEED_MAX_IQE_SIZE1 | F_ERR_CPL_EXCEED_MAX_IQE_SIZE0, 5537 "SGE CPL exceeds max IQE size" }, 5538 { F_ERR_WR_LEN_TOO_LARGE3 | F_ERR_WR_LEN_TOO_LARGE2 | 5539 F_ERR_WR_LEN_TOO_LARGE1 | F_ERR_WR_LEN_TOO_LARGE0, 5540 "SGE WR length too large" }, 5541 { F_ERR_LARGE_MINFETCH_WITH_TXCOAL3 | F_ERR_LARGE_MINFETCH_WITH_TXCOAL2 | 5542 F_ERR_LARGE_MINFETCH_WITH_TXCOAL1 | F_ERR_LARGE_MINFETCH_WITH_TXCOAL0, 5543 "SGE invalid MinFetchBurst with TxCoalesce" }, 5544 { F_COAL_WITH_HP_DISABLE_ERR, "SGE coalesce with HP disable error" }, 5545 { F_BAR2_EGRESS_COAL0_ERR, "SGE BAR2 PL access addr offset 0" }, 5546 { F_BAR2_EGRESS_SIZE_ERR, "SGE BAR2 illegal egress QID access" }, 5547 { F_FLM_PC_RSP_ERR, "SGE FLM PC response error" }, 5548 { F_ERR_TH3_MAX_FETCH | F_ERR_TH2_MAX_FETCH | 5549 F_ERR_TH1_MAX_FETCH | F_ERR_TH0_MAX_FETCH, 5550 "SGE max fetch violation" }, 5551 { F_ERR_RX_CPL_PACKET_SIZE1 | F_ERR_RX_CPL_PACKET_SIZE0, 5552 "SGE CPL length mismatch error" }, 5553 { F_ERR_BAD_UPFL_INC_CREDIT3 | F_ERR_BAD_UPFL_INC_CREDIT2 | 5554 F_ERR_BAD_UPFL_INC_CREDIT1 | F_ERR_BAD_UPFL_INC_CREDIT0, 5555 "SGE upfl credit wrap error" }, 5556 { F_ERR_PHYSADDR_LEN0_IDMA1 | F_ERR_PHYSADDR_LEN0_IDMA0, 5557 "SGE CPL_RX_PHYS_ADDR length 0 error" }, 5558 { F_ERR_FLM_INVALID_PKT_DROP1 | F_ERR_FLM_INVALID_PKT_DROP0, 5559 "SGE IDMA packet drop due to invalid FLM context" }, 5560 { F_ERR_UNEXPECTED_TIMER, "SGE unexpected timer error" }, 5561 { 0 } 5562 }; 5563 static const struct intr_info sge_int4_info = { 5564 .name = "SGE_INT_CAUSE4", 5565 .cause_reg = A_SGE_INT_CAUSE4, 5566 .enable_reg = A_SGE_INT_ENABLE4, 5567 .fatal = 0, 5568 .flags = 0, 5569 .details = sge_int4_details, 5570 .actions = NULL, 5571 }; 5572 static const struct intr_details t7_sge_int5_details[] = { 5573 { F_ERR_T_RXCRC, "SGE RxCRC error" }, 5574 { F_PERR_MC_RSPDATA, "SGE MC response data parity error" }, 5575 { F_PERR_PC_RSPDATA, "SGE PC response data parity error" }, 5576 { F_PERR_PD_RDRSPDATA, "SGE PD read response data parity error" }, 5577 { F_PERR_U_RXDATA, "SGE U Rx data parity error" }, 5578 { F_PERR_UD_RXDATA, "SGE UD Rx data parity error" }, 5579 { F_PERR_UP_DATA, "SGE uP data parity error" }, 5580 { F_PERR_CIM2SGE_RXDATA, "SGE CIM2SGE Rx data parity error" }, 5581 { F_PERR_IMSG_PD_FIFO, "SGE IMSG PD FIFO parity error" }, 5582 { F_PERR_ULPTX_FIFO1 | F_PERR_ULPTX_FIFO0, "SGE ULPTX FIFO parity error" }, 5583 { F_PERR_IDMA2IMSG_FIFO3 | F_PERR_IDMA2IMSG_FIFO2 | 5584 F_PERR_IDMA2IMSG_FIFO1 | F_PERR_IDMA2IMSG_FIFO0, 5585 "SGE IDMA2IMSG FIFO parity error" }, 5586 { F_PERR_POINTER_DATA_FIFO3 | F_PERR_POINTER_DATA_FIFO2 | 5587 F_PERR_POINTER_DATA_FIFO1 | F_PERR_POINTER_DATA_FIFO0, 5588 "SGE pointer data FIFO parity error" }, 5589 { F_PERR_POINTER_HDR_FIFO3 | F_PERR_POINTER_HDR_FIFO2 | 5590 F_PERR_POINTER_HDR_FIFO1 | F_PERR_POINTER_HDR_FIFO0, 5591 "SGE pointer header FIFO parity error" }, 5592 { F_PERR_PAYLOAD_FIFO1 | F_PERR_PAYLOAD_FIFO0, 5593 "SGE payload FIFO parity error" }, 5594 { F_PERR_MGT_BAR2_FIFO, "SGE MGT BAR2 FIFO parity error" }, 5595 { F_PERR_HEADERSPLIT_FIFO1 | F_PERR_HEADERSPLIT_FIFO0, 5596 "SGE header split FIFO parity error" }, 5597 { F_PERR_HINT_DELAY_FIFO, "SGE hint delay FIFO parity error" }, 5598 { 0 } 5599 }; 5600 static const struct intr_details t6_sge_int5_details[] = { 5601 { F_ERR_T_RXCRC, "SGE T RxCRC parity error" }, 5602 { F_PERR_MC_RSPDATA, "SGE MC response data parity error" }, 5603 { F_PERR_PC_RSPDATA, "SGE PC response data parity error" }, 5604 { F_PERR_U_RXDATA | F_PERR_UD_RXDATA, "SGE ULP Rx data parity error" }, 5605 { F_PERR_UP_DATA, "SGE uP data parity error" }, 5606 { F_PERR_CIM2SGE_RXDATA, "SGE CIM2SGE Rx data parity error" }, 5607 { F_PERR_HINT_DELAY_FIFO1 | F_PERR_HINT_DELAY_FIFO0, 5608 "SGE hint delay FIFO parity error" }, 5609 { F_PERR_IMSG_PD_FIFO, "SGE IMSG PD FIFO parity error" }, 5610 { F_PERR_ULPTX_FIFO1 | F_PERR_ULPTX_FIFO0, 5611 "SGE ULPTX FIFO parity error" }, 5612 { F_PERR_IDMA2IMSG_FIFO1 | F_PERR_IDMA2IMSG_FIFO0, 5613 "SGE IDMA2IMSG FIFO parity error" }, 5614 { F_PERR_POINTER_DATA_FIFO1 | F_PERR_POINTER_DATA_FIFO0, 5615 "SGE pointer data FIFO parity error" }, 5616 { F_PERR_POINTER_HDR_FIFO1 | F_PERR_POINTER_HDR_FIFO0, 5617 "SGE pointer header FIFO parity error" }, 5618 { F_PERR_PAYLOAD_FIFO1 | F_PERR_PAYLOAD_FIFO0, 5619 "SGE payload FIFO parity error" }, 5620 { F_PERR_EDMA_INPUT_FIFO3 | F_PERR_EDMA_INPUT_FIFO2 | 5621 F_PERR_EDMA_INPUT_FIFO1 | F_PERR_EDMA_INPUT_FIFO0, 5622 "SGE EDMA input FIFO parity error" }, 5623 { F_PERR_MGT_BAR2_FIFO, "SGE MGT BAR2 FIFO parity error" }, 5624 { F_PERR_HEADERSPLIT_FIFO1 | F_PERR_HEADERSPLIT_FIFO0, 5625 "SGE header split FIFO parity error" }, 5626 { F_PERR_CIM_FIFO1 | F_PERR_CIM_FIFO0, "SGE CIM FIFO parity error" }, 5627 { F_PERR_IDMA_SWITCH_OUTPUT_FIFO1 | F_PERR_IDMA_SWITCH_OUTPUT_FIFO0, 5628 "SGE IDMA switch output FIFO parity error" }, 5629 { 0 } 5630 }; 5631 struct intr_info sge_int5_info = { 5632 .name = "SGE_INT_CAUSE5", 5633 .cause_reg = A_SGE_INT_CAUSE5, 5634 .enable_reg = A_SGE_INT_ENABLE5, 5635 .fatal = 0xffffffff, 5636 .flags = IHF_FATAL_IFF_ENABLED, 5637 .details = NULL, 5638 .actions = NULL, 5639 }; 5640 static const struct intr_details sge_int6_details[] = { 5641 /* T7+ */ 5642 { 0xe0000000, "SGE fatal DEQ0 DRDY error" }, 5643 { 0x1c000000, "SGE fatal OUT0 DRDY error" }, 5644 { F_IMSG_DBG3_STUCK | F_IMSG_DBG2_STUCK | 5645 F_IMSG_DBG1_STUCK | F_IMSG_DBG0_STUCK, 5646 "SGE IMSG stuck due to insufficient credits" }, 5647 /* T6 + */ 5648 { F_ERR_DB_SYNC, "SGE doorbell sync failed" }, 5649 { F_ERR_GTS_SYNC, "SGE GTS sync failed" }, 5650 { F_FATAL_LARGE_COAL, "SGE BAR2 payload too large" }, 5651 { F_PL_BAR2_FRM_ERR, "SGE BAR2 framing error" }, 5652 { F_SILENT_DROP_TX_COAL, "SGE silent drop of Tx coal WR" }, 5653 { F_ERR_INV_CTXT4, "SGE context access for invalid queue thread 4" }, 5654 { F_ERR_BAD_DB_PIDX4, "SGE doorbell pidx too large thread 4" }, 5655 { F_ERR_BAD_UPFL_INC_CREDIT4, "SGE upfl credit wrap thread 4" }, 5656 { F_FATAL_TAG_MISMATCH, "SGE doorbell tag mismatch" }, 5657 { F_FATAL_ENQ_CTL_RDY, "SGE enq_ctl_fifo overflow" }, 5658 { F_ERR_PC_RSP_LEN3 | F_ERR_PC_RSP_LEN2 | 5659 F_ERR_PC_RSP_LEN1 | F_ERR_PC_RSP_LEN0, 5660 "SGE PCIe response error for DBP threads" }, 5661 { F_FATAL_ENQ2LL_VLD, "SGE tbuf fatal_enq2ll_vld" }, 5662 { F_FATAL_LL_EMPTY, "SGE tbuf fatal_ll_empty" }, 5663 { F_FATAL_OFF_WDENQ, "SGE tbuf fatal_off_wdenq" }, 5664 { 0x00000018, "SGE tbuf fatal_deq1_drdy" }, 5665 { 0x00000006, "SGE tbuf fatal_out1_drdy" }, 5666 { F_FATAL_DEQ, "SGE tbuf fatal_deq" }, 5667 { 0 } 5668 }; 5669 static const struct intr_info sge_int6_info = { 5670 .name = "SGE_INT_CAUSE6", 5671 .cause_reg = A_SGE_INT_CAUSE6, 5672 .enable_reg = A_SGE_INT_ENABLE6, 5673 .fatal = 0, 5674 .flags = 0, 5675 .details = sge_int6_details, 5676 .actions = NULL, 5677 }; 5678 static const struct intr_details sge_int7_details[] = { 5679 { F_HINT_FIFO_FULL, "SGE hint FIFO full" }, 5680 { F_CERR_HINT_DELAY_FIFO, "SGE hint delay FIFO ECC error" }, 5681 { F_COAL_TIMER_FIFO_PERR, "SGE coalescing timer FIFO parity error" }, 5682 { F_CMP_FIFO_PERR, "SGE CMP FIFO parity error" }, 5683 { F_SGE_IPP_FIFO_CERR, "SGE IPP FIFO ECC error" }, 5684 { F_CERR_ING_CTXT_CACHE | F_CERR_EGR_CTXT_CACHE, 5685 "SGE context cache ECC error" }, 5686 { F_IMSG_CNTX_PERR, "SGE IMSG context parity error" }, 5687 { F_PD_FIFO_PERR, "SGE PD FIFO parity error" }, 5688 { F_IMSG_512_FIFO_PERR, "SGE IMSG 512 FIFO parity error" }, 5689 { F_CPLSW_FIFO_PERR, "SGE CPLSW FIFO parity error" }, 5690 { F_IMSG_FIFO_PERR, "SGE IMSG FIFO parity error" }, 5691 { F_CERR_ITP_EVR, "SGE ITP EVR ECC error" }, 5692 { F_CERR_CONM_SRAM, "SGE CONM SRAM ECC error" }, 5693 { F_CERR_FLM_CNTXMEM, "SGE FLM context memory ECC error" }, 5694 { F_CERR_FUNC_QBASE, "SGE function queue base ECC error" }, 5695 { F_IMSG_CNTX_CERR, "SGE IMSG context ECC error" }, 5696 { F_PD_FIFO_CERR, "SGE PD FIFO ECC error" }, 5697 { F_IMSG_512_FIFO_CERR, "SGE IMSG 512 FIFO ECC error" }, 5698 { F_CPLSW_FIFO_CERR, "SGE CPLSW FIFO ECC error" }, 5699 { F_IMSG_FIFO_CERR, "SGE IMSG FIFO ECC error" }, 5700 { 0x0000001e, "SGE header split FIFO ECC error" }, // Bits 4:1 5701 { F_CERR_FLM_L1CACHE, "SGE FLM L1 cache ECC error" }, 5702 { 0 } 5703 }; 5704 static const struct intr_info sge_int7_info = { 5705 .name = "SGE_INT_CAUSE7", 5706 .cause_reg = A_SGE_INT_CAUSE7, 5707 .enable_reg = A_SGE_INT_ENABLE7, 5708 .fatal = 0, 5709 .flags = 0, 5710 .details = sge_int7_details, 5711 .actions = NULL, 5712 }; 5713 static const struct intr_details sge_int8_details[] = { 5714 { F_TRACE_RXPERR, "SGE trace packet parity error" }, 5715 { F_U3_RXPERR | F_U2_RXPERR | F_U1_RXPERR | F_U0_RXPERR, 5716 "SGE ULP interface parity error" }, 5717 { F_T3_RXPERR | F_T2_RXPERR | F_T1_RXPERR | F_T0_RXPERR, 5718 "SGE TP interface parity error" }, 5719 { 0 } 5720 }; 5721 static const struct intr_info sge_int8_info = { 5722 .name = "SGE_INT_CAUSE8", 5723 .cause_reg = A_SGE_INT_CAUSE8, 5724 .enable_reg = A_SGE_INT_ENABLE8, 5725 .fatal = 0, 5726 .flags = 0, 5727 .details = sge_int8_details, 5728 .actions = NULL, 5729 }; 5730 bool fatal; 5731 u32 v; 5732 5733 if (chip_id(adap) <= CHELSIO_T5) { 5734 sge_int3_info.details = sge_int3_details; 5735 } else if (chip_id(adap) == CHELSIO_T6) { 5736 sge_int3_info.details = t6_sge_int3_details; 5737 sge_int2_info.details = t6_sge_int2_details; 5738 sge_int5_info.details = t6_sge_int5_details; 5739 } else { 5740 sge_int3_info.details = t6_sge_int3_details; 5741 sge_int2_info.details = t7_sge_int2_details; 5742 sge_int5_info.details = t7_sge_int5_details; 5743 } 5744 5745 fatal = false; 5746 fatal |= t4_handle_intr(adap, &sge_int1_info, 0, flags); 5747 fatal |= t4_handle_intr(adap, &sge_int2_info, 0, flags); 5748 fatal |= t4_handle_intr(adap, &sge_int3_info, 0, flags); 5749 fatal |= t4_handle_intr(adap, &sge_int4_info, 0, flags); 5750 if (chip_id(adap) >= CHELSIO_T5) 5751 fatal |= t4_handle_intr(adap, &sge_int5_info, 0, flags); 5752 if (chip_id(adap) >= CHELSIO_T6) 5753 fatal |= t4_handle_intr(adap, &sge_int6_info, 0, flags); 5754 if (chip_id(adap) >= CHELSIO_T7) { 5755 fatal |= t4_handle_intr(adap, &sge_int7_info, 0, flags); 5756 fatal |= t4_handle_intr(adap, &sge_int8_info, 0, flags); 5757 } 5758 5759 v = t4_read_reg(adap, A_SGE_ERROR_STATS); 5760 if (v & F_ERROR_QID_VALID) { 5761 CH_ERR(adap, "SGE error for QID %u\n", G_ERROR_QID(v)); 5762 if (v & F_UNCAPTURED_ERROR) 5763 CH_ERR(adap, "SGE UNCAPTURED_ERROR set (clearing)\n"); 5764 t4_write_reg(adap, A_SGE_ERROR_STATS, 5765 F_ERROR_QID_VALID | F_UNCAPTURED_ERROR); 5766 } 5767 5768 return (fatal); 5769 } 5770 5771 /* 5772 * CIM interrupt handler. 5773 */ 5774 static bool cim_intr_handler(struct adapter *adap, int arg, int flags) 5775 { 5776 static const struct intr_details cim_host_t7_intr_details[] = { 5777 { F_CORE7ACCINT, "CIM slave core 7 access interrupt "}, 5778 { F_CORE6ACCINT, "CIM slave core 6 access interrupt "}, 5779 { F_CORE5ACCINT, "CIM slave core 5 access interrupt "}, 5780 { F_CORE4ACCINT, "CIM slave core 4 access interrupt "}, 5781 { F_CORE3ACCINT, "CIM slave core 3 access interrupt "}, 5782 { F_CORE2ACCINT, "CIM slave core 2 access interrupt "}, 5783 { F_CORE1ACCINT, "CIM slave core 1 access interrupt "}, 5784 { F_TIMER1INT, "CIM TIMER0 interrupt" }, 5785 { F_TIMER0INT, "CIM TIMER0 interrupt" }, 5786 { F_PREFDROPINT, "CIM control register prefetch drop" }, 5787 { 0} 5788 }; 5789 static const struct intr_details cim_host_intr_details[] = { 5790 /* T6+ */ 5791 { F_PCIE2CIMINTFPARERR, "CIM IBQ PCIe interface parity error" }, 5792 5793 /* T5+ */ 5794 { F_MA_CIM_INTFPERR, "MA2CIM interface parity error" }, 5795 { F_PLCIM_MSTRSPDATAPARERR, 5796 "PL2CIM master response data parity error" }, 5797 { F_NCSI2CIMINTFPARERR, "CIM IBQ NC-SI interface parity error" }, 5798 { F_SGE2CIMINTFPARERR, "CIM IBQ SGE interface parity error" }, 5799 { F_ULP2CIMINTFPARERR, "CIM IBQ ULP_TX interface parity error" }, 5800 { F_TP2CIMINTFPARERR, "CIM IBQ TP interface parity error" }, 5801 { F_OBQSGERX1PARERR, "CIM OBQ PCIE_RX parity error" }, 5802 { F_OBQSGERX0PARERR, "CIM OBQ SGE_RX parity error" }, 5803 5804 /* T4+ */ 5805 { F_TIEQOUTPARERRINT, "CIM TIEQ outgoing FIFO parity error" }, 5806 { F_TIEQINPARERRINT, "CIM TIEQ incoming FIFO parity error" }, 5807 { F_MBHOSTPARERR, "CIM mailbox host read parity error" }, 5808 { F_MBUPPARERR, "CIM mailbox uP parity error" }, 5809 { F_IBQTP0PARERR, "CIM IBQ TP0 parity error" }, 5810 { F_IBQTP1PARERR, "CIM IBQ TP1 parity error" }, 5811 { F_IBQULPPARERR, "CIM IBQ ULP parity error" }, 5812 { F_IBQSGELOPARERR, "CIM IBQ SGE_LO parity error" }, 5813 { F_IBQSGEHIPARERR | F_IBQPCIEPARERR, /* same bit */ 5814 "CIM IBQ PCIe/SGE_HI parity error" }, 5815 { F_IBQNCSIPARERR, "CIM IBQ NC-SI parity error" }, 5816 { F_OBQULP0PARERR, "CIM OBQ ULP0 parity error" }, 5817 { F_OBQULP1PARERR, "CIM OBQ ULP1 parity error" }, 5818 { F_OBQULP2PARERR, "CIM OBQ ULP2 parity error" }, 5819 { F_OBQULP3PARERR, "CIM OBQ ULP3 parity error" }, 5820 { F_OBQSGEPARERR, "CIM OBQ SGE parity error" }, 5821 { F_OBQNCSIPARERR, "CIM OBQ NC-SI parity error" }, 5822 { F_TIMER1INT, "CIM TIMER0 interrupt" }, 5823 { F_TIMER0INT, "CIM TIMER0 interrupt" }, 5824 { F_PREFDROPINT, "CIM control register prefetch drop" }, 5825 { 0} 5826 }; 5827 struct intr_info cim_host_intr_info = { 5828 .name = "CIM_HOST_INT_CAUSE", 5829 .cause_reg = A_CIM_HOST_INT_CAUSE, 5830 .enable_reg = A_CIM_HOST_INT_ENABLE, 5831 .fatal = 0x007fffe6, 5832 .flags = IHF_FATAL_IFF_ENABLED, 5833 .details = NULL, 5834 .actions = NULL, 5835 }; 5836 static const struct intr_details cim_host_upacc_intr_details[] = { 5837 { F_CONWRERRINT, "CIM condition write error "}, 5838 { F_EEPROMWRINT, "CIM EEPROM came out of busy state" }, 5839 { F_TIMEOUTMAINT, "CIM PIF MA timeout" }, 5840 { F_TIMEOUTINT, "CIM PIF timeout" }, 5841 { F_RSPOVRLOOKUPINT, "CIM response FIFO overwrite" }, 5842 { F_REQOVRLOOKUPINT, "CIM request FIFO overwrite" }, 5843 { F_BLKWRPLINT, "CIM block write to PL space" }, 5844 { F_BLKRDPLINT, "CIM block read from PL space" }, 5845 { F_SGLWRPLINT, 5846 "CIM single write to PL space with illegal BEs" }, 5847 { F_SGLRDPLINT, 5848 "CIM single read from PL space with illegal BEs" }, 5849 { F_BLKWRCTLINT, "CIM block write to CTL space" }, 5850 { F_BLKRDCTLINT, "CIM block read from CTL space" }, 5851 { F_SGLWRCTLINT, 5852 "CIM single write to CTL space with illegal BEs" }, 5853 { F_SGLRDCTLINT, 5854 "CIM single read from CTL space with illegal BEs" }, 5855 { F_BLKWREEPROMINT, "CIM block write to EEPROM space" }, 5856 { F_BLKRDEEPROMINT, "CIM block read from EEPROM space" }, 5857 { F_SGLWREEPROMINT, 5858 "CIM single write to EEPROM space with illegal BEs" }, 5859 { F_SGLRDEEPROMINT, 5860 "CIM single read from EEPROM space with illegal BEs" }, 5861 { F_BLKWRFLASHINT, "CIM block write to flash space" }, 5862 { F_BLKRDFLASHINT, "CIM block read from flash space" }, 5863 { F_SGLWRFLASHINT, "CIM single write to flash space" }, 5864 { F_SGLRDFLASHINT, 5865 "CIM single read from flash space with illegal BEs" }, 5866 { F_BLKWRBOOTINT, "CIM block write to boot space" }, 5867 { F_BLKRDBOOTINT, "CIM block read from boot space" }, 5868 { F_SGLWRBOOTINT, "CIM single write to boot space" }, 5869 { F_SGLRDBOOTINT, 5870 "CIM single read from boot space with illegal BEs" }, 5871 { F_ILLWRBEINT, "CIM illegal write BEs" }, 5872 { F_ILLRDBEINT, "CIM illegal read BEs" }, 5873 { F_ILLRDINT, "CIM illegal read" }, 5874 { F_ILLWRINT, "CIM illegal write" }, 5875 { F_ILLTRANSINT, "CIM illegal transaction" }, 5876 { F_RSVDSPACEINT, "CIM reserved space access" }, 5877 {0} 5878 }; 5879 static const struct intr_info cim_host_upacc_intr_info = { 5880 .name = "CIM_HOST_UPACC_INT_CAUSE", 5881 .cause_reg = A_CIM_HOST_UPACC_INT_CAUSE, 5882 .enable_reg = A_CIM_HOST_UPACC_INT_ENABLE, 5883 .fatal = 0x3fffeeff, 5884 .flags = IHF_FATAL_IFF_ENABLED, 5885 .details = cim_host_upacc_intr_details, 5886 .actions = NULL, 5887 }; 5888 static const struct intr_info cim_pf_host_intr_info = { 5889 .name = "CIM_PF_HOST_INT_CAUSE", 5890 .cause_reg = MYPF_REG(A_CIM_PF_HOST_INT_CAUSE), 5891 .enable_reg = MYPF_REG(A_CIM_PF_HOST_INT_ENABLE), 5892 .fatal = 0, 5893 .flags = 0, 5894 .details = NULL, 5895 .actions = NULL, 5896 }; 5897 static const struct intr_details cim_perr_cause_details[] = { 5898 { F_T7_MA_CIM_INTFPERR, "MA2CIM interface parity error" }, 5899 { F_T7_MBHOSTPARERR, "Mailbox Host Read parity error" }, 5900 { F_MAARBINVRSPTAG, "MA Arbiter Invalid Response Tag (Fatal)" }, 5901 { F_MAARBFIFOPARERR, "MA Arbiter FIFO Parity Error" }, 5902 { F_SEMSRAMPARERR, "Semaphore logic SRAM Parity Error" }, 5903 { F_RSACPARERR, "RSA Code SRAM Parity Error" }, 5904 { F_RSADPARERR, "RSA Data SRAM Parity Error" }, 5905 { F_T7_PLCIM_MSTRSPDATAPARERR, "PL2CIM Master response data parity error" }, 5906 { F_T7_PCIE2CIMINTFPARERR, "IBQ PCIE intf parity error" }, 5907 { F_T7_NCSI2CIMINTFPARERR, "IBQ NCSI intf parity error" }, 5908 { F_T7_SGE2CIMINTFPARERR, "IBQ SGE Intf Parity error" }, 5909 { F_T7_ULP2CIMINTFPARERR, "IBQ ULP_TX intf parity error" }, 5910 { F_T7_TP2CIMINTFPARERR, "IBQ TP intf parity error" }, 5911 { F_CORE7PARERR, "Slave Core7 parity error" }, 5912 { F_CORE6PARERR, "Slave Core6 parity error" }, 5913 { F_CORE5PARERR, "Slave Core5 parity error" }, 5914 { F_CORE4PARERR, "Slave Core4 parity error" }, 5915 { F_CORE3PARERR, "Slave Core3 parity error" }, 5916 { F_CORE2PARERR, "Slave Core2 parity error" }, 5917 { F_CORE1PARERR, "Slave Core1 parity error" }, 5918 { F_GFTPARERR, "GFT block Memory parity error" }, 5919 { F_MPSRSPDATAPARERR, "MPS lookup interface Response parity error" }, 5920 { F_ER_RSPDATAPARERR, "Expansion ROM/Flash Interface Response Parity Error" }, 5921 { F_FLOWFIFOPARERR, "SGE FlowID Prefetch FIFO Parity Error" }, 5922 { F_OBQSRAMPARERR, "OBQ SRAM Parity Error" }, 5923 { F_TIEQOUTPARERR, "TIE Queue Outgoing FIFO parity error" }, 5924 { F_TIEQINPARERR, "TIE Queue Incoming FIFO parity error" }, 5925 { F_PIFRSPPARERR, "PIF Response interface FIFO Parity error" }, 5926 { F_PIFREQPARERR, "PIF Request interface FIFO Parity error" }, 5927 { 0 } 5928 }; 5929 static const struct intr_info cim_perr_cause = { 5930 .name = "CIM_PERR_CAUSE", 5931 .cause_reg = A_CIM_PERR_CAUSE, 5932 .enable_reg = A_CIM_PERR_ENABLE, 5933 .fatal = 0xffffffff, 5934 .flags = IHF_FATAL_IFF_ENABLED, 5935 .details = cim_perr_cause_details, 5936 .actions = NULL, 5937 }; 5938 u32 val, fw_err; 5939 bool fatal; 5940 5941 if (chip_id(adap) >= CHELSIO_T7) 5942 cim_host_intr_info.details = cim_host_t7_intr_details; 5943 else 5944 cim_host_intr_info.details = cim_host_intr_details; 5945 /* 5946 * When the Firmware detects an internal error which normally wouldn't 5947 * raise a Host Interrupt, it forces a CIM Timer0 interrupt in order 5948 * to make sure the Host sees the Firmware Crash. So if we have a 5949 * Timer0 interrupt and don't see a Firmware Crash, ignore the Timer0 5950 * interrupt. 5951 */ 5952 fw_err = t4_read_reg(adap, A_PCIE_FW); 5953 val = t4_read_reg(adap, A_CIM_HOST_INT_CAUSE); 5954 if (val & F_TIMER0INT && (!(fw_err & F_PCIE_FW_ERR) || 5955 G_PCIE_FW_EVAL(fw_err) != PCIE_FW_EVAL_CRASH)) { 5956 t4_write_reg(adap, A_CIM_HOST_INT_CAUSE, F_TIMER0INT); 5957 } 5958 5959 fatal = (fw_err & F_PCIE_FW_ERR) != 0; 5960 fatal |= t4_handle_intr(adap, &cim_host_intr_info, 0, flags); 5961 fatal |= t4_handle_intr(adap, &cim_host_upacc_intr_info, 0, flags); 5962 fatal |= t4_handle_intr(adap, &cim_pf_host_intr_info, 0, flags); 5963 if (chip_id(adap) > CHELSIO_T6) 5964 fatal |= t4_handle_intr(adap, &cim_perr_cause, 0, flags); 5965 if (fatal) 5966 t4_os_cim_err(adap); 5967 5968 return (fatal); 5969 } 5970 5971 /* 5972 * ULP RX interrupt handler. 5973 */ 5974 static bool ulprx_intr_handler(struct adapter *adap, int arg, int flags) 5975 { 5976 static const struct intr_details ulprx_intr_details[] = { 5977 /* T5+ */ 5978 { F_SE_CNT_MISMATCH_1, "ULPRX SE count mismatch in channel 1" }, 5979 { F_SE_CNT_MISMATCH_0, "ULPRX SE count mismatch in channel 0" }, 5980 5981 /* T4+ */ 5982 { F_CAUSE_CTX_1, "ULPRX channel 1 context error" }, 5983 { F_CAUSE_CTX_0, "ULPRX channel 0 context error" }, 5984 { 0x007fffff, "ULPRX parity error" }, 5985 { 0 } 5986 }; 5987 static const struct intr_details t6_ulprx_int_cause_details[] = { 5988 { F_SE_CNT_MISMATCH_1, "SE count mismatch in channel1" }, 5989 { F_SE_CNT_MISMATCH_0, "SE count mismatch in channel 0" }, 5990 { F_CAUSE_CTX_1, "Context access error on channel 1" }, 5991 { F_CAUSE_CTX_0, "Context access error on channel 0" }, 5992 { F_CAUSE_FF, "filp-flop based fifos" }, 5993 { F_CAUSE_APF_1, "Arb prefetch memory, channel 1" }, 5994 { F_CAUSE_APF_0, "Arb prefetch memory, channel 0" }, 5995 { F_CAUSE_AF_1, "Arb fetch memory, channel 1" }, 5996 { F_CAUSE_AF_0, "Arb fetch memory, channel 0" }, 5997 { F_CAUSE_DDPDF_1, "ddp_data_fifo Fifo, channel 1" }, 5998 { F_CAUSE_DDPMF_1, "ddp_msg_fifo Fifo, channel 1" }, 5999 { F_CAUSE_MEMRF_1, "mem_req_fifo_d Fifo, channel 1" }, 6000 { F_CAUSE_PRSDF_1, "prsr_data_fifo Fifo, channel 1" }, 6001 { F_CAUSE_DDPDF_0, "ddp_data_fifo Fifo, channel 0" }, 6002 { F_CAUSE_DDPMF_0, "ddp_msg_fifo Fifo, channel 0" }, 6003 { F_CAUSE_MEMRF_0, "mem_req_fifo_d Fifo, channel 0" }, 6004 { F_CAUSE_PRSDF_0, "prsr_data_fifo Fifo, channel 0" }, 6005 { F_CAUSE_PCMDF_1, "Pcmd Fifo, channel 1" }, 6006 { F_CAUSE_TPTCF_1, "tpt_ctl_fifo Fifo, channel 1" }, 6007 { F_CAUSE_DDPCF_1, "ddp_ctl_fifo Fifo, channel 1" }, 6008 { F_CAUSE_MPARF_1, "mpar_ctl_fifo Fifo, channel 1" }, 6009 { F_CAUSE_MPARC_1, "mpac_ctl_fifo Fifo, channel 1" }, 6010 { F_CAUSE_PCMDF_0, "Pcmd Fifo, channel 0" }, 6011 { F_CAUSE_TPTCF_0, "tpt_ctl_fifo Fifo, channel 0" }, 6012 { F_CAUSE_DDPCF_0, "ddp_ctl_fifo Fifo, channel 0" }, 6013 { F_CAUSE_MPARF_0, "mpar_ctl_fifo Fifo, channel 0" }, 6014 { F_CAUSE_MPARC_0, "mpac_ctl_fifo Fifo, channel 0" }, 6015 { 0 } 6016 }; 6017 static const struct intr_details t7_ulprx_int_cause_details[] = { 6018 { F_CERR_PCMD_FIFO_3, "PCMD FIFO correctable Error3" }, 6019 { F_CERR_PCMD_FIFO_2, "PCMD FIFO correctable Error2" }, 6020 { F_CERR_PCMD_FIFO_1, "PCMD FIFO correctable Error1" }, 6021 { F_CERR_PCMD_FIFO_0, "PCMD FIFO correctable Error0" }, 6022 { F_CERR_DATA_FIFO_3, "DDP Data FIFO correctable Error3" }, 6023 { F_CERR_DATA_FIFO_2, "DDP Data FIFO correctable Error2" }, 6024 { F_CERR_DATA_FIFO_1, "DDP Data FIFO correctable Error1" }, 6025 { F_CERR_DATA_FIFO_0, "DDP Data FIFO correctable Error0" }, 6026 { F_SE_CNT_MISMATCH_3, "SE count mismatch in channel3" }, 6027 { F_SE_CNT_MISMATCH_2, "SE count mismatch in channel2" }, 6028 { F_T7_SE_CNT_MISMATCH_1, "SE count mismatch in channel1" }, 6029 { F_T7_SE_CNT_MISMATCH_0, "SE count mismatch in channel 0" }, 6030 { F_T7_ENABLE_CTX_3, "Context access error on channel 3" }, 6031 { F_T7_ENABLE_CTX_2, "Context access error on channel 2" }, 6032 { F_T7_ENABLE_CTX_1, "Context access error on channel 1" }, 6033 { F_T7_ENABLE_CTX_0, "Context access error on channel 0" }, 6034 { F_T7_ENABLE_ALN_SDC_ERR_3, "SDC error reported by aligner in channel3" }, 6035 { F_T7_ENABLE_ALN_SDC_ERR_2, "SDC error reported by aligner in channel2" }, 6036 { F_T7_ENABLE_ALN_SDC_ERR_1, "SDC error reported by aligner in channel1" }, 6037 { F_T7_ENABLE_ALN_SDC_ERR_0, "SDC error reported by aligner in channel0" }, 6038 { 0 } 6039 }; 6040 struct intr_info ulprx_intr_info = { 6041 .name = "ULP_RX_INT_CAUSE", 6042 .cause_reg = A_ULP_RX_INT_CAUSE, 6043 .enable_reg = A_ULP_RX_INT_ENABLE, 6044 .fatal = 0x07ffffff, 6045 .flags = IHF_FATAL_IFF_ENABLED, 6046 .details = NULL, 6047 .actions = NULL, 6048 }; 6049 static const struct intr_details ulprx_int_cause_2_details[] = { 6050 { F_ULPRX2MA_INTFPERR, "SDC error reported by ULPRX2MA interface parity checker" }, 6051 { F_ALN_SDC_ERR_1, "SDC error reported by aligner in channel 1" }, 6052 { F_ALN_SDC_ERR_0, "SDC error reported by aligner in channel 0" }, 6053 { F_PF_UNTAGGED_TPT_1, "Parity error from Untagged TPT prefetch fifo channel 1" }, 6054 { F_PF_UNTAGGED_TPT_0, "Parity error from Untagged TPT prefetch fifo channel 0" }, 6055 { F_PF_PBL_1, "Parity error from PBL prefetch fifo channel 1" }, 6056 { F_PF_PBL_0, "Parity error from PBL prefetch fifo channel 0" }, 6057 { F_DDP_HINT_1, "DDP hint fifo Perr in channel 1" }, 6058 { F_DDP_HINT_0, "DDP hint fifo Perr in channel 0" }, 6059 { 0 } 6060 }; 6061 static const struct intr_info ulprx_intr2_info = { 6062 .name = "ULP_RX_INT_CAUSE_2", 6063 .cause_reg = A_ULP_RX_INT_CAUSE_2, 6064 .enable_reg = A_ULP_RX_INT_ENABLE_2, 6065 .fatal = 0, 6066 .flags = 0, 6067 .details = ulprx_int_cause_2_details, 6068 .actions = NULL, 6069 }; 6070 static const struct intr_details ulprx_int_cause_pcmd_details[] = { 6071 { F_CAUSE_PCMD_SFIFO_3, "Small FIFOs, channel 3" }, 6072 { F_CAUSE_PCMD_FIFO_3, "pcmd_ctl_fifo, channel 3" }, 6073 { F_CAUSE_PCMD_DDP_HINT_3, "ddp_hint_ctl_fifo FIFO, channel 3" }, 6074 { F_CAUSE_PCMD_TPT_3, "tpt_ctl_fifo FIFO, channel 3" }, 6075 { F_CAUSE_PCMD_DDP_3, "ddp_ctl_fifo FIFO, channel 3" }, 6076 { F_CAUSE_PCMD_MPAR_3, "mpar_ctl_fifo FIFO, channel 3" }, 6077 { F_CAUSE_PCMD_MPAC_3, "mpac_ctl_fifo FIFO, channel 3" }, 6078 { F_CAUSE_PCMD_SFIFO_2, "Small FIFOs, channel 2" }, 6079 { F_CAUSE_PCMD_FIFO_2, "pcmd_ctl_fifo, channel 2" }, 6080 { F_CAUSE_PCMD_DDP_HINT_2, "ddp_hint_ctl_fifo FIFO, channel 2" }, 6081 { F_CAUSE_PCMD_TPT_2, "tpt_ctl_fifo FIFO, channel 2" }, 6082 { F_CAUSE_PCMD_DDP_2, "ddp_ctl_fifo FIFO, channel 2" }, 6083 { F_CAUSE_PCMD_MPAR_2, "mpar_ctl_fifo FIFO, channel 2" }, 6084 { F_CAUSE_PCMD_MPAC_2, "mpac_ctl_fifo FIFO, channel 2" }, 6085 { F_CAUSE_PCMD_SFIFO_1, "Small FIFOs, channel 1" }, 6086 { F_CAUSE_PCMD_FIFO_1, "pcmd_ctl_fifo, channel 1" }, 6087 { F_CAUSE_PCMD_DDP_HINT_1, "ddp_hint_ctl_fifo FIFO, channel 1" }, 6088 { F_CAUSE_PCMD_TPT_1, "tpt_ctl_fifo FIFO, channel 1" }, 6089 { F_CAUSE_PCMD_DDP_1, "ddp_ctl_fifo FIFO, channel 1" }, 6090 { F_CAUSE_PCMD_MPAR_1, "mpar_ctl_fifo FIFO, channel 1" }, 6091 { F_CAUSE_PCMD_MPAC_1, "mpac_ctl_fifo FIFO, channel 1" }, 6092 { F_CAUSE_PCMD_SFIFO_0, "Small FIFOs, channel 0" }, 6093 { F_CAUSE_PCMD_FIFO_0, "pcmd_ctl_fifo, channel 0" }, 6094 { F_CAUSE_PCMD_DDP_HINT_0, "ddp_hint_ctl_fifo FIFO, channel 0" }, 6095 { F_CAUSE_PCMD_TPT_0, "tpt_ctl_fifo FIFO, channel 0" }, 6096 { F_CAUSE_PCMD_DDP_0, "ddp_ctl_fifo FIFO, channel 0" }, 6097 { F_CAUSE_PCMD_MPAR_0, "mpar_ctl_fifo FIFO, channel 0" }, 6098 { F_CAUSE_PCMD_MPAC_0, "mpac_ctl_fifo FIFO, channel 0" }, 6099 { 0 } 6100 }; 6101 static const struct intr_info ulprx_int_cause_pcmd = { 6102 .name = "ULP_RX_INT_CAUSE_PCMD", 6103 .cause_reg = A_ULP_RX_INT_CAUSE_PCMD, 6104 .enable_reg = A_ULP_RX_INT_ENABLE_PCMD, 6105 .fatal = 0, 6106 .flags = 0, 6107 .details = ulprx_int_cause_pcmd_details, 6108 .actions = NULL, 6109 }; 6110 static const struct intr_details ulprx_int_cause_data_details[] = { 6111 { F_CAUSE_DATA_SNOOP_3, "Snoop FIFO, channel 3" }, 6112 { F_CAUSE_DATA_SFIFO_3, "Small FIFO, channel 3" }, 6113 { F_CAUSE_DATA_FIFO_3, "data_ctl_fifo FIFO, channel 3" }, 6114 { F_CAUSE_DATA_DDP_3, "ddp_ctl_fifo FIFO, channel 3" }, 6115 { F_CAUSE_DATA_CTX_3, "ctx_ctl_fifo FIFO, channel 3" }, 6116 { F_CAUSE_DATA_PARSER_3, "parser_ctl_fifo FIFO, channel 3" }, 6117 { F_CAUSE_DATA_SNOOP_2, "Snoop FIFO, channel 2" }, 6118 { F_CAUSE_DATA_SFIFO_2, "Small FIFO, channel 2" }, 6119 { F_CAUSE_DATA_FIFO_2, "data_ctl_fifo FIFO, channel 2" }, 6120 { F_CAUSE_DATA_DDP_2, "ddp_ctl_fifo FIFO, channel 2" }, 6121 { F_CAUSE_DATA_CTX_2, "ctx_ctl_fifo FIFO, channel 2" }, 6122 { F_CAUSE_DATA_PARSER_2, "parser_ctl_fifo FIFO, channel 2" }, 6123 { F_CAUSE_DATA_SNOOP_1, "Snoop FIFO, channel 1" }, 6124 { F_CAUSE_DATA_SFIFO_1, "Small FIFO, channel 1" }, 6125 { F_CAUSE_DATA_FIFO_1, "data_ctl_fifo FIFO, channel 1" }, 6126 { F_CAUSE_DATA_DDP_1, "ddp_ctl_fifo FIFO, channel 1" }, 6127 { F_CAUSE_DATA_CTX_1, "ctx_ctl_fifo FIFO, channel 1" }, 6128 { F_CAUSE_DATA_PARSER_1, "parser_ctl_fifo FIFO, channel 1" }, 6129 { F_CAUSE_DATA_SNOOP_0, "Snoop FIFO, channel 0" }, 6130 { F_CAUSE_DATA_SFIFO_0, "Small FIFO, channel 0" }, 6131 { F_CAUSE_DATA_FIFO_0, "data_ctl_fifo FIFO, channel 0" }, 6132 { F_CAUSE_DATA_DDP_0, "ddp_ctl_fifo FIFO, channel 0" }, 6133 { F_CAUSE_DATA_CTX_0, "ctx_ctl_fifo FIFO, channel 0" }, 6134 { F_CAUSE_DATA_PARSER_0, "parser_ctl_fifo FIFO, channel 0" }, 6135 { 0 } 6136 }; 6137 static const struct intr_info ulprx_int_cause_data = { 6138 .name = "ULP_RX_INT_CAUSE_DATA", 6139 .cause_reg = A_ULP_RX_INT_CAUSE_DATA, 6140 .enable_reg = A_ULP_RX_INT_ENABLE_DATA, 6141 .fatal = 0, 6142 .flags = 0, 6143 .details = ulprx_int_cause_data_details, 6144 .actions = NULL, 6145 }; 6146 static const struct intr_details ulprx_int_cause_arb_details[] = { 6147 { F_CAUSE_ARB_PBL_PF_3, "pbl_pf_ctl_fifo FIFO, channel 3" }, 6148 { F_CAUSE_ARB_PF_3, "pf_ctl_fifo FIFO, channel 3" }, 6149 { F_CAUSE_ARB_TPT_PF_3, "tpt_pf_ctl_fifo FIFO, channel 3" }, 6150 { F_CAUSE_ARB_F_3, "f_ctl_fifo FIFO, channel 3" }, 6151 { F_CAUSE_ARB_PBL_PF_2, "pbl_pf_ctl_fifo FIFO, channel 2" }, 6152 { F_CAUSE_ARB_PF_2, "pf_ctl_fifo FIFO, channel 2" }, 6153 { F_CAUSE_ARB_TPT_PF_2, "tpt_pf_ctl_fifo FIFO, channel 2" }, 6154 { F_CAUSE_ARB_F_2, "f_ctl_fifo FIFO, channel 2" }, 6155 { F_CAUSE_ARB_PBL_PF_1, "pbl_pf_ctl_fifo FIFO, channel 1" }, 6156 { F_CAUSE_ARB_PF_1, "pf_ctl_fifo FIFO, channel 1" }, 6157 { F_CAUSE_ARB_TPT_PF_1, "tpt_pf_ctl_fifo FIFO, channel 1" }, 6158 { F_CAUSE_ARB_F_1, "f_ctl_fifo FIFO, channel 1" }, 6159 { F_CAUSE_ARB_PBL_PF_0, "pbl_pf_ctl_fifo FIFO, channel 0" }, 6160 { F_CAUSE_ARB_PF_0, "pf_ctl_fifo FIFO, channel 0" }, 6161 { F_CAUSE_ARB_TPT_PF_0, "tpt_pf_ctl_fifo FIFO, channel 0" }, 6162 { F_CAUSE_ARB_F_0, "f_ctl_fifo FIFO, channel 0" }, 6163 { 0 } 6164 }; 6165 static const struct intr_info ulprx_int_cause_arb = { 6166 .name = "ULP_RX_INT_CAUSE_ARB", 6167 .cause_reg = A_ULP_RX_INT_CAUSE_ARB, 6168 .enable_reg = A_ULP_RX_INT_ENABLE_ARB, 6169 .fatal = 0, 6170 .flags = 0, 6171 .details = ulprx_int_cause_arb_details, 6172 .actions = NULL, 6173 }; 6174 static const struct intr_details ulprx_int_cause_interface_details[] = { 6175 { F_CAUSE_ULPRX2SBT_RSPPERR, "ULPRX2SBT_RspPerr" }, 6176 { F_CAUSE_ULPRX2MA_RSPPERR, "ULPRX2MA_RspPerr" }, 6177 { F_CAUSE_PIO_BUS_PERR, "Pio_Bus_Perr" }, 6178 { F_CAUSE_PM2ULP_SNOOPDATA_3, "PM2ULP_SnoopData, channel 3" }, 6179 { F_CAUSE_PM2ULP_SNOOPDATA_2, "PM2ULP_SnoopData, channel 2" }, 6180 { F_CAUSE_PM2ULP_SNOOPDATA_1, "PM2ULP_SnoopData, channel 1" }, 6181 { F_CAUSE_PM2ULP_SNOOPDATA_0, "PM2ULP_SnoopData, channel 0" }, 6182 { F_CAUSE_TLS2ULP_DATA_3, "TLS2ULP_Data, channel 3" }, 6183 { F_CAUSE_TLS2ULP_DATA_2, "TLS2ULP_Data, channel 2" }, 6184 { F_CAUSE_TLS2ULP_DATA_1, "TLS2ULP_Data, channel 1" }, 6185 { F_CAUSE_TLS2ULP_DATA_0, "TLS2ULP_Data, channel 0" }, 6186 { F_CAUSE_TLS2ULP_PLENDATA_3, "TLS2ULP_PLenData, channel 3" }, 6187 { F_CAUSE_TLS2ULP_PLENDATA_2, "TLS2ULP_PLenData, channel 2" }, 6188 { F_CAUSE_TLS2ULP_PLENDATA_1, "TLS2ULP_PLenData, channel 1" }, 6189 { F_CAUSE_TLS2ULP_PLENDATA_0, "TLS2ULP_PLenData, channel 0" }, 6190 { F_CAUSE_PM2ULP_DATA_3, "Pm2Ulp_Data, channel 3" }, 6191 { F_CAUSE_PM2ULP_DATA_2, "Pm2Ulp_Data, channel 2" }, 6192 { F_CAUSE_PM2ULP_DATA_1, "Pm2Ulp_Data, channel 1" }, 6193 { F_CAUSE_PM2ULP_DATA_0, "Pm2Ulp_Data, channel 0" }, 6194 { F_CAUSE_TP2ULP_PCMD_3, "Tp2Ulp_Pcmd, channel 3" }, 6195 { F_CAUSE_TP2ULP_PCMD_2, "Tp2Ulp_Pcmd, channel 2" }, 6196 { F_CAUSE_TP2ULP_PCMD_1, "Tp2Ulp_Pcmd, channel 1" }, 6197 { F_CAUSE_TP2ULP_PCMD_0, "Tp2Ulp_Pcmd, channel 0" }, 6198 { 0 } 6199 }; 6200 static const struct intr_info ulprx_int_cause_intf = { 6201 .name = "ULP_RX_INT_CAUSE_INTERFACE", 6202 .cause_reg = A_ULP_RX_INT_CAUSE_INTERFACE, 6203 .enable_reg = A_ULP_RX_INT_ENABLE_INTERFACE, 6204 .fatal = 0, 6205 .flags = 0, 6206 .details = ulprx_int_cause_interface_details, 6207 .actions = NULL, 6208 }; 6209 bool fatal = false; 6210 6211 if (chip_id(adap) <= CHELSIO_T5) 6212 ulprx_intr_info.details = ulprx_intr_details; 6213 else if (chip_id(adap) <= CHELSIO_T6) 6214 ulprx_intr_info.details = t6_ulprx_int_cause_details; 6215 else 6216 ulprx_intr_info.details = t7_ulprx_int_cause_details; 6217 6218 fatal |= t4_handle_intr(adap, &ulprx_intr_info, 0, flags); 6219 if (chip_id(adap) < CHELSIO_T7) 6220 fatal |= t4_handle_intr(adap, &ulprx_intr2_info, 0, flags); 6221 else { 6222 fatal |= t4_handle_intr(adap, &ulprx_int_cause_pcmd, 0, flags); 6223 fatal |= t4_handle_intr(adap, &ulprx_int_cause_data, 0, flags); 6224 fatal |= t4_handle_intr(adap, &ulprx_int_cause_arb, 0, flags); 6225 fatal |= t4_handle_intr(adap, &ulprx_int_cause_intf, 0, flags); 6226 } 6227 6228 return (fatal); 6229 } 6230 6231 /* 6232 * ULP TX interrupt handler. 6233 */ 6234 static bool ulptx_intr_handler(struct adapter *adap, int arg, int flags) 6235 { 6236 static const struct intr_details ulptx_intr_details[] = { 6237 { F_PBL_BOUND_ERR_CH3, "ULPTX channel 3 PBL out of bounds" }, 6238 { F_PBL_BOUND_ERR_CH2, "ULPTX channel 2 PBL out of bounds" }, 6239 { F_PBL_BOUND_ERR_CH1, "ULPTX channel 1 PBL out of bounds" }, 6240 { F_PBL_BOUND_ERR_CH0, "ULPTX channel 0 PBL out of bounds" }, 6241 { 0x0fffffff, "ULPTX parity error" }, 6242 { 0 } 6243 }; 6244 static const struct intr_details t6_ulptx_int_cause_details[] = { 6245 { F_PBL_BOUND_ERR_CH3 | F_PBL_BOUND_ERR_CH2 | 6246 F_PBL_BOUND_ERR_CH1 | F_PBL_BOUND_ERR_CH0, 6247 "PBL address out of bounds" }, 6248 { F_SGE2ULP_FIFO_PERR_SET3 | F_SGE2ULP_FIFO_PERR_SET2 | 6249 F_SGE2ULP_FIFO_PERR_SET1 | F_SGE2ULP_FIFO_PERR_SET0, 6250 "SGE2ULP fifo parity error" }, 6251 { F_CIM2ULP_FIFO_PERR_SET3 | F_CIM2ULP_FIFO_PERR_SET2 | 6252 F_CIM2ULP_FIFO_PERR_SET1 | F_CIM2ULP_FIFO_PERR_SET0, 6253 "CIM2ULP fifo parity error" }, 6254 { F_CQE_FIFO_PERR_SET3 | F_CQE_FIFO_PERR_SET2 | 6255 F_CQE_FIFO_PERR_SET1 | F_CQE_FIFO_PERR_SET0, 6256 "CQE fifo parity error" }, 6257 { F_PBL_FIFO_PERR_SET3 | F_PBL_FIFO_PERR_SET2 | 6258 F_PBL_FIFO_PERR_SET1 | F_PBL_FIFO_PERR_SET0, 6259 "PBL fifo parity error" }, 6260 { F_CMD_FIFO_PERR_SET3 | F_CMD_FIFO_PERR_SET2 | 6261 F_CMD_FIFO_PERR_SET1 | F_CMD_FIFO_PERR_SET0, 6262 "Command fifo parity error" }, 6263 { F_LSO_HDR_SRAM_PERR_SET3 | F_LSO_HDR_SRAM_PERR_SET2 | 6264 F_LSO_HDR_SRAM_PERR_SET1 | F_LSO_HDR_SRAM_PERR_SET0, 6265 "LSO hdr parity error" }, 6266 { 0 } 6267 }; 6268 struct intr_info ulptx_intr_info = { 6269 .name = "ULP_TX_INT_CAUSE", 6270 .cause_reg = A_ULP_TX_INT_CAUSE, 6271 .enable_reg = A_ULP_TX_INT_ENABLE, 6272 .fatal = 0x0fffffff, 6273 .flags = IHF_FATAL_IFF_ENABLED, 6274 .details = NULL, 6275 .actions = NULL, 6276 }; 6277 static const struct intr_details ulptx_int_cause_1_details[] = { 6278 { F_PBL_BOUND_ERR_CH3 | F_PBL_BOUND_ERR_CH2 | 6279 F_PBL_BOUND_ERR_CH1 | F_PBL_BOUND_ERR_CH0, 6280 "PBL address out of bounds (configured PBL_ULIMIT/LLIMIT)" }, 6281 { F_SGE2ULP_FIFO_PERR_SET3 | F_SGE2ULP_FIFO_PERR_SET2 | 6282 F_SGE2ULP_FIFO_PERR_SET1 | F_SGE2ULP_FIFO_PERR_SET0, 6283 "SGE2ULP FIFO parity error" }, 6284 { F_CIM2ULP_FIFO_PERR_SET3 | F_CIM2ULP_FIFO_PERR_SET2 | 6285 F_CIM2ULP_FIFO_PERR_SET1 | F_CIM2ULP_FIFO_PERR_SET0, 6286 "CIM2ULP FIFO parity error" }, 6287 { F_CQE_FIFO_PERR_SET3 | F_CQE_FIFO_PERR_SET2 | 6288 F_CQE_FIFO_PERR_SET1 | F_CQE_FIFO_PERR_SET0, 6289 "CQE FIFO parity error" }, 6290 { F_PBL_FIFO_PERR_SET3 | F_PBL_FIFO_PERR_SET2 | 6291 F_PBL_FIFO_PERR_SET1 | F_PBL_FIFO_PERR_SET0, 6292 "PBL FIFO parity error" }, 6293 { F_CMD_FIFO_PERR_SET3 | F_CMD_FIFO_PERR_SET2 | 6294 F_CMD_FIFO_PERR_SET1 | F_CMD_FIFO_PERR_SET0, 6295 "Command FIFO parity error" }, 6296 { F_LSO_HDR_SRAM_PERR_SET3 | F_LSO_HDR_SRAM_PERR_SET2 | 6297 F_LSO_HDR_SRAM_PERR_SET1 | F_LSO_HDR_SRAM_PERR_SET0, 6298 "LSO HDR parity error" }, 6299 { F_TLS_DSGL_PARERR3 | F_TLS_DSGL_PARERR2 | 6300 F_TLS_DSGL_PARERR1 | F_TLS_DSGL_PARERR0, 6301 "TLS Glue DSGL FIFO parity error" }, 6302 { 0 } 6303 }; 6304 static const struct intr_info ulptx_intr_info1 = { 6305 .name = "ULP_TX_INT_CAUSE_1", 6306 .cause_reg = A_ULP_TX_INT_CAUSE_1, 6307 .enable_reg = A_ULP_TX_INT_ENABLE_1, 6308 .fatal = 0x0fffffff, 6309 .flags = IHF_FATAL_IFF_ENABLED, 6310 .details = ulptx_int_cause_1_details, 6311 .actions = NULL, 6312 }; 6313 static const struct intr_details ulptx_int_cause_2_details[] = { 6314 { F_EDMA_IN_FIFO_PERR_SET3 | F_EDMA_IN_FIFO_PERR_SET2 | 6315 F_EDMA_IN_FIFO_PERR_SET1 | F_EDMA_IN_FIFO_PERR_SET0, 6316 "EDMA input FIFO parity error" }, 6317 { F_ALIGN_CTL_FIFO_PERR_SET3 | F_ALIGN_CTL_FIFO_PERR_SET2 | 6318 F_ALIGN_CTL_FIFO_PERR_SET1 | F_ALIGN_CTL_FIFO_PERR_SET0, 6319 "Align control FIFO parity error" }, 6320 { F_SGE_FIFO_PERR_SET3 | F_SGE_FIFO_PERR_SET2 | 6321 F_SGE_FIFO_PERR_SET1 | F_SGE_FIFO_PERR_SET0, 6322 "SGE FIFO parity error" }, 6323 { F_STAG_FIFO_PERR_SET3 | F_STAG_FIFO_PERR_SET2 | 6324 F_STAG_FIFO_PERR_SET1 | F_STAG_FIFO_PERR_SET0, 6325 "STAG FIFO parity error" }, 6326 { F_MAP_FIFO_PERR_SET3 | F_MAP_FIFO_PERR_SET2 | 6327 F_MAP_FIFO_PERR_SET1 | F_MAP_FIFO_PERR_SET0, 6328 "MAP FIFO parity error" }, 6329 { F_DMA_FIFO_PERR_SET3 | F_DMA_FIFO_PERR_SET2 | 6330 F_DMA_FIFO_PERR_SET1 | F_DMA_FIFO_PERR_SET0, 6331 "DMA FIFO parity error" }, 6332 { F_FSO_HDR_SRAM_PERR_SET3 | F_FSO_HDR_SRAM_PERR_SET2 | 6333 F_FSO_HDR_SRAM_PERR_SET1 | F_FSO_HDR_SRAM_PERR_SET0, 6334 "FSO HDR memory parity error" }, 6335 { F_T10_PI_SRAM_PERR_SET3 | F_T10_PI_SRAM_PERR_SET2 | 6336 F_T10_PI_SRAM_PERR_SET1 | F_T10_PI_SRAM_PERR_SET0, 6337 "T10 PI memory parity error" }, 6338 { 0 } 6339 }; 6340 static const struct intr_info ulptx_intr_info2 = { 6341 .name = "ULP_TX_INT_CAUSE_2", 6342 .cause_reg = A_ULP_TX_INT_CAUSE_2, 6343 .enable_reg = A_ULP_TX_INT_ENABLE_2, 6344 .fatal = 0xffffffff, 6345 .flags = IHF_FATAL_IFF_ENABLED, 6346 .details = ulptx_int_cause_2_details, 6347 .actions = NULL, 6348 }; 6349 static const struct intr_details ulptx_int_cause_3_details[] = { 6350 { F_GF_SGE_FIFO_PARERR3 | F_GF_SGE_FIFO_PARERR2 | 6351 F_GF_SGE_FIFO_PARERR1 | F_GF_SGE_FIFO_PARERR0, 6352 "GF SGE interface FIFO parity error" }, 6353 { F_DEDUPE_SGE_FIFO_PARERR3 | F_DEDUPE_SGE_FIFO_PARERR2 | 6354 F_DEDUPE_SGE_FIFO_PARERR1 | F_DEDUPE_SGE_FIFO_PARERR0, 6355 "DeDupe SGE interface FIFO parity error" }, 6356 { F_GF3_DSGL_FIFO_PARERR | F_GF2_DSGL_FIFO_PARERR | 6357 F_GF1_DSGL_FIFO_PARERR | F_GF0_DSGL_FIFO_PARERR, 6358 "GF DSGL FIFO parity error" }, 6359 { F_DEDUPE3_DSGL_FIFO_PARERR | F_DEDUPE2_DSGL_FIFO_PARERR | 6360 F_DEDUPE1_DSGL_FIFO_PARERR | F_DEDUPE0_DSGL_FIFO_PARERR, 6361 "DeDupe DSGL FIFO parity error" }, 6362 { F_XP10_SGE_FIFO_PARERR, "XP10 SGE FIFO parity error (Ch0)" }, 6363 { F_DSGL_PAR_ERR, "XP10 DSGL interface parity error" }, 6364 { F_CDDIP_INT, "XP10 decompression interrupt" }, 6365 { F_CCEIP_INT, "XP10 compression interrupt" }, 6366 { F_TLS_SGE_FIFO_PARERR3 | F_TLS_SGE_FIFO_PARERR2 | 6367 F_TLS_SGE_FIFO_PARERR1 | F_TLS_SGE_FIFO_PARERR0, 6368 "TLS Glue SGE FIFO parity error" }, 6369 { F_ULP2SMARBT_RSP_PERR, "ULP2SMARBT response data/CTL parity error" }, 6370 { F_ULPTX2MA_RSP_PERR, "ULP2MA response data/CTL parity error" }, 6371 { F_PCIE2ULP_PERR3 | F_PCIE2ULP_PERR2 | 6372 F_PCIE2ULP_PERR1 | F_PCIE2ULP_PERR0, 6373 "PCIE2ULP EDMA response parity error" }, 6374 { F_CIM2ULP_PERR, "CIM2ULP command parity error (all ports)" }, 6375 { 0 } 6376 }; 6377 static const struct intr_info ulptx_intr_info3 = { 6378 .name = "ULP_TX_INT_CAUSE_3", 6379 .cause_reg = A_ULP_TX_INT_CAUSE_3, 6380 .enable_reg = A_ULP_TX_INT_ENABLE_3, 6381 .fatal = 0xffffffff, 6382 .flags = IHF_FATAL_IFF_ENABLED, 6383 .details = ulptx_int_cause_3_details, 6384 .actions = NULL, 6385 }; 6386 static const struct intr_details ulptx_int_cause_4_details[] = { 6387 { F_XP10_2_ULP_PERR, "XP10 to ULP parity error" }, 6388 { F_ULP_2_XP10_PERR, "ULP to XP10 parity error" }, 6389 { F_CMD_FIFO_LB1 | F_CMD_FIFO_LB0, 6390 "Command FIFO LB error" }, 6391 { F_TF_TP_PERR, "TF TP parity error" }, 6392 { F_TF_SGE_PERR, "TF SGE parity error" }, 6393 { F_TF_MEM_PERR, "TF memory parity error" }, 6394 { F_TF_MP_PERR, "TF MP parity error" }, 6395 { 0 } 6396 }; 6397 static const struct intr_info ulptx_intr_info4 = { 6398 .name = "ULP_TX_INT_CAUSE_4", 6399 .cause_reg = A_ULP_TX_INT_CAUSE_4, 6400 .enable_reg = A_ULP_TX_INT_ENABLE_4, 6401 .fatal = 0xffffffff, 6402 .flags = IHF_FATAL_IFF_ENABLED, 6403 .details = ulptx_int_cause_4_details, 6404 .actions = NULL, 6405 }; 6406 static const struct intr_details ulptx_int_cause_5_details[] = { 6407 { F_DEDUPE_PERR3 | F_DEDUPE_PERR2 | 6408 F_DEDUPE_PERR1 | F_DEDUPE_PERR0, 6409 "DeDupe parity error" }, 6410 { F_GF_PERR3 | F_GF_PERR2 | 6411 F_GF_PERR1 | F_GF_PERR0, 6412 "GF parity error" }, 6413 { F_SGE2ULP_INV_PERR, "SGE2ULP invalid parity error" }, 6414 { F_T7_PL_BUSPERR, "PL bus parity error" }, 6415 { F_TLSTX2ULPTX_PERR3 | F_TLSTX2ULPTX_PERR2 | 6416 F_TLSTX2ULPTX_PERR1 | F_TLSTX2ULPTX_PERR0, 6417 "TLS to ULP parity error" }, 6418 { F_XP10_2_ULP_PL_PERR, "XP10 to ULP PL parity error" }, 6419 { F_ULP_2_XP10_PL_PERR, "ULP to XP10 PL parity error" }, 6420 { 0 } 6421 }; 6422 static const struct intr_info ulptx_intr_info5 = { 6423 .name = "ULP_TX_INT_CAUSE_5", 6424 .cause_reg = A_ULP_TX_INT_CAUSE_5, 6425 .enable_reg = A_ULP_TX_INT_ENABLE_5, 6426 .fatal = 0xffffffff, 6427 .flags = IHF_FATAL_IFF_ENABLED, 6428 .details = ulptx_int_cause_5_details, 6429 .actions = NULL, 6430 }; 6431 static const struct intr_details ulptx_int_cause_6_details[] = { 6432 { F_DDR_HDR_FIFO_PERR_SET3 | F_DDR_HDR_FIFO_PERR_SET2 | 6433 F_DDR_HDR_FIFO_PERR_SET1 | F_DDR_HDR_FIFO_PERR_SET0, 6434 "DDR HDR FIFO parity error" }, 6435 { F_PRE_MP_RSP_PERR_SET3 | F_PRE_MP_RSP_PERR_SET2 | 6436 F_PRE_MP_RSP_PERR_SET1 | F_PRE_MP_RSP_PERR_SET0, 6437 "Pre-MP response parity error" }, 6438 { F_PRE_CQE_FIFO_PERR_SET3 | F_PRE_CQE_FIFO_PERR_SET2 | 6439 F_PRE_CQE_FIFO_PERR_SET1 | F_PRE_CQE_FIFO_PERR_SET0, 6440 "Pre-CQE FIFO parity error" }, 6441 { F_RSP_FIFO_PERR_SET, "Response FIFO parity error" }, 6442 { 0 } 6443 }; 6444 static const struct intr_info ulptx_intr_info6 = { 6445 .name = "ULP_TX_INT_CAUSE_6", 6446 .cause_reg = A_ULP_TX_INT_CAUSE_6, 6447 .enable_reg = A_ULP_TX_INT_ENABLE_6, 6448 .fatal = 0xffffffff, 6449 .flags = IHF_FATAL_IFF_ENABLED, 6450 .details = ulptx_int_cause_6_details, 6451 .actions = NULL, 6452 }; 6453 static const struct intr_details ulptx_int_cause_7_details[] = { 6454 { F_TLS_SGE_FIFO_CORERR3 | F_TLS_SGE_FIFO_CORERR2 | 6455 F_TLS_SGE_FIFO_CORERR1 | F_TLS_SGE_FIFO_CORERR0, 6456 "TLS SGE FIFO correctable error" }, 6457 { F_LSO_HDR_SRAM_CERR_SET3 | F_LSO_HDR_SRAM_CERR_SET2 | 6458 F_LSO_HDR_SRAM_CERR_SET1 | F_LSO_HDR_SRAM_CERR_SET0, 6459 "LSO HDR SRAM correctable error" }, 6460 { F_CORE_CMD_FIFO_CERR_SET_CH3_LB1 | F_CORE_CMD_FIFO_CERR_SET_CH2_LB1 | 6461 F_CORE_CMD_FIFO_CERR_SET_CH1_LB1 | F_CORE_CMD_FIFO_CERR_SET_CH0_LB1, 6462 "Core command FIFO LB1 correctable error" }, 6463 { F_CORE_CMD_FIFO_CERR_SET_CH3_LB0 | F_CORE_CMD_FIFO_CERR_SET_CH2_LB0 | 6464 F_CORE_CMD_FIFO_CERR_SET_CH1_LB0 | F_CORE_CMD_FIFO_CERR_SET_CH0_LB0, 6465 "Core command FIFO LB0 correctable error" }, 6466 { F_CQE_FIFO_CERR_SET3 | F_CQE_FIFO_CERR_SET2 | 6467 F_CQE_FIFO_CERR_SET1 | F_CQE_FIFO_CERR_SET0, 6468 "CQE FIFO correctable error" }, 6469 { F_PRE_CQE_FIFO_CERR_SET3 | F_PRE_CQE_FIFO_CERR_SET2 | 6470 F_PRE_CQE_FIFO_CERR_SET1 | F_PRE_CQE_FIFO_CERR_SET0, 6471 "Pre-CQE FIFO correctable error" }, 6472 { 0 } 6473 }; 6474 static const struct intr_info ulptx_intr_info7 = { 6475 .name = "ULP_TX_INT_CAUSE_7", 6476 .cause_reg = A_ULP_TX_INT_CAUSE_7, 6477 .enable_reg = A_ULP_TX_INT_ENABLE_7, 6478 .fatal = 0, 6479 .flags = 0, 6480 .details = ulptx_int_cause_7_details, 6481 .actions = NULL, 6482 }; 6483 static const struct intr_details ulptx_int_cause_8_details[] = { 6484 { F_MEM_RSP_FIFO_CERR_SET3 | F_MEM_RSP_FIFO_CERR_SET2 | 6485 F_MEM_RSP_FIFO_CERR_SET1 | F_MEM_RSP_FIFO_CERR_SET0, 6486 "Memory response FIFO correctable error" }, 6487 { F_PI_SRAM_CERR_SET3 | F_PI_SRAM_CERR_SET2 | 6488 F_PI_SRAM_CERR_SET1 | F_PI_SRAM_CERR_SET0, 6489 "PI SRAM correctable error" }, 6490 { F_PRE_MP_RSP_CERR_SET3 | F_PRE_MP_RSP_CERR_SET2 | 6491 F_PRE_MP_RSP_CERR_SET1 | F_PRE_MP_RSP_CERR_SET0, 6492 "Pre-MP response correctable error" }, 6493 { F_DDR_HDR_FIFO_CERR_SET3 | F_DDR_HDR_FIFO_CERR_SET2 | 6494 F_DDR_HDR_FIFO_CERR_SET1 | F_DDR_HDR_FIFO_CERR_SET0, 6495 "DDR HDR FIFO correctable error" }, 6496 { F_CMD_FIFO_CERR_SET3 | F_CMD_FIFO_CERR_SET2 | 6497 F_CMD_FIFO_CERR_SET1 | F_CMD_FIFO_CERR_SET0, 6498 "Command FIFO correctable error" }, 6499 { F_GF_SGE_FIFO_CORERR3 | F_GF_SGE_FIFO_CORERR2 | 6500 F_GF_SGE_FIFO_CORERR1 | F_GF_SGE_FIFO_CORERR0, 6501 "GF SGE FIFO correctable error" }, 6502 { F_DEDUPE_SGE_FIFO_CORERR3 | F_DEDUPE_SGE_FIFO_CORERR2 | 6503 F_DEDUPE_SGE_FIFO_CORERR1 | F_DEDUPE_SGE_FIFO_CORERR0, 6504 "DeDupe SGE FIFO correctable error" }, 6505 { F_RSP_FIFO_CERR_SET, "Response FIFO correctable error" }, 6506 { 0 } 6507 }; 6508 static const struct intr_info ulptx_intr_info8 = { 6509 .name = "ULP_TX_INT_CAUSE_8", 6510 .cause_reg = A_ULP_TX_INT_CAUSE_8, 6511 .enable_reg = A_ULP_TX_INT_ENABLE_8, 6512 .fatal = 0, 6513 .flags = 0, 6514 .details = ulptx_int_cause_8_details, 6515 .actions = NULL, 6516 }; 6517 bool fatal = false; 6518 6519 if (chip_id(adap) > CHELSIO_T6) { 6520 fatal |= t4_handle_intr(adap, &ulptx_intr_info1, 0, flags); 6521 fatal |= t4_handle_intr(adap, &ulptx_intr_info2, 0, flags); 6522 fatal |= t4_handle_intr(adap, &ulptx_intr_info3, 0, flags); 6523 fatal |= t4_handle_intr(adap, &ulptx_intr_info4, 0, flags); 6524 fatal |= t4_handle_intr(adap, &ulptx_intr_info5, 0, flags); 6525 fatal |= t4_handle_intr(adap, &ulptx_intr_info6, 0, flags); 6526 fatal |= t4_handle_intr(adap, &ulptx_intr_info7, 0, flags); 6527 fatal |= t4_handle_intr(adap, &ulptx_intr_info8, 0, flags); 6528 } else { 6529 if (chip_id(adap) == CHELSIO_T6) 6530 ulptx_intr_info.details = t6_ulptx_int_cause_details; 6531 else 6532 ulptx_intr_info.details = ulptx_intr_details; 6533 fatal |= t4_handle_intr(adap, &ulptx_intr_info, 0, flags); 6534 if (chip_id(adap) > CHELSIO_T4) 6535 fatal |= t4_handle_intr(adap, &ulptx_intr_info2, 0, flags); 6536 } 6537 6538 return (fatal); 6539 } 6540 6541 static bool pmtx_dump_dbg_stats(struct adapter *adap, int arg, int flags) 6542 { 6543 int i; 6544 u32 data[17]; 6545 6546 if (flags & IHF_NO_SHOW) 6547 return (false); 6548 6549 t4_read_indirect(adap, A_PM_TX_DBG_CTRL, A_PM_TX_DBG_DATA, &data[0], 6550 ARRAY_SIZE(data), A_PM_TX_DBG_STAT0); 6551 for (i = 0; i < ARRAY_SIZE(data); i++) { 6552 CH_ALERT(adap, " - PM_TX_DBG_STAT%u (0x%x) = 0x%08x\n", i, 6553 A_PM_TX_DBG_STAT0 + i, data[i]); 6554 } 6555 6556 return (false); 6557 } 6558 6559 /* 6560 * PM TX interrupt handler. 6561 */ 6562 static bool pmtx_intr_handler(struct adapter *adap, int arg, int flags) 6563 { 6564 static const struct intr_details t7_pmtx_int_cause_fields[] = { 6565 { F_MASTER_PERR, "PM_TX master parity error" }, 6566 { F_T7_ZERO_C_CMD_ERROR, "PM_TX PCMD with zero length error" }, 6567 { F_OESPI_COR_ERR, " oespi FIFO Correctable Error" }, 6568 { F_ICSPI_COR_ERR, " icspi FIFO Correctable Error" }, 6569 { F_ICSPI_OVFL, " icspi FIFO overflow" }, 6570 { F_T7_PCMD_LEN_OVFL0, "PMTX channel 0 pcmd too large" }, 6571 { F_T7_PCMD_LEN_OVFL1, "PMTX channel 1 pcmd too large" }, 6572 { F_T7_PCMD_LEN_OVFL2, "PMTX channel 2 pcmd too large" }, 6573 { F_PCMD_LEN_OVFL3, "PMTX channel 2 pcmd too large" }, 6574 { F_T7_ZERO_C_CMD_ERROR, "PMTX 0-length pcmd" }, 6575 { 0x00f00000, "PM_TX PCMD length larger than oespi capacity" }, 6576 { 0x000f0000, "PM_TX icspi 2x FIFO Rx framing error" }, 6577 { 0x0000f000, "PM_TX icspi FIFO Tx framing error" }, 6578 { 0x00000f00, "PM_TX oespi FIFO Rx framing error" }, 6579 { 0x000000f0, "PM_TX oespi FIFO Tx framing error" }, 6580 { 0x0000000f, "PM_TX oespi 2x FIFO Tx framing error" }, 6581 { 0 } 6582 }; 6583 static const struct intr_details pmtx_int_cause_fields[] = { 6584 { F_PCMD_LEN_OVFL0, "PMTX channel 0 pcmd too large" }, 6585 { F_PCMD_LEN_OVFL1, "PMTX channel 1 pcmd too large" }, 6586 { F_PCMD_LEN_OVFL2, "PMTX channel 2 pcmd too large" }, 6587 { F_ZERO_C_CMD_ERROR, "PMTX 0-length pcmd" }, 6588 { 0x0f000000, "PMTX icspi FIFO2X Rx framing error" }, 6589 { 0x00f00000, "PMTX icspi FIFO Rx framing error" }, 6590 { 0x000f0000, "PMTX icspi FIFO Tx framing error" }, 6591 { 0x0000f000, "PMTX oespi FIFO Rx framing error" }, 6592 { 0x00000f00, "PMTX oespi FIFO Tx framing error" }, 6593 { 0x000000f0, "PMTX oespi FIFO2X Tx framing error" }, 6594 { F_OESPI_PAR_ERROR, "PMTX oespi parity error" }, 6595 { F_DB_OPTIONS_PAR_ERROR, "PMTX db_options parity error" }, 6596 { F_ICSPI_PAR_ERROR, "PMTX icspi parity error" }, 6597 { F_C_PCMD_PAR_ERROR, "PMTX c_pcmd parity error" }, 6598 { 0 } 6599 }; 6600 static const struct intr_action pmtx_int_cause_actions[] = { 6601 { 0xffffffff, -1, pmtx_dump_dbg_stats }, 6602 { 0 }, 6603 }; 6604 struct intr_info pmtx_int_cause = { 6605 .name = "PM_TX_INT_CAUSE", 6606 .cause_reg = A_PM_TX_INT_CAUSE, 6607 .enable_reg = A_PM_TX_INT_ENABLE, 6608 .fatal = 0xffffffff, 6609 .flags = IHF_CLR_DELAYED, 6610 .details = NULL, 6611 .actions = pmtx_int_cause_actions, 6612 }; 6613 #ifdef notyet 6614 static const struct intr_details pmtx_perr_cause_details[] = { 6615 { F_ICSPI_OVFL, "icspi FIFO Overflow" }, 6616 { F_OSPI_OVERFLOW3_TX, " OSPI overflow on channel 3 error." }, 6617 { F_OSPI_OVERFLOW2_TX, " OSPI overflow on channel 2 error." }, 6618 { F_OSPI_OVERFLOW1_TX, " OSPI overflow on channel 1 error." }, 6619 { F_OSPI_OVERFLOW0_TX, " OSPI overflow on channel 0 error." }, 6620 { F_T7_BUNDLE_LEN_OVFL_EN, "This bit indicates bundle_len_ovfl_err." }, 6621 { F_T7_M_INTFPERREN, "This bit indicates Parity error from MA interfaces." }, 6622 { F_T7_1_SDC_ERR, 6623 "SDC Error reported by Check PCMD which carries CRC16 from TP-CSide." }, 6624 { F_MC_WCNT_FIFO_PERR, "MC Interface Write count FIFO Parity error" }, 6625 { F_MC_WDATA_FIFO_PERR, "MC Interface Write Data FIFO Parity error" }, 6626 { F_MC_RCNT_FIFO_PERR, "MC Interface Read count FIFO Parity error" }, 6627 { F_MC_RDATA_FIFO_PERR, "MC Interface Read Data FIFO Parity error" }, 6628 { F_TOKEN_PAR_ERROR, "c_pcmd, Token FIFO par error" }, 6629 { F_BUNDLE_LEN_PAR_ERROR, "oespi par error" }, 6630 { F_OESPI_PAR_ERROR, "oespi par error" }, 6631 { F_DB_OPTIONS_PAR_ERROR, "db_options par error" }, 6632 { F_ICSPI_PAR_ERROR, "icspi par error" }, 6633 { F_C_PCMD_TOKEN_PAR_ERROR, "c_pcmd par error" }, 6634 { 0 } 6635 }; 6636 static struct intr_info pmtx_perr_cause = { 6637 .name = "PM_TX_PERR_CAUSE", 6638 .cause_reg = A_PM_TX_PERR_CAUSE, 6639 .enable_reg = A_PM_TX_PERR_ENABLE, 6640 .fatal = 0xffffffff, 6641 .flags = 0, 6642 .details = pmtx_perr_cause_details, 6643 .actions = NULL, 6644 }; 6645 #endif 6646 bool fatal; 6647 6648 if (chip_id(adap) >= CHELSIO_T7) 6649 pmtx_int_cause.details = t7_pmtx_int_cause_fields; 6650 else 6651 pmtx_int_cause.details = pmtx_int_cause_fields; 6652 fatal = t4_handle_intr(adap, &pmtx_int_cause, 0, flags); 6653 #ifdef notyet 6654 if (chip_id(adap) >= CHELSIO_T7) 6655 fatal |= t4_handle_intr(adap, &pmtx_perr_cause, 0, flags); 6656 #endif 6657 clear_int_cause_reg(adap, &pmtx_int_cause, flags); 6658 6659 return (fatal); 6660 } 6661 6662 /* 6663 * PM RX interrupt handler. 6664 */ 6665 static bool pmrx_intr_handler(struct adapter *adap, int arg, int flags) 6666 { 6667 static const struct intr_details t7_pmrx_int_cause_fields[] = { 6668 { F_MASTER_PERR, "PM_RX master parity error" }, 6669 { 0x18000000, "PMRX ospi overflow" }, 6670 { F_BUNDLE_LEN_OVFL, "PMRX bundle len FIFO overflow" }, 6671 { F_SDC_ERR, "PMRX SDC error" }, 6672 { F_ZERO_E_CMD_ERROR, "PMRX 0-length pcmd" }, 6673 { 0x003c0000, "PMRX iespi FIFO2X Rx framing error" }, 6674 { 0x0003c000, "PMRX iespi Rx framing error" }, 6675 { 0x00003c00, "PMRX iespi Tx framing error" }, 6676 { 0x00000300, "PMRX ocspi Rx framing error" }, 6677 { 0x000000c0, "PMRX ocspi Tx framing error" }, 6678 { 0x00000030, "PMRX ocspi FIFO2X Tx framing error" }, 6679 { 0 } 6680 }; 6681 static const struct intr_details pmrx_int_cause_fields[] = { 6682 /* T6+ */ 6683 { 0x18000000, "PMRX ospi overflow" }, 6684 { F_MA_INTF_SDC_ERR, "PMRX MA interface SDC parity error" }, 6685 { F_BUNDLE_LEN_PARERR, "PMRX bundle len FIFO parity error" }, 6686 { F_BUNDLE_LEN_OVFL, "PMRX bundle len FIFO overflow" }, 6687 { F_SDC_ERR, "PMRX SDC error" }, 6688 6689 /* T4+ */ 6690 { F_ZERO_E_CMD_ERROR, "PMRX 0-length pcmd" }, 6691 { 0x003c0000, "PMRX iespi FIFO2X Rx framing error" }, 6692 { 0x0003c000, "PMRX iespi Rx framing error" }, 6693 { 0x00003c00, "PMRX iespi Tx framing error" }, 6694 { 0x00000300, "PMRX ocspi Rx framing error" }, 6695 { 0x000000c0, "PMRX ocspi Tx framing error" }, 6696 { 0x00000030, "PMRX ocspi FIFO2X Tx framing error" }, 6697 { F_OCSPI_PAR_ERROR, "PMRX ocspi parity error" }, 6698 { F_DB_OPTIONS_PAR_ERROR, "PMRX db_options parity error" }, 6699 { F_IESPI_PAR_ERROR, "PMRX iespi parity error" }, 6700 { F_E_PCMD_PAR_ERROR, "PMRX e_pcmd parity error"}, 6701 { 0 } 6702 }; 6703 struct intr_info pmrx_int_cause = { 6704 .name = "PM_RX_INT_CAUSE", 6705 .cause_reg = A_PM_RX_INT_CAUSE, 6706 .enable_reg = A_PM_RX_INT_ENABLE, 6707 .fatal = 0x1fffffff, 6708 .flags = IHF_FATAL_IFF_ENABLED | IHF_CLR_DELAYED, 6709 .details = NULL, 6710 .actions = NULL, 6711 }; 6712 #ifdef notyet 6713 static const struct intr_details pm_rx_int_cause_2_details[] = { 6714 { F_CACHE_SRAM_ODD_CERR, "Cache Data Odd SRAM Correctable Error" }, 6715 { F_CACHE_SRAM_EVEN_CERR, "Cache Data Even SRAM Correctable Error" }, 6716 { F_CACHE_LRU_LEFT_CERR, "Cache LRU Left SRAM Correctable Error" }, 6717 { F_CACHE_LRU_RIGHT_CERR, "Cache LRU Right SRAM Correctable Error" }, 6718 { F_CACHE_ISLAND_CERR, "Cache Island SRAM Correctable Error" }, 6719 { F_OCSPI_CERR, "ocspi FIFO Correctable Error" }, 6720 { F_IESPI_CERR, "iespi FIFO Correctable Error" }, 6721 { F_OCSPI2_RX_FRAMING_ERROR, "ocspi FIFO channel 2 Rx/wr framing error" }, 6722 { F_OCSPI3_RX_FRAMING_ERROR, "ocspi FIFO channel 3 Rx/wr framing error" }, 6723 { F_OCSPI2_TX_FRAMING_ERROR, "ocspi FIFO channel 2 Tx/rd framing error" }, 6724 { F_OCSPI3_TX_FRAMING_ERROR, "ocspi FIFO channel 3 Tx/rd framing error" }, 6725 { F_OCSPI2_OFIFO2X_TX_FRAMING_ERROR, "ocspi 2x FIFO 2 Tx/rd framing error" }, 6726 { F_OCSPI3_OFIFO2X_TX_FRAMING_ERROR, "ocspi 2x FIFO 3 Tx/rd framing error" }, 6727 { 0 } 6728 }; 6729 static struct intr_info pmrx_int_cause2 = { 6730 .name = "PM_RX_INT_CAUSE_2", 6731 .cause_reg = A_PM_RX_INT_CAUSE_2, 6732 .enable_reg = A_PM_RX_INT_ENABLE_2, 6733 .fatal = 0x1fffffff, 6734 .flags = IHF_FATAL_IFF_ENABLED, 6735 .details = pm_rx_int_cause_2_details, 6736 .actions = NULL, 6737 }; 6738 static const struct intr_details pm_rx_perr_cause_details[] = { 6739 { F_T7_SDC_ERR, "SDC error. CRC provided by TP and PM didn't match." }, 6740 { F_T7_MA_INTF_SDC_ERR, "MA intf SDC perr" }, 6741 { F_E_PCMD_PERR, "ulp_rx 2 pm_rx PCMD interface parity error." }, 6742 { F_CACHE_RSP_DFIFO_PERR, "Cache Response Data FIFO Parity error" }, 6743 { F_CACHE_SRAM_ODD_PERR, "Cache Odd SRAM error" }, 6744 { F_CACHE_SRAM_EVEN_PERR, "Cache Even SRAM error" }, 6745 { F_CACHE_RSVD_PERR, "Cache Reserved Parity error" }, 6746 { F_CACHE_LRU_LEFT_PERR, "Cache LRU Left SRAM error" }, 6747 { F_CACHE_LRU_RIGHT_PERR, "Cache LRU Rigth SRAM error" }, 6748 { F_CACHE_RSP_CMD_PERR, "Cache Response Command FIFO error" }, 6749 { F_CACHE_SRAM_CMD_PERR, "Cache SRAM Command FIFO error" }, 6750 { F_CACHE_MA_CMD_PERR, "Cache MA Command FIFO error" }, 6751 { F_CACHE_TCAM_PERR, "Cache TCAM Parity error" }, 6752 { F_CACHE_ISLAND_PERR, "Cache island SRAM Parity error" }, 6753 { F_MC_WCNT_FIFO_PERR, "MC Interface Write count FIFO Parity error" }, 6754 { F_MC_WDATA_FIFO_PERR, "MC Interface Write Data FIFO Parity error" }, 6755 { F_MC_RCNT_FIFO_PERR, "MC Interface Read count FIFO Parity error" }, 6756 { F_MC_RDATA_FIFO_PERR, "MC Interface Read Data FIFO Parity error" }, 6757 { F_TOKEN_FIFO_PERR, "Token FIFO Parity error" }, 6758 { F_T7_BUNDLE_LEN_PARERR, "Bundle len fifo had parity error." }, 6759 { F_OCSPI_PAR_ERROR, "ocspi par error vector" }, 6760 { F_DB_OPTIONS_PAR_ERROR, "db_options par error" }, 6761 { F_IESPI_PAR_ERROR, "iespi par error" }, 6762 { F_E_PCMD_PAR_ERROR, "e_pcmd par error" }, 6763 { 0 } 6764 }; 6765 static struct intr_info pmrx_perr_cause = { 6766 .name = "PM_RX_PERR_CAUSE", 6767 .cause_reg = A_PM_RX_PERR_CAUSE, 6768 .enable_reg = A_PM_RX_PERR_ENABLE, 6769 .fatal = 0x1fffffff, 6770 .flags = IHF_FATAL_IFF_ENABLED, 6771 .details = pm_rx_perr_cause_details, 6772 .actions = NULL, 6773 }; 6774 #endif 6775 bool fatal; 6776 6777 if (chip_id(adap) >= CHELSIO_T7) { 6778 pmrx_int_cause.details = t7_pmrx_int_cause_fields; 6779 fatal = t4_handle_intr(adap, &pmrx_int_cause, 0, flags); 6780 #ifdef notyet 6781 fatal |= t4_handle_intr(adap, &pmrx_int_cause2, 0, flags); 6782 fatal |= t4_handle_intr(adap, &pmrx_perr_cause, 0, flags); 6783 #endif 6784 } else { 6785 pmrx_int_cause.details = pmrx_int_cause_fields; 6786 fatal = t4_handle_intr(adap, &pmrx_int_cause, 0, flags); 6787 } 6788 clear_int_cause_reg(adap, &pmrx_int_cause, flags); 6789 6790 return (fatal); 6791 } 6792 6793 /* 6794 * CPL switch interrupt handler. 6795 */ 6796 static bool cplsw_intr_handler(struct adapter *adap, int arg, int flags) 6797 { 6798 static const struct intr_details cplsw_int_cause_fields[] = { 6799 /* T7+ */ 6800 { F_PERR_CPL_128TO128_3, "CPLSW 128TO128 FIFO3 parity error" }, 6801 { F_PERR_CPL_128TO128_2, "CPLSW 128TO128 FIFO2 parity error" }, 6802 /* T5+ */ 6803 { F_PERR_CPL_128TO128_1, "CPLSW 128TO128 FIFO1 parity error" }, 6804 { F_PERR_CPL_128TO128_0, "CPLSW 128TO128 FIFO0 parity error" }, 6805 6806 /* T4+ */ 6807 { F_CIM_OP_MAP_PERR, "CPLSW CIM op_map parity error" }, 6808 { F_CIM_OVFL_ERROR, "CPLSW CIM overflow" }, 6809 { F_TP_FRAMING_ERROR, "CPLSW TP framing error" }, 6810 { F_SGE_FRAMING_ERROR, "CPLSW SGE framing error" }, 6811 { F_CIM_FRAMING_ERROR, "CPLSW CIM framing error" }, 6812 { F_ZERO_SWITCH_ERROR, "CPLSW no-switch error" }, 6813 { 0 } 6814 }; 6815 static const struct intr_info cplsw_int_cause = { 6816 .name = "CPL_INTR_CAUSE", 6817 .cause_reg = A_CPL_INTR_CAUSE, 6818 .enable_reg = A_CPL_INTR_ENABLE, 6819 .fatal = 0xffffffff, 6820 .flags = IHF_FATAL_IFF_ENABLED, 6821 .details = cplsw_int_cause_fields, 6822 .actions = NULL, 6823 }; 6824 6825 return (t4_handle_intr(adap, &cplsw_int_cause, 0, flags)); 6826 } 6827 6828 #define T4_LE_FATAL_MASK (F_PARITYERR | F_UNKNOWNCMD | F_REQQPARERR) 6829 #define T5_LE_FATAL_MASK (T4_LE_FATAL_MASK | F_VFPARERR) 6830 #define T6_LE_PERRCRC_MASK (F_PIPELINEERR | F_CLIPTCAMACCFAIL | \ 6831 F_SRVSRAMACCFAIL | F_CLCAMCRCPARERR | F_CLCAMINTPERR | F_SSRAMINTPERR | \ 6832 F_SRVSRAMPERR | F_VFSRAMPERR | F_TCAMINTPERR | F_TCAMCRCERR | \ 6833 F_HASHTBLMEMACCERR | F_MAIFWRINTPERR | F_HASHTBLMEMCRCERR) 6834 #define T6_LE_FATAL_MASK (T6_LE_PERRCRC_MASK | F_T6_UNKNOWNCMD | \ 6835 F_TCAMACCFAIL | F_HASHTBLACCFAIL | F_CMDTIDERR | F_CMDPRSRINTERR | \ 6836 F_TOTCNTERR | F_CLCAMFIFOERR | F_CLIPSUBERR) 6837 #define T7_LE_FATAL_MASK (T6_LE_FATAL_MASK | F_CACHESRAMPERR | F_CACHEINTPERR) 6838 6839 /* 6840 * LE interrupt handler. 6841 */ 6842 static bool le_intr_handler(struct adapter *adap, int arg, int flags) 6843 { 6844 static const struct intr_details le_intr_details[] = { 6845 { F_REQQPARERR, "LE request queue parity error" }, 6846 { F_UNKNOWNCMD, "LE unknown command" }, 6847 { F_ACTRGNFULL, "LE active region full" }, 6848 { F_PARITYERR, "LE parity error" }, 6849 { F_LIPMISS, "LE LIP miss" }, 6850 { F_LIP0, "LE 0 LIP error" }, 6851 { 0 } 6852 }; 6853 static const struct intr_details t6_le_intr_details[] = { 6854 { F_CACHEINTPERR, "Parity error in cache module" }, 6855 { F_CACHESRAMPERR, "Parity error in data sram " }, 6856 { F_CLIPSUBERR, "LE CLIP CAM reverse substitution error" }, 6857 { F_CLCAMFIFOERR, "LE CLIP CAM internal FIFO error" }, 6858 { F_CTCAMINVLDENT, "Invalid IPv6 CLIP TCAM entry" }, 6859 { F_TCAMINVLDENT, "Invalid IPv6 TCAM entry" }, 6860 { F_TOTCNTERR, "LE total active < TCAM count" }, 6861 { F_CMDPRSRINTERR, "LE internal error in parser" }, 6862 { F_CMDTIDERR, "Incorrect tid in LE command" }, 6863 { F_T6_ACTRGNFULL, "LE active region full" }, 6864 { F_T6_ACTCNTIPV6TZERO, "LE IPv6 active open TCAM counter -ve" }, 6865 { F_T6_ACTCNTIPV4TZERO, "LE IPv4 active open TCAM counter -ve" }, 6866 { F_T6_ACTCNTIPV6ZERO, "LE IPv6 active open counter -ve" }, 6867 { F_T6_ACTCNTIPV4ZERO, "LE IPv4 active open counter -ve" }, 6868 { F_HASHTBLACCFAIL, "Hash table read error (proto conflict)" }, 6869 { F_TCAMACCFAIL, "LE TCAM access failure" }, 6870 { F_T6_UNKNOWNCMD, "LE unknown command" }, 6871 { F_T6_LIP0, "LE found 0 LIP during CLIP substitution" }, 6872 { F_T6_LIPMISS, "LE CLIP lookup miss" }, 6873 { T6_LE_PERRCRC_MASK, "LE parity/CRC error" }, 6874 { 0 } 6875 }; 6876 struct intr_info le_intr_info = { 6877 .name = "LE_DB_INT_CAUSE", 6878 .cause_reg = A_LE_DB_INT_CAUSE, 6879 .enable_reg = A_LE_DB_INT_ENABLE, 6880 .fatal = 0, 6881 .flags = IHF_FATAL_IFF_ENABLED, 6882 .details = NULL, 6883 .actions = NULL, 6884 }; 6885 6886 if (chip_id(adap) <= CHELSIO_T5) { 6887 le_intr_info.details = le_intr_details; 6888 le_intr_info.fatal = T5_LE_FATAL_MASK; 6889 } else { 6890 le_intr_info.details = t6_le_intr_details; 6891 if (chip_id(adap) < CHELSIO_T7) 6892 le_intr_info.fatal = T6_LE_FATAL_MASK; 6893 else 6894 le_intr_info.fatal = T7_LE_FATAL_MASK; 6895 } 6896 6897 return (t4_handle_intr(adap, &le_intr_info, 0, flags)); 6898 } 6899 6900 /* 6901 * MPS interrupt handler. 6902 */ 6903 static bool mps_intr_handler(struct adapter *adap, int arg, int flags) 6904 { 6905 static const struct intr_details mps_rx_perr_intr_details[] = { 6906 { 0xffffffff, "MPS Rx parity error" }, 6907 { 0 } 6908 }; 6909 static const struct intr_info mps_rx_perr_intr_info = { 6910 .name = "MPS_RX_PERR_INT_CAUSE", 6911 .cause_reg = A_MPS_RX_PERR_INT_CAUSE, 6912 .enable_reg = A_MPS_RX_PERR_INT_ENABLE, 6913 .fatal = 0xffffffff, 6914 .flags = IHF_FATAL_IFF_ENABLED, 6915 .details = mps_rx_perr_intr_details, 6916 .actions = NULL, 6917 }; 6918 static const struct intr_details mps_rx_func_intr_details[] = { 6919 { F_MTU_ERR3, "MTU error interrupt enable bit for loopback group 3" }, 6920 { F_MTU_ERR2, "MTU error interrupt enable bit for loopback group 2" }, 6921 { F_MTU_ERR1, "MTU error interrupt enable bit for loopback group 1" }, 6922 { F_MTU_ERR0, "MTU error interrupt enable bit for loopback group 0" }, 6923 { F_DBG_LEN_ERR, "Oring of len error in traffic transfer b/w internal modules" }, 6924 { F_DBG_SPI_ERR, "Oring of spi error in traffic transfer b/w internal modules" }, 6925 { F_DBG_SE_CNT_ERR, "Oring of se cnt error in traffic transfer" }, 6926 { F_DBG_SPI_LEN_SE_CNT_ERR, "Oring of all se_cnt|len|spi errors" }, 6927 { 0 } 6928 }; 6929 static const struct intr_info mps_rx_func_intr_info = { 6930 .name = "MPS_RX_FUNC_INT_CAUSE", 6931 .cause_reg = A_MPS_RX_FUNC_INT_CAUSE, 6932 .enable_reg = A_MPS_RX_FUNC_INT_ENABLE, 6933 .fatal = 0xffffffff, 6934 .flags = IHF_FATAL_IFF_ENABLED, 6935 .details = mps_rx_func_intr_details, 6936 .actions = NULL, 6937 }; 6938 static const struct intr_details mpsrx_int_cause_2_details[] = { 6939 { F_CRYPTO2MPS_RX0_PERR | F_CRYPTO2MPS_RX1_PERR | 6940 F_CRYPTO2MPS_RX2_PERR | F_CRYPTO2MPS_RX3_PERR, 6941 "Crypto to MPS RX interface parity error" }, 6942 { F_INIC2MPS_TX1_PERR | F_INIC2MPS_TX0_PERR, 6943 "INIC to MPS TX interface parity error" }, 6944 { F_XGMAC2MPS_RX1_PERR | F_XGMAC2MPS_RX0_PERR, 6945 "XGMAC to MPS RX interface parity error" }, 6946 { F_RX_FINAL_TF_FIFO_PERR, 6947 "Final RX token FIFO output parity error" }, 6948 { F_MPS_DWRR_FIFO_PERR, 6949 "MPS DWRR MTU FIFO parity error" }, 6950 { F_MAC_TF_FIFO_PERR, 6951 "MAC token FIFO parity error" }, 6952 { F_MAC2MPS_PT3_PERR | F_MAC2MPS_PT2_PERR | 6953 F_MAC2MPS_PT1_PERR | F_MAC2MPS_PT0_PERR, 6954 "MAC to MPS interface parity error" }, 6955 { F_TP_LPBK_FIFO_PERR, "TP loopback FIFO parity error" }, 6956 { F_TP_LPBK_TF_PERR, "Loopback token FIFO parity error" }, 6957 { 0 } 6958 }; 6959 static const struct intr_info mps_rx_perr_intr_info2 = { 6960 .name = "MPS_RX_PERR_INT_CAUSE2", 6961 .cause_reg = A_MPS_RX_PERR_INT_CAUSE2, 6962 .enable_reg = A_MPS_RX_PERR_INT_ENABLE2, 6963 .fatal = 0xffffffff, 6964 .flags = IHF_FATAL_IFF_ENABLED, 6965 .details = mpsrx_int_cause_2_details, 6966 .actions = NULL, 6967 }; 6968 static const struct intr_details mpsrx_int_cause_3_details[] = { 6969 { F_FIFO_REPL_CH3_CERR | F_FIFO_REPL_CH2_CERR | 6970 F_FIFO_REPL_CH1_CERR | F_FIFO_REPL_CH0_CERR, 6971 "Replication FIFO ECC error" }, 6972 { F_VLAN_FILTER_RAM_CERR, "VLAN filter SRAM ECC error" }, 6973 { F_MPS_RX_TD_STAT_FIFO_PERR_CH3 | F_MPS_RX_TD_STAT_FIFO_PERR_CH2 | 6974 F_MPS_RX_TD_STAT_FIFO_PERR_CH1 | F_MPS_RX_TD_STAT_FIFO_PERR_CH0, 6975 "MPS RX TD status descriptor FIFO parity error" }, 6976 { F_RPLCT_HDR_FIFO_IN_PERR_CH3 | F_RPLCT_HDR_FIFO_IN_PERR_CH2 | 6977 F_RPLCT_HDR_FIFO_IN_PERR_CH1 | F_RPLCT_HDR_FIFO_IN_PERR_CH0, 6978 "MPS RX replication header input FIFO parity error" }, 6979 { F_ID_FIFO_IN_PERR_CH3 | F_ID_FIFO_IN_PERR_CH2 | 6980 F_ID_FIFO_IN_PERR_CH1 | F_ID_FIFO_IN_PERR_CH0, 6981 "MPS RX replication ID input FIFO parity error" }, 6982 { F_DESC_HDR2_PERR_CH3 | F_DESC_HDR2_PERR_CH2 | 6983 F_DESC_HDR2_PERR_CH1 | F_DESC_HDR2_PERR_CH0, 6984 "MPS RX replication descriptor/header2 FIFO parity error" }, 6985 { F_FIFO_REPL_PERR_CH3 | F_FIFO_REPL_PERR_CH2 | 6986 F_FIFO_REPL_PERR_CH1 | F_FIFO_REPL_PERR_CH0, 6987 "Replication FIFO parity error" }, 6988 { F_MPS_RX_TD_PERR_CH3 | F_MPS_RX_TD_PERR_CH2 | 6989 F_MPS_RX_TD_PERR_CH1 | F_MPS_RX_TD_PERR_CH0, 6990 "MPS RX TD input FIFO parity error" }, 6991 { 0 } 6992 }; 6993 static const struct intr_info mps_rx_perr_intr_info3 = { 6994 .name = "MPS_RX_PERR_INT_CAUSE3", 6995 .cause_reg = A_MPS_RX_PERR_INT_CAUSE3, 6996 .enable_reg = A_MPS_RX_PERR_INT_ENABLE3, 6997 .fatal = 0xffffffff, 6998 .flags = IHF_FATAL_IFF_ENABLED, 6999 .details = mpsrx_int_cause_3_details, 7000 .actions = NULL, 7001 }; 7002 static const struct intr_details mpsrx_int_cause_4_details[] = { 7003 { F_VNI_MULTICAST_FIFO_ECC_ERR_CH3 | F_VNI_MULTICAST_FIFO_ECC_ERR_CH2, 7004 "RX out VNI multicast SRAM ECC error" }, 7005 { F_HASH_SRAM_CLS_ENG1 | F_HASH_SRAM_CLS_ENG0, 7006 "Classification engine hash SRAM ECC error" }, 7007 { F_CLS_TCAM_SRAM_CLS_ENG1 | F_CLS_TCAM_SRAM_CLS_ENG0, 7008 "Classification engine TCAM SRAM ECC error" }, 7009 { F_CLS_TCAM_CRC_SRAM_CLS_ENG1 | F_CLS_TCAM_CRC_SRAM_CLS_ENG0, 7010 "Classification engine TCAM CRC SRAM ECC error" }, 7011 { F_DWRR_CH_FIFO_ECC_ERR, "DWRR output FIFO ECC error" }, 7012 { F_MAC_RX_FIFO_ECC_ERR, "MAC RX FIFO ECC error" }, 7013 { F_LPBK_RX_FIFO_ECC_ERR, "Loopback RX FIFO ECC error" }, 7014 { F_CRS_DATA_STORE_N_FWD_CH3 | F_CRS_DATA_STORE_N_FWD_CH2 | 7015 F_CRS_DATA_STORE_N_FWD_CH1 | F_CRS_DATA_STORE_N_FWD_CH0, 7016 "CRS store and forward FIFO ECC error" }, 7017 { F_TRACE_FWD_FIFO_CERR_CH3 | F_TRACE_FWD_FIFO_CERR_CH2 | 7018 F_TRACE_FWD_FIFO_CERR_CH1 | F_TRACE_FWD_FIFO_CERR_CH0, 7019 "Trace packet forward FIFO ECC error" }, 7020 { F_TRANSPARENT_ENCAP_FWD_FIFO_CERR_CH3 | F_TRANSPARENT_ENCAP_FWD_FIFO_CERR_CH2 | 7021 F_TRANSPARENT_ENCAP_FWD_FIFO_CERR_CH1 | F_TRANSPARENT_ENCAP_FWD_FIFO_CERR_CH0, 7022 "Transparent encap forward FIFO ECC error" }, 7023 { F_PTP_TRACE_FWD_FIFO_CERR_CH3 | F_PTP_TRACE_FWD_FIFO_CERR_CH2 | 7024 F_PTP_TRACE_FWD_FIFO_CERR_CH1 | F_PTP_TRACE_FWD_FIFO_CERR_CH0, 7025 "PTP packet forward FIFO ECC error" }, 7026 { 0 } 7027 }; 7028 static const struct intr_info mps_rx_perr_intr_info4 = { 7029 .name = "MPS_RX_PERR_INT_CAUSE4", 7030 .cause_reg = A_MPS_RX_PERR_INT_CAUSE4, 7031 .enable_reg = A_MPS_RX_PERR_INT_ENABLE4, 7032 .fatal = 0xffffffff, 7033 .flags = IHF_FATAL_IFF_ENABLED, 7034 .details = mpsrx_int_cause_4_details, 7035 .actions = NULL, 7036 }; 7037 static const struct intr_details mpsrx_int_cause_5_details[] = { 7038 { F_MPS2CRYP_RX_FIFO3_PERR | F_MPS2CRYP_RX_FIFO2_PERR | 7039 F_MPS2CRYP_RX_FIFO1_PERR | F_MPS2CRYP_RX_FIFO0_PERR, 7040 "MPS to Crypto RX interface FIFO parity error" }, 7041 { F_VNI_MULTICAST_SRAM2_PERR | F_VNI_MULTICAST_SRAM1_PERR | 7042 F_VNI_MULTICAST_SRAM0_PERR, 7043 "VNI multicast SRAM parity error" }, 7044 { F_MAC_MULTICAST_SRAM4_PERR | F_MAC_MULTICAST_SRAM3_PERR | 7045 F_MAC_MULTICAST_SRAM2_PERR | F_MAC_MULTICAST_SRAM1_PERR | 7046 F_MAC_MULTICAST_SRAM0_PERR, 7047 "MAC multicast SRAM parity error" }, 7048 { F_MEM_WRAP_IPSEC_HDR_UPD_FIFO3_PERR | F_MEM_WRAP_IPSEC_HDR_UPD_FIFO2_PERR | 7049 F_MEM_WRAP_IPSEC_HDR_UPD_FIFO1_PERR | F_MEM_WRAP_IPSEC_HDR_UPD_FIFO0_PERR, 7050 "IPsec header update storing FIFO parity error" }, 7051 { F_MEM_WRAP_CR2MPS_RX_FIFO3_PERR | F_MEM_WRAP_CR2MPS_RX_FIFO2_PERR | 7052 F_MEM_WRAP_CR2MPS_RX_FIFO1_PERR | F_MEM_WRAP_CR2MPS_RX_FIFO0_PERR, 7053 "IPsec storing FIFO parity error" }, 7054 { F_MEM_WRAP_NON_IPSEC_FIFO3_PERR | F_MEM_WRAP_NON_IPSEC_FIFO2_PERR | 7055 F_MEM_WRAP_NON_IPSEC_FIFO1_PERR | F_MEM_WRAP_NON_IPSEC_FIFO0_PERR, 7056 "Non-IPsec storing FIFO parity error" }, 7057 { F_MEM_WRAP_TP_DB_REQ_FIFO3_PERR | F_MEM_WRAP_TP_DB_REQ_FIFO2_PERR | 7058 F_MEM_WRAP_TP_DB_REQ_FIFO1_PERR | F_MEM_WRAP_TP_DB_REQ_FIFO0_PERR, 7059 "TP DB request storing FIFO parity error" }, 7060 { F_MEM_WRAP_CNTRL_FIFO3_PERR | F_MEM_WRAP_CNTRL_FIFO2_PERR | 7061 F_MEM_WRAP_CNTRL_FIFO1_PERR | F_MEM_WRAP_CNTRL_FIFO0_PERR, 7062 "Header flit storing FIFO parity error" }, 7063 { 0 } 7064 }; 7065 static const struct intr_info mps_rx_perr_intr_info5 = { 7066 .name = "MPS_RX_PERR_INT_CAUSE5", 7067 .cause_reg = A_MPS_RX_PERR_INT_CAUSE5, 7068 .enable_reg = A_MPS_RX_PERR_INT_ENABLE5, 7069 .fatal = 0xffffffff, 7070 .flags = IHF_FATAL_IFF_ENABLED, 7071 .details = mpsrx_int_cause_5_details, 7072 .actions = NULL, 7073 }; 7074 static const struct intr_details mpsrx_int_cause_6_details[] = { 7075 { F_T7_MEM_WRAP_IPSEC_HDR_UPD_FIFO3_PERR | F_T7_MEM_WRAP_IPSEC_HDR_UPD_FIFO2_PERR | 7076 F_T7_MEM_WRAP_IPSEC_HDR_UPD_FIFO1_PERR | F_T7_MEM_WRAP_IPSEC_HDR_UPD_FIFO0_PERR, 7077 "IPsec header update storing FIFO parity error" }, 7078 { F_MEM_WRAP_CR2MPS_UPDTD_HDR_FIFO3_PERR | F_MEM_WRAP_CR2MPS_UPDTD_HDR_FIFO2_PERR | 7079 F_MEM_WRAP_CR2MPS_UPDTD_HDR_FIFO1_PERR | F_MEM_WRAP_CR2MPS_UPDTD_HDR_FIFO0_PERR, 7080 "IPsec updated header only storing FIFO parity error" }, 7081 { F_MEM_WRAP_CR2MPS_RX_FIFO3_PERR | F_MEM_WRAP_CR2MPS_RX_FIFO2_PERR | 7082 F_MEM_WRAP_CR2MPS_RX_FIFO1_PERR | F_MEM_WRAP_CR2MPS_RX_FIFO0_PERR, 7083 "IPsec storing FIFO parity error" }, 7084 { F_MEM_WRAP_NON_IPSEC_FIFO3_PERR | F_MEM_WRAP_NON_IPSEC_FIFO2_PERR | 7085 F_MEM_WRAP_NON_IPSEC_FIFO1_PERR | F_MEM_WRAP_NON_IPSEC_FIFO0_PERR, 7086 "Non-IPsec storing FIFO parity error" }, 7087 { F_MEM_WRAP_TP_DB_REQ_FIFO3_PERR | F_MEM_WRAP_TP_DB_REQ_FIFO2_PERR | 7088 F_MEM_WRAP_TP_DB_REQ_FIFO1_PERR | F_MEM_WRAP_TP_DB_REQ_FIFO0_PERR, 7089 "TP DB request storing FIFO parity error" }, 7090 { F_MEM_WRAP_CNTRL_FIFO3_PERR | F_MEM_WRAP_CNTRL_FIFO2_PERR | 7091 F_MEM_WRAP_CNTRL_FIFO1_PERR | F_MEM_WRAP_CNTRL_FIFO0_PERR, 7092 "Header flit storing FIFO parity error" }, 7093 { 0 } 7094 }; 7095 static const struct intr_info mps_rx_perr_intr_info6 = { 7096 .name = "MPS_RX_PERR_INT_CAUSE6", 7097 .cause_reg = A_MPS_RX_PERR_INT_CAUSE6, 7098 .enable_reg = A_MPS_RX_PERR_INT_ENABLE6, 7099 .fatal = 0xffffffff, 7100 .flags = IHF_FATAL_IFF_ENABLED, 7101 .details = mpsrx_int_cause_6_details, 7102 .actions = NULL, 7103 }; 7104 static const struct intr_details t7_mpstx_int_cause_details[] = { 7105 { F_T7_PORTERR, "Tx received a frame for TP destined to a disable port" }, 7106 { F_T7_FRMERR, "Framing error in received Data from TP or Data to MAC" }, 7107 { F_T7_SECNTERR, "SOP-EOP count error in received Data from TP or Data to MAC" }, 7108 { F_T7_BUBBLE, "Valid is deasserted between SOP and EOP" }, 7109 { F_TX_TF_FIFO_PERR, "Parity error of TX token fifo" }, 7110 { F_TX_FIFO_PERR, "Parity error of TX MPS2MAC underrun fifo" }, 7111 { 0x0003c000, "Parity error of fifo storing non-ipsec +1 flit ipsec pkt" }, 7112 { 0x00003fc0, "Interface parity error on TP/Crypto to MPS TX" }, 7113 { F_NCSI2MPS, "interface Parity Error on ncsi2mps_tx_ch3" }, 7114 { F_NCSIFIFO, "Parity Error in mps_tx_arbiter input FIFO (from NCSI)" }, 7115 { 0x0000000f, "Parity Error in mps_tx_arbiter input FIFO (from TP)" }, 7116 { 0 } 7117 }; 7118 static const struct intr_details mps_tx_intr_details[] = { 7119 { F_PORTERR, "MPS Tx destination port is disabled" }, 7120 { F_FRMERR, "MPS Tx framing error" }, 7121 { F_SECNTERR, "MPS Tx SOP/EOP error" }, 7122 { F_BUBBLE, "MPS Tx underflow" }, 7123 { V_TXDESCFIFO(M_TXDESCFIFO), "MPS Tx desc FIFO parity error" }, 7124 { V_TXDATAFIFO(M_TXDATAFIFO), "MPS Tx data FIFO parity error" }, 7125 { F_NCSIFIFO, "MPS Tx NC-SI FIFO parity error" }, 7126 { V_TPFIFO(M_TPFIFO), "MPS Tx TP FIFO parity error" }, 7127 { 0 } 7128 }; 7129 struct intr_info mps_tx_intr_info = { 7130 .name = "MPS_TX_INT_CAUSE", 7131 .cause_reg = A_MPS_TX_INT_CAUSE, 7132 .enable_reg = A_MPS_TX_INT_ENABLE, 7133 .fatal = 0x1ffff, 7134 .flags = IHF_FATAL_IFF_ENABLED, 7135 .details = NULL, 7136 .actions = NULL, 7137 }; 7138 static const struct intr_details mpstx_int_cause_2_details[] = { 7139 { F_TX_FIFO_PERR, "ECC error of TX MPS2MAC underrun fifo" }, 7140 { 0x0000000f, "ECC error of fifo storing non-ipsec +1 flit ipsec pkt" }, 7141 { 0 } 7142 }; 7143 static const struct intr_info mps_tx_intr_info2 = { 7144 .name = "MPS_TX_INT2_CAUSE", 7145 .cause_reg = A_MPS_TX_INT2_CAUSE, 7146 .enable_reg = A_MPS_TX_INT2_ENABLE, 7147 .fatal = 0xffffffff, 7148 .flags = IHF_FATAL_IFF_ENABLED, 7149 .details = mpstx_int_cause_2_details, 7150 .actions = NULL, 7151 }; 7152 static const struct intr_info mps_tx_intr_info3 = { 7153 .name = "MPS_TX_INT3_CAUSE", 7154 .cause_reg = A_MPS_TX_INT3_CAUSE, 7155 .enable_reg = A_MPS_TX_INT3_ENABLE, 7156 .fatal = 0xffffffff, 7157 .flags = IHF_FATAL_IFF_ENABLED, 7158 .details = NULL, 7159 .actions = NULL, 7160 }; 7161 static const struct intr_info mps_tx_intr_info4 = { 7162 .name = "MPS_TX_INT4_CAUSE", 7163 .cause_reg = A_MPS_TX_INT4_CAUSE, 7164 .enable_reg = A_MPS_TX_INT4_ENABLE, 7165 .fatal = 0xffffffff, 7166 .flags = IHF_FATAL_IFF_ENABLED, 7167 .details = NULL, 7168 .actions = NULL, 7169 }; 7170 static const struct intr_details mps_trc_intr_details[] = { 7171 { F_MISCPERR, "MPS TRC misc parity error" }, 7172 { V_PKTFIFO(M_PKTFIFO), "MPS TRC packet FIFO parity error" }, 7173 { V_FILTMEM(M_FILTMEM), "MPS TRC filter parity error" }, 7174 { 0 } 7175 }; 7176 static const struct intr_info mps_trc_intr_info = { 7177 .name = "MPS_TRC_INT_CAUSE", 7178 .cause_reg = A_MPS_TRC_INT_CAUSE, 7179 .enable_reg = A_MPS_TRC_INT_ENABLE, 7180 .fatal = F_MISCPERR | V_PKTFIFO(M_PKTFIFO) | V_FILTMEM(M_FILTMEM), 7181 .flags = 0, 7182 .details = mps_trc_intr_details, 7183 .actions = NULL, 7184 }; 7185 static const struct intr_details t7_mps_trc_intr_details[] = { 7186 { F_T7_TRCPLERRENB, "TRC PL error" }, 7187 { F_T7_MISCPERR, "TRC header register parity error" }, 7188 { 0x0000ff00, "TRC packet FIFO parity error" }, 7189 { 0x000000ff, "TRC filter memory parity error" }, 7190 { 0 } 7191 }; 7192 static const struct intr_info t7_mps_trc_intr_info = { 7193 .name = "MPS_TRC_INT_CAUSE", 7194 .cause_reg = A_T7_MPS_TRC_INT_CAUSE, 7195 .enable_reg = A_T7_MPS_TRC_INT_ENABLE, 7196 .fatal = 0xffffffff, 7197 .flags = IHF_FATAL_IFF_ENABLED, 7198 .details = t7_mps_trc_intr_details, 7199 .actions = NULL, 7200 }; 7201 static const struct intr_details t7_trc_int_cause2_details[] = { 7202 { 0x0001e000, "TRC Tx2Rx down-converter correctable error" }, 7203 { 0x00001800, "TRC MPS2MAC down-converter correctable error" }, 7204 { 0x00000600, "TRC MAC2MPS down-converter correctable error" }, 7205 { 0x000001e0, "TRC Tx2Rx down-converter parity error" }, 7206 { 0x00000018, "TRC MAC2MPS down-converter parity error" }, 7207 { 0x00000006, "TRC MPS2MAC down-converter parity error" }, 7208 { 0 } 7209 }; 7210 static const struct intr_info t7_mps_trc_intr_info2 = { 7211 .name = "MPS_TRC_INT_CAUSE2", 7212 .cause_reg = A_MPS_TRC_INT_CAUSE2, 7213 .enable_reg = A_MPS_TRC_INT_ENABLE2, 7214 .fatal = 0xffffffff, 7215 .flags = IHF_FATAL_IFF_ENABLED, 7216 .details = t7_trc_int_cause2_details, 7217 .actions = NULL, 7218 }; 7219 static const struct intr_details mps_stat_intr_details[] = { 7220 { F_PLREADSYNCERR, "MPS pl read sync error" }, 7221 { 0 } 7222 }; 7223 static const struct intr_info mps_stat_intr_info = { 7224 .name = "MPS_STAT_INT_CAUSE", 7225 .cause_reg = A_MPS_STAT_INT_CAUSE, 7226 .enable_reg = A_MPS_STAT_INT_ENABLE, 7227 .fatal = 0xf, 7228 .flags = IHF_FATAL_IFF_ENABLED, 7229 .details = mps_stat_intr_details, 7230 .actions = NULL, 7231 }; 7232 static const struct intr_details mps_stat_sram_intr_details[] = { 7233 { 0xffffffff, "MPS statistics SRAM parity error" }, 7234 { 0 } 7235 }; 7236 static const struct intr_info mps_stat_sram_intr_info = { 7237 .name = "MPS_STAT_PERR_INT_CAUSE_SRAM", 7238 .cause_reg = A_MPS_STAT_PERR_INT_CAUSE_SRAM, 7239 .enable_reg = A_MPS_STAT_PERR_INT_ENABLE_SRAM, 7240 .fatal = 0x1fffffff, 7241 .flags = IHF_FATAL_IFF_ENABLED, 7242 .details = mps_stat_sram_intr_details, 7243 .actions = NULL, 7244 }; 7245 static const struct intr_details mps_stat_tx_intr_details[] = { 7246 { 0xffffff, "MPS statistics Tx FIFO parity error" }, 7247 { 0 } 7248 }; 7249 static const struct intr_info mps_stat_tx_intr_info = { 7250 .name = "MPS_STAT_PERR_INT_CAUSE_TX_FIFO", 7251 .cause_reg = A_MPS_STAT_PERR_INT_CAUSE_TX_FIFO, 7252 .enable_reg = A_MPS_STAT_PERR_INT_ENABLE_TX_FIFO, 7253 .fatal = 0xffffff, 7254 .flags = IHF_FATAL_IFF_ENABLED, 7255 .details = mps_stat_tx_intr_details, 7256 .actions = NULL, 7257 }; 7258 static const struct intr_details mps_stat_rx_intr_details[] = { 7259 { 0xffffff, "MPS statistics Rx FIFO parity error" }, 7260 { 0 } 7261 }; 7262 static const struct intr_info mps_stat_rx_intr_info = { 7263 .name = "MPS_STAT_PERR_INT_CAUSE_RX_FIFO", 7264 .cause_reg = A_MPS_STAT_PERR_INT_CAUSE_RX_FIFO, 7265 .enable_reg = A_MPS_STAT_PERR_INT_ENABLE_RX_FIFO, 7266 .fatal = 0xffffff, 7267 .flags = 0, 7268 .details = mps_stat_rx_intr_details, 7269 .actions = NULL, 7270 }; 7271 static const struct intr_details mps_cls_intr_details[] = { 7272 { F_T7_PLERRENB, "PL error"}, 7273 { F_CIM2MPS_INTF_PAR, "cim2mps interface parity"}, 7274 { F_TCAM_CRC_SRAM, "tcam crc sram parity error"}, 7275 { F_HASHSRAM, "MPS hash SRAM parity error" }, 7276 { F_MATCHTCAM, "MPS match TCAM parity error" }, 7277 { F_MATCHSRAM, "MPS match SRAM parity error" }, 7278 { 0 } 7279 }; 7280 static const struct intr_info mps_cls_intr_info = { 7281 .name = "MPS_CLS_INT_CAUSE", 7282 .cause_reg = A_MPS_CLS_INT_CAUSE, 7283 .enable_reg = A_MPS_CLS_INT_ENABLE, 7284 .fatal = F_MATCHSRAM | F_MATCHTCAM | F_HASHSRAM, 7285 .flags = 0, 7286 .details = mps_cls_intr_details, 7287 .actions = NULL, 7288 }; 7289 static const struct intr_details mps_stat_sram1_intr_details[] = { 7290 { 0xff, "MPS statistics SRAM1 parity error" }, 7291 { 0 } 7292 }; 7293 static const struct intr_info mps_stat_sram1_intr_info = { 7294 .name = "MPS_STAT_PERR_INT_CAUSE_SRAM1", 7295 .cause_reg = A_MPS_STAT_PERR_INT_CAUSE_SRAM1, 7296 .enable_reg = A_MPS_STAT_PERR_INT_ENABLE_SRAM1, 7297 .fatal = 0xff, 7298 .flags = 0, 7299 .details = mps_stat_sram1_intr_details, 7300 .actions = NULL, 7301 }; 7302 bool fatal = false; 7303 if (chip_id(adap) >= CHELSIO_T7) 7304 mps_tx_intr_info.details = t7_mpstx_int_cause_details; 7305 else 7306 mps_tx_intr_info.details = mps_tx_intr_details; 7307 7308 fatal |= t4_handle_intr(adap, &mps_rx_perr_intr_info, 0, flags); 7309 if (chip_id(adap) > CHELSIO_T6) { 7310 fatal |= t4_handle_intr(adap, &mps_rx_func_intr_info, 0, flags); 7311 fatal |= t4_handle_intr(adap, &mps_rx_perr_intr_info2, 0, flags); 7312 fatal |= t4_handle_intr(adap, &mps_rx_perr_intr_info3, 0, flags); 7313 fatal |= t4_handle_intr(adap, &mps_rx_perr_intr_info4, 0, flags); 7314 fatal |= t4_handle_intr(adap, &mps_rx_perr_intr_info5, 0, flags); 7315 fatal |= t4_handle_intr(adap, &mps_rx_perr_intr_info6, 0, flags); 7316 } 7317 fatal |= t4_handle_intr(adap, &mps_tx_intr_info, 0, flags); 7318 if (chip_id(adap) > CHELSIO_T6) { 7319 fatal |= t4_handle_intr(adap, &mps_tx_intr_info2, 0, flags); 7320 fatal |= t4_handle_intr(adap, &mps_tx_intr_info3, 0, flags); 7321 fatal |= t4_handle_intr(adap, &mps_tx_intr_info4, 0, flags); 7322 fatal |= t4_handle_intr(adap, &t7_mps_trc_intr_info, 0, flags); 7323 fatal |= t4_handle_intr(adap, &t7_mps_trc_intr_info2, 0, flags); 7324 } else 7325 fatal |= t4_handle_intr(adap, &mps_trc_intr_info, 0, flags); 7326 fatal |= t4_handle_intr(adap, &mps_stat_intr_info, 0, flags); 7327 fatal |= t4_handle_intr(adap, &mps_stat_sram_intr_info, 0, flags); 7328 fatal |= t4_handle_intr(adap, &mps_stat_tx_intr_info, 0, flags); 7329 fatal |= t4_handle_intr(adap, &mps_stat_rx_intr_info, 0, flags); 7330 fatal |= t4_handle_intr(adap, &mps_cls_intr_info, 0, flags); 7331 if (chip_id(adap) > CHELSIO_T4) 7332 fatal |= t4_handle_intr(adap, &mps_stat_sram1_intr_info, 0, flags); 7333 7334 t4_write_reg(adap, A_MPS_INT_CAUSE, is_t4(adap) ? 0 : 0xffffffff); 7335 t4_read_reg(adap, A_MPS_INT_CAUSE); /* flush */ 7336 7337 return (fatal); 7338 } 7339 7340 /* 7341 * EDC/MC interrupt handler. 7342 */ 7343 static bool mem_intr_handler(struct adapter *adap, int idx, int flags) 7344 { 7345 static const char name[4][5] = { "EDC0", "EDC1", "MC0", "MC1" }; 7346 unsigned int count_reg = 0, v; 7347 static const struct intr_details mem_intr_details[] = { 7348 { F_ECC_UE_INT_CAUSE, "Uncorrectable ECC data error(s)" }, 7349 { F_ECC_CE_INT_CAUSE, "Correctable ECC data error(s)" }, 7350 { F_PERR_INT_CAUSE, "FIFO parity error" }, 7351 { 0 } 7352 }; 7353 static const struct intr_details t7_mem_intr_details[] = { 7354 { F_DDRPHY_INT_CAUSE, "DDR PHY" }, 7355 { F_DDRCTL_INT_CAUSE, "DDR Controller" }, 7356 { F_T7_ECC_UE_INT_CAUSE, "Uncorrectable ECC data error(s)" }, 7357 { F_T7_ECC_CE_INT_CAUSE, "Correctable ECC data error(s)" }, 7358 { F_PERR_INT_CAUSE, "FIFO parity error" }, 7359 { 0 } 7360 }; 7361 char rname[32]; 7362 struct intr_info ii = { 7363 .name = &rname[0], 7364 .fatal = F_PERR_INT_CAUSE | F_ECC_UE_INT_CAUSE, 7365 .flags = IHF_CLR_DELAYED, 7366 .details = mem_intr_details, 7367 .actions = NULL, 7368 }; 7369 bool fatal = false; 7370 int i = 0; 7371 7372 switch (idx) { 7373 case MEM_EDC1: i = 1; 7374 /* fall through */ 7375 case MEM_EDC0: 7376 snprintf(rname, sizeof(rname), "EDC%u_INT_CAUSE", i); 7377 if (is_t4(adap)) { 7378 ii.cause_reg = EDC_REG(A_EDC_INT_CAUSE, i); 7379 ii.enable_reg = EDC_REG(A_EDC_INT_ENABLE, i); 7380 count_reg = EDC_REG(A_EDC_ECC_STATUS, i); 7381 } else { 7382 ii.cause_reg = EDC_T5_REG(A_EDC_H_INT_CAUSE, i); 7383 ii.enable_reg = EDC_T5_REG(A_EDC_H_INT_ENABLE, i); 7384 count_reg = EDC_T5_REG(A_EDC_H_ECC_STATUS, i); 7385 } 7386 fatal |= t4_handle_intr(adap, &ii, 0, flags); 7387 break; 7388 case MEM_MC1: 7389 if (is_t4(adap) || is_t6(adap)) 7390 return (false); 7391 i = 1; 7392 /* fall through */ 7393 case MEM_MC0: 7394 snprintf(rname, sizeof(rname), "MC%u_INT_CAUSE", i); 7395 if (is_t4(adap)) { 7396 ii.cause_reg = A_MC_INT_CAUSE; 7397 ii.enable_reg = A_MC_INT_ENABLE; 7398 count_reg = A_MC_ECC_STATUS; 7399 } else if (chip_id(adap) < CHELSIO_T7) { 7400 ii.cause_reg = MC_REG(A_MC_P_INT_CAUSE, i); 7401 ii.enable_reg = MC_REG(A_MC_P_INT_ENABLE, i); 7402 count_reg = MC_REG(A_MC_P_ECC_STATUS, i); 7403 } else { 7404 ii.cause_reg = MC_T7_REG(A_T7_MC_P_INT_CAUSE, i); 7405 ii.enable_reg = MC_T7_REG(A_T7_MC_P_INT_ENABLE, i); 7406 ii.fatal = F_PERR_INT_CAUSE | F_T7_ECC_UE_INT_CAUSE; 7407 ii.details = t7_mem_intr_details; 7408 } 7409 fatal |= t4_handle_intr(adap, &ii, 0, flags); 7410 break; 7411 } 7412 7413 if (count_reg != 0) { 7414 v = t4_read_reg(adap, count_reg); 7415 if (v != 0) { 7416 if (G_ECC_UECNT(v) != 0 && !(flags & IHF_NO_SHOW)) { 7417 CH_ALERT(adap, 7418 " %s: %u uncorrectable ECC data error(s)\n", 7419 name[idx], G_ECC_UECNT(v)); 7420 } 7421 if (G_ECC_CECNT(v) != 0 && !(flags & IHF_NO_SHOW)) { 7422 if (idx <= MEM_EDC1) 7423 t4_edc_err_read(adap, idx); 7424 CH_WARN_RATELIMIT(adap, 7425 " %s: %u correctable ECC data error(s)\n", 7426 name[idx], G_ECC_CECNT(v)); 7427 } 7428 t4_write_reg(adap, count_reg, 0xffffffff); 7429 } 7430 } 7431 clear_int_cause_reg(adap, &ii, flags); 7432 return (fatal); 7433 } 7434 7435 static bool ma_wrap_status(struct adapter *adap, int arg, int flags) 7436 { 7437 u32 v; 7438 7439 v = t4_read_reg(adap, A_MA_INT_WRAP_STATUS); 7440 if (!(flags & IHF_NO_SHOW)) { 7441 CH_ALERT(adap, 7442 " MA address wrap-around by client %u to address %#x\n", 7443 G_MEM_WRAP_CLIENT_NUM(v), G_MEM_WRAP_ADDRESS(v) << 4); 7444 } 7445 t4_write_reg(adap, A_MA_INT_WRAP_STATUS, v); 7446 7447 return (false); 7448 } 7449 7450 /* 7451 * MA interrupt handler. 7452 */ 7453 static bool ma_intr_handler(struct adapter *adap, int arg, int flags) 7454 { 7455 static const struct intr_action ma_intr_actions[] = { 7456 { F_MEM_WRAP_INT_CAUSE, -1, ma_wrap_status }, 7457 { 0 }, 7458 }; 7459 static const struct intr_info ma_intr_info = { 7460 .name = "MA_INT_CAUSE", 7461 .cause_reg = A_MA_INT_CAUSE, 7462 .enable_reg = A_MA_INT_ENABLE, 7463 .fatal = F_MEM_PERR_INT_CAUSE | F_MEM_TO_INT_CAUSE, 7464 .flags = IHF_FATAL_IFF_ENABLED, 7465 .details = NULL, 7466 .actions = ma_intr_actions, 7467 }; 7468 static const struct intr_info ma_perr_status1 = { 7469 .name = "MA_PARITY_ERROR_STATUS1", 7470 .cause_reg = A_MA_PARITY_ERROR_STATUS1, 7471 .enable_reg = A_MA_PARITY_ERROR_ENABLE1, 7472 .fatal = 0xffffffff, 7473 .flags = 0, 7474 .details = NULL, 7475 .actions = NULL, 7476 }; 7477 static const struct intr_info ma_perr_status2 = { 7478 .name = "MA_PARITY_ERROR_STATUS2", 7479 .cause_reg = A_MA_PARITY_ERROR_STATUS2, 7480 .enable_reg = A_MA_PARITY_ERROR_ENABLE2, 7481 .fatal = 0xffffffff, 7482 .flags = 0, 7483 .details = NULL, 7484 .actions = NULL, 7485 }; 7486 bool fatal; 7487 7488 fatal = false; 7489 fatal |= t4_handle_intr(adap, &ma_intr_info, 0, flags); 7490 fatal |= t4_handle_intr(adap, &ma_perr_status1, 0, flags); 7491 if (chip_id(adap) > CHELSIO_T4) 7492 fatal |= t4_handle_intr(adap, &ma_perr_status2, 0, flags); 7493 7494 return (fatal); 7495 } 7496 7497 /* 7498 * SMB interrupt handler. 7499 */ 7500 static bool smb_intr_handler(struct adapter *adap, int arg, int flags) 7501 { 7502 static const struct intr_details smb_int_cause_details[] = { 7503 { F_MSTTXFIFOPARINT, "Master has Parity Error in Tx Fifo" }, 7504 { F_MSTRXFIFOPARINT, "Master has Parity Error in Rx Fifo" }, 7505 { F_SLVFIFOPARINT, "Slave has Parity Error in Fifo" }, 7506 { F_SLVUNEXPBUSSTOPINT, "Slave get Unexpected BusStop" }, 7507 { F_SLVUNEXPBUSSTARTINT, "Slave get Unexpected BusStart" }, 7508 { F_SLVCOMMANDCODEINVINT, "Slave get Invalid Command Code" }, 7509 { F_SLVBYTECNTERRINT, "Slave get Erroneous ByteCount value" }, 7510 { F_SLVUNEXPACKMSTINT, "Slave get Unexpected Ack from Master" }, 7511 { F_SLVUNEXPNACKMSTINT, "Slave get Unexpected Nack from Master" }, 7512 { F_SLVNOBUSSTOPINT, "Slave did not get Bus Stop" }, 7513 { F_SLVNOREPSTARTINT, "Slave has no Repeated Start" }, 7514 { F_SLVRXADDRINT, "Slave has Address Error" }, 7515 { F_SLVRXPECERRINT, "Slave has Pec Error" }, 7516 { F_SLVPREPTOARPINT, "PL has invalid request" }, 7517 { F_SLVTIMEOUTINT, "Slave has timed out" }, 7518 { F_SLVERRINT, "Slave detected error during the current transfer" }, 7519 { F_SLVDONEINT, "Slave has completed the current transaction" }, 7520 { F_SLVRXRDYINT, "Slave has received bytes to be processed by uP" }, 7521 { F_MSTTIMEOUTINT, "Master has timed out" }, 7522 { F_MSTNACKINT, "Master has detected a NAck on the transfer" }, 7523 { F_MSTLOSTARBINT, "Master has lost arbitration all the timeline" }, 7524 { F_MSTDONEINT, "Master has completed the current transaction" }, 7525 { 0 } 7526 }; 7527 static const struct intr_info smb_int_cause = { 7528 .name = "SMB_INT_CAUSE", 7529 .cause_reg = A_SMB_INT_CAUSE, 7530 .enable_reg = A_SMB_INT_ENABLE, 7531 .fatal = F_SLVFIFOPARINT | F_MSTRXFIFOPARINT | F_MSTTXFIFOPARINT, 7532 .flags = 0, 7533 .details = smb_int_cause_details, 7534 .actions = NULL, 7535 }; 7536 7537 return (t4_handle_intr(adap, &smb_int_cause, 0, flags)); 7538 } 7539 7540 /* 7541 * NC-SI interrupt handler. 7542 */ 7543 static bool ncsi_intr_handler(struct adapter *adap, int arg, int flags) 7544 { 7545 static const struct intr_details ncsi_int_cause_fields[] = { 7546 { F_CIM2NC_PERR, " CIM to NC parity error" }, 7547 { F_CIM_DM_PRTY_ERR, "NC-SI CIM parity error" }, 7548 { F_MPS_DM_PRTY_ERR, "NC-SI MPS parity error" }, 7549 { F_TXFIFO_PRTY_ERR, "NC-SI Tx FIFO parity error" }, 7550 { F_RXFIFO_PRTY_ERR, "NC-SI Rx FIFO parity error" }, 7551 { 0 } 7552 }; 7553 static const struct intr_info ncsi_int_cause = { 7554 .name = "NCSI_INT_CAUSE", 7555 .cause_reg = A_NCSI_INT_CAUSE, 7556 .enable_reg = A_NCSI_INT_ENABLE, 7557 .fatal = F_RXFIFO_PRTY_ERR | F_TXFIFO_PRTY_ERR | 7558 F_MPS_DM_PRTY_ERR | F_CIM_DM_PRTY_ERR, 7559 .flags = 0, 7560 .details = ncsi_int_cause_fields, 7561 .actions = NULL, 7562 }; 7563 static const struct intr_details ncsi_xgmac0_int_cause_details[] = { 7564 { F_XAUIPCSDECERR, "RGMII PCS DEC Error" }, 7565 { F_RGMIIRXFIFOOVERFLOW, "RGMII receive FIFO over flow" }, 7566 { F_RGMIIRXFIFOUNDERFLOW, "RGMII receive FIFO under flow" }, 7567 { F_RXPKTSIZEERROR, "Receive over size packet" }, 7568 { F_WOLPATDETECTED, "WOL pattern detected" }, 7569 { 0x000e0000, "Tx FIFO parity error" }, 7570 { 0x0001c000, "Rx FIFO parity error" }, 7571 { F_TXFIFO_UNDERRUN, "Tx FIFO underrun" }, 7572 { F_RXFIFO_OVERFLOW, "Rx FIFO overflow" }, 7573 { 0x00000f00, "XAUI SERDES BIST error" }, 7574 { 0x000000f0, "XAUI SERDES receive low signal change" }, 7575 { F_XAUIPCSCTCERR, "XAUI PCS CTC FIFO error" }, 7576 { F_XAUIPCSALIGNCHANGE, "XAUI PCS alignment change" }, 7577 { F_RGMIILINKSTSCHANGE, "RGMII link status change" }, 7578 { F_XGM_INT, "XGM Core embedded interrupt (2nd level)" }, 7579 { 0 } 7580 }; 7581 static const struct intr_info ncsi_xgmac0_int_cause = { 7582 .name = "NCSI_XGMAC0_INT_CAUSE", 7583 .cause_reg = A_NCSI_XGMAC0_INT_CAUSE, 7584 .enable_reg = A_NCSI_XGMAC0_INT_ENABLE, 7585 .fatal = 0, 7586 .flags = 0, 7587 .details = ncsi_xgmac0_int_cause_details, 7588 .actions = NULL, 7589 }; 7590 bool fatal = false; 7591 7592 fatal |= t4_handle_intr(adap, &ncsi_int_cause, 0, flags); 7593 if (chip_id(adap) > CHELSIO_T6) 7594 fatal |= t4_handle_intr(adap, &ncsi_xgmac0_int_cause, 0, flags); 7595 return (fatal); 7596 } 7597 7598 /* 7599 * MAC interrupt handler. 7600 */ 7601 static bool mac_intr_handler(struct adapter *adap, int port, int flags) 7602 { 7603 static const struct intr_details mac_int_cause_cmn_details[] = { 7604 { 0x3fffc0, "HSS PLL lock error " }, 7605 { F_FLOCK_ASSERTED, "frequency lock coming out of DPLL sub-block is asserted" }, 7606 { F_FLOCK_LOST, "frequency lock coming out of DPLL sub-blocki is lost." }, 7607 { F_PHASE_LOCK_ASSERTED, "PHASE LOCK from DPLL sub-block is asserted" }, 7608 { F_PHASE_LOCK_LOST, "PHASE LOCK from DPLL sub-block is lost." }, 7609 { F_LOCK_ASSERTED, "Lock from frac_n PLL inside t7_clk module is asserted" }, 7610 { F_LOCK_LOST, "Lock from frac_n PLL inside t7_clk module is lost " }, 7611 { 0 } 7612 }; 7613 static const struct intr_info mac_int_cause_cmn = { 7614 .name = "MAC_INT_CAUSE_CMN", 7615 .cause_reg = A_MAC_INT_CAUSE_CMN, 7616 .enable_reg = A_MAC_INT_EN_CMN, 7617 .fatal = 0, 7618 .flags = 0, 7619 .details = mac_int_cause_cmn_details, 7620 .actions = NULL, 7621 }; 7622 static const struct intr_details mac_perr_int_cause_mtip_details[] = { 7623 { F_PERR_MAC0_TX, "MTIP MAC TX memory for MAC 0 (the 200G MAC for port 0)" }, 7624 { F_PERR_MAC1_TX, "MTIP MAC TX memory for MAC 1 (the 200G MAC for port 1)" }, 7625 { F_PERR_MAC2_TX, "MTIP MAC TX memory for MAC 2 (the 10-100G MAC for port 0)" }, 7626 { F_PERR_MAC3_TX, "MTIP MAC TX memory for MAC 3 (the 10-100G MAC for port 1)" }, 7627 { F_PERR_MAC4_TX, "MTIP MAC TX memory for MAC 4 (the 10-100G MAC for port 2)" }, 7628 { F_PERR_MAC5_TX, "MTIP MAC TX memory for MAC 5 (the 10-100G MAC for port 3)" }, 7629 { F_PERR_MAC0_RX, "MTIP MAC RX memory for MAC 0 (the 200G MAC for port 0)" }, 7630 { F_PERR_MAC1_RX, "MTIP MAC RX memory for MAC 1 (the 200G MAC for port 1)" }, 7631 { F_PERR_MAC2_RX, "MTIP MAC RX memory for MAC 2 (the 10-100G MAC for port 0)" }, 7632 { F_PERR_MAC3_RX, "MTIP MAC RX memory for MAC 3 (the 10-100G MAC for port 1)" }, 7633 { F_PERR_MAC4_RX, "MTIP MAC RX memory for MAC 4 (the 10-100G MAC for port 2)" }, 7634 { F_PERR_MAC5_RX, "MTIP MAC RX memory for MAC 5 (the 10-100G MAC for port 3)" }, 7635 { F_PERR_MAC_STAT_RX, "MTIP MAC RX statistics memory (1 for all 4 10-100G MACs)" }, 7636 { F_PERR_MAC_STAT_TX, "MTIP MAC TX statistics memory (1 for all 4 10-100G MACs)" }, 7637 { F_PERR_MAC_STAT_CAP, "MTIP MAC stat capture memory (1 for all 4 100G MACs)" }, 7638 { 0 } 7639 }; 7640 static const struct intr_info mac_perr_cause_mtip = { 7641 .name = "MAC_PERR_INT_CAUSE_MTIP", 7642 .cause_reg = A_MAC_PERR_INT_CAUSE_MTIP, 7643 .enable_reg = A_MAC_PERR_INT_EN_MTIP, 7644 .fatal = 0xffffffff, 7645 .flags = IHF_FATAL_IFF_ENABLED | IHF_IGNORE_IF_DISABLED, 7646 .details = mac_perr_int_cause_mtip_details, 7647 .actions = NULL, 7648 }; 7649 static const struct intr_details ios_intr_cause_quad0_details[] = { 7650 { F_Q0_MAILBOX_INT_ASSERT, "Etopus Quad0 Mailbox interrupt cause" }, 7651 { 0x00f00000, "Etopus Quad0 training failure" }, 7652 { 0x000f0000, "Etopus Quad0 training complete" }, 7653 { 0x0000f000, "Etopus Quad0 AN TX interrupt" }, 7654 { 0x00000f00, "Etopus Quad0 signal detect assertion" }, 7655 { 0x000000f0, "Etopus Quad0 CDR LOL assertion" }, 7656 { 0x0000000f, "Etopus Quad0 LOS signal assertion" }, 7657 { 0 } 7658 }; 7659 static const struct intr_details ios_intr_cause_quad1_details[] = { 7660 { F_Q1_MAILBOX_INT_ASSERT, "Etopus Quad1 Mailbox interrupt cause" }, 7661 { 0x00f00000, "Etopus Quad1 training failure" }, 7662 { 0x000f0000, "Etopus Quad1 training complete" }, 7663 { 0x0000f000, "Etopus Quad1 AN TX interrupt" }, 7664 { 0x00000f00, "Etopus Quad1 signal detect assertion" }, 7665 { 0x000000f0, "Etopus Quad1 CDR LOL assertion" }, 7666 { 0x0000000f, "Etopus Quad1 LOS signal assertion" }, 7667 { 0 } 7668 }; 7669 static const struct intr_info mac_ios_int_cause_quad0 = { 7670 .name = "MAC_IOS_INTR_CAUSE_QUAD0", 7671 .cause_reg = A_MAC_IOS_INTR_CAUSE_QUAD0, 7672 .enable_reg = A_MAC_IOS_INTR_EN_QUAD0, 7673 .fatal = 0, 7674 .flags = 0, 7675 .details = ios_intr_cause_quad0_details, 7676 .actions = NULL, 7677 }; 7678 static const struct intr_info mac_ios_int_cause_quad1 = { 7679 .name = "MAC_IOS_INTR_CAUSE_QUAD1", 7680 .cause_reg = A_MAC_IOS_INTR_CAUSE_QUAD1, 7681 .enable_reg = A_MAC_IOS_INTR_EN_QUAD1, 7682 .fatal = 0, 7683 .flags = 0, 7684 .details = ios_intr_cause_quad1_details, 7685 .actions = NULL, 7686 }; 7687 static const struct intr_details mac_intr_details[] = { 7688 { F_TXFIFO_PRTY_ERR, "MAC Tx FIFO parity error" }, 7689 { F_RXFIFO_PRTY_ERR, "MAC Rx FIFO parity error" }, 7690 { 0 } 7691 }; 7692 static const struct intr_details t7_mac_int_cause_details[] = { 7693 { F_MAC2MPS_PERR_CAUSE, "MPS2MAC Data parity error per port" }, 7694 { F_MAC_PPS_INT_CAUSE, "One second interrupt based on PTP timer" }, 7695 { F_MAC_TX_TS_AVAIL_INT_CAUSE, 7696 "Time stamp is available for the last IEEE 1588 event frame" }, 7697 { F_MAC_PATDETWAKE_INT_CAUSE, "Wake up pattern match packet received" }, 7698 { F_MAC_MAGIC_WAKE_INT_CAUSE, "Magic packet received" }, 7699 { F_MAC_SIGDETCHG_INT_CAUSE, "Signal Detect Change" }, 7700 { F_MAC_PCS_LINK_GOOD_CAUSE, "PCS link good (xaui pcsr or 1g)" }, 7701 { F_MAC_PCS_LINK_FAIL_CAUSE, "PCS Failure (xaui pcsr or 1g)" }, 7702 { F_RXFIFOOVERFLOW, "RX Fifo Over flow error" }, 7703 { F_MAC_REM_FAULT_INT_CAUSE, "Remote fault received by XGMAC" }, 7704 { F_MAC_LOC_FAULT_INT_CAUSE, "Local fault received by XGMAC" }, 7705 { F_MAC_LINK_DOWN_INT_CAUSE, "Link is down" }, 7706 { F_MAC_LINK_UP_INT_CAUSE, "Link is up" }, 7707 { F_MAC_AN_DONE_INT_CAUSE, "Autonegotiation complete" }, 7708 { F_MAC_AN_PGRD_INT_CAUSE, "An page received" }, 7709 { F_MAC_TXFIFO_ERR_INT_CAUSE, "Tx FIFO parity error" }, 7710 { F_MAC_RXFIFO_ERR_INT_CAUSE, "Rx FIFO parity error" }, 7711 { 0 } 7712 }; 7713 static const struct intr_details mac_perr_int_cause_details[] = { 7714 { F_T6_PERR_PKT_RAM, "WoL packet data memory" }, 7715 { F_T6_PERR_MASK_RAM, "WoL mask memory" }, 7716 { F_T6_PERR_CRC_RAM, "WoL CRC memory" }, 7717 { 0 } 7718 }; 7719 char name[32]; 7720 struct intr_info ii; 7721 bool fatal = false; 7722 7723 if (port > 1 && is_t6(adap)) 7724 return (false); 7725 7726 if (is_t4(adap)) { 7727 snprintf(name, sizeof(name), "XGMAC_PORT%u_INT_CAUSE", port); 7728 ii.name = &name[0]; 7729 ii.cause_reg = PORT_REG(port, A_XGMAC_PORT_INT_CAUSE); 7730 ii.enable_reg = PORT_REG(port, A_XGMAC_PORT_INT_EN); 7731 ii.fatal = F_TXFIFO_PRTY_ERR | F_RXFIFO_PRTY_ERR; 7732 ii.flags = 0; 7733 ii.details = mac_intr_details; 7734 ii.actions = NULL; 7735 } else if (chip_id(adap) < CHELSIO_T7) { 7736 snprintf(name, sizeof(name), "MAC_PORT%u_INT_CAUSE", port); 7737 ii.name = &name[0]; 7738 ii.cause_reg = T5_PORT_REG(port, A_MAC_PORT_INT_CAUSE); 7739 ii.enable_reg = T5_PORT_REG(port, A_MAC_PORT_INT_EN); 7740 ii.fatal = F_TXFIFO_PRTY_ERR | F_RXFIFO_PRTY_ERR; 7741 ii.flags = 0; 7742 ii.details = mac_intr_details; 7743 ii.actions = NULL; 7744 } else { 7745 snprintf(name, sizeof(name), "MAC_PORT%u_INT_CAUSE", port); 7746 ii.name = &name[0]; 7747 ii.cause_reg = T7_PORT_REG(port, A_T7_MAC_PORT_INT_CAUSE); 7748 ii.enable_reg = T7_PORT_REG(port, A_T7_MAC_PORT_INT_EN); 7749 ii.fatal = 0xffffffff; 7750 ii.flags = IHF_FATAL_IFF_ENABLED; 7751 ii.details = t7_mac_int_cause_details; 7752 ii.actions = NULL; 7753 } 7754 fatal |= t4_handle_intr(adap, &ii, 0, flags); 7755 if (is_t4(adap)) 7756 return (fatal); 7757 7758 MPASS(chip_id(adap) >= CHELSIO_T5); 7759 snprintf(name, sizeof(name), "MAC_PORT%u_PERR_INT_CAUSE", port); 7760 if (chip_id(adap) > CHELSIO_T6) { 7761 ii.name = &name[0]; 7762 ii.cause_reg = T7_PORT_REG(port, A_T7_MAC_PORT_PERR_INT_CAUSE); 7763 ii.enable_reg = T7_PORT_REG(port, A_T7_MAC_PORT_PERR_INT_EN); 7764 ii.fatal = 0xffffffff; 7765 ii.flags = IHF_FATAL_IFF_ENABLED; 7766 ii.details = mac_perr_int_cause_details; 7767 ii.actions = NULL; 7768 } else { 7769 ii.name = &name[0]; 7770 ii.cause_reg = T5_PORT_REG(port, A_MAC_PORT_PERR_INT_CAUSE); 7771 ii.enable_reg = T5_PORT_REG(port, A_MAC_PORT_PERR_INT_EN); 7772 ii.fatal = 0xffffffff; 7773 ii.flags = IHF_FATAL_IFF_ENABLED; 7774 ii.details = NULL; 7775 ii.actions = NULL; 7776 } 7777 fatal |= t4_handle_intr(adap, &ii, 0, flags); 7778 if (is_t5(adap)) 7779 return (fatal); 7780 7781 MPASS(chip_id(adap) >= CHELSIO_T6); 7782 snprintf(name, sizeof(name), "MAC_PORT%u_PERR_INT_CAUSE_100G", port); 7783 if (chip_id(adap) > CHELSIO_T6) { 7784 ii.name = &name[0]; 7785 ii.cause_reg = T7_PORT_REG(port, A_T7_MAC_PORT_PERR_INT_CAUSE_100G); 7786 ii.enable_reg = T7_PORT_REG(port, A_T7_MAC_PORT_PERR_INT_EN_100G); 7787 ii.fatal = 0xffffffff; 7788 ii.flags = IHF_FATAL_IFF_ENABLED; 7789 ii.details = NULL; 7790 ii.actions = NULL; 7791 } else { 7792 ii.name = &name[0]; 7793 ii.cause_reg = T5_PORT_REG(port, A_MAC_PORT_PERR_INT_CAUSE_100G); 7794 ii.enable_reg = T5_PORT_REG(port, A_MAC_PORT_PERR_INT_EN_100G); 7795 ii.fatal = 0xffffffff; 7796 ii.flags = IHF_FATAL_IFF_ENABLED; 7797 ii.details = NULL; 7798 ii.actions = NULL; 7799 } 7800 fatal |= t4_handle_intr(adap, &ii, 0, flags); 7801 if (is_t6(adap)) 7802 return (fatal); 7803 7804 MPASS(chip_id(adap) >= CHELSIO_T7); 7805 fatal |= t4_handle_intr(adap, &mac_int_cause_cmn, 0, flags); 7806 fatal |= t4_handle_intr(adap, &mac_perr_cause_mtip, 0, flags); 7807 fatal |= t4_handle_intr(adap, &mac_ios_int_cause_quad0, 0, flags); 7808 fatal |= t4_handle_intr(adap, &mac_ios_int_cause_quad1, 0, flags); 7809 7810 return (fatal); 7811 } 7812 7813 static bool pl_timeout_status(struct adapter *adap, int arg, int flags) 7814 { 7815 if (flags & IHF_NO_SHOW) 7816 return (false); 7817 7818 CH_ALERT(adap, " PL_TIMEOUT_STATUS 0x%08x 0x%08x\n", 7819 t4_read_reg(adap, A_PL_TIMEOUT_STATUS0), 7820 t4_read_reg(adap, A_PL_TIMEOUT_STATUS1)); 7821 7822 return (false); 7823 } 7824 7825 static bool plpl_intr_handler(struct adapter *adap, int arg, int flags) 7826 { 7827 static const struct intr_details plpl_int_cause_fields[] = { 7828 { F_FATALPERR, "Fatal parity error" }, 7829 { F_PERRVFID, "VFID_MAP parity error" }, 7830 { 0 } 7831 }; 7832 static const struct intr_details t5_plpl_int_cause_fields[] = { 7833 { F_PL_BUSPERR, "Bus parity error" }, 7834 { F_FATALPERR, "Fatal parity error" }, 7835 { F_INVALIDACCESS, "Global reserved memory access" }, 7836 { F_TIMEOUT, "Bus timeout" }, 7837 { F_PLERR, "Module reserved access" }, 7838 { 0 } 7839 }; 7840 static const struct intr_action plpl_int_cause_actions[] = { 7841 { F_TIMEOUT, -1, pl_timeout_status }, 7842 { 0 }, 7843 }; 7844 struct intr_info plpl_int_cause = { 7845 .name = "PL_PL_INT_CAUSE", 7846 .cause_reg = A_PL_PL_INT_CAUSE, 7847 .enable_reg = A_PL_PL_INT_ENABLE, 7848 .fatal = F_FATALPERR, 7849 .flags = IHF_FATAL_IFF_ENABLED, 7850 .details = NULL, 7851 .actions = NULL, 7852 }; 7853 7854 if (is_t4(adap)) { 7855 plpl_int_cause.fatal |= F_PERRVFID; 7856 plpl_int_cause.details = plpl_int_cause_fields; 7857 } else { 7858 plpl_int_cause.fatal |= F_INVALIDACCESS; 7859 plpl_int_cause.details = t5_plpl_int_cause_fields; 7860 plpl_int_cause.actions = plpl_int_cause_actions; 7861 } 7862 return (t4_handle_intr(adap, &plpl_int_cause, 0, flags)); 7863 } 7864 7865 /* similar to t4_port_reg */ 7866 static inline u32 7867 t7_tlstx_reg(u8 instance, u8 channel, u32 reg) 7868 { 7869 MPASS(instance <= 1); 7870 MPASS(channel < NUM_TLS_TX_CH_INSTANCES); 7871 return (instance * (CRYPTO_1_BASE_ADDR - CRYPTO_0_BASE_ADDR) + 7872 TLS_TX_CH_REG(reg, channel)); 7873 } 7874 7875 /* 7876 * CRYPTO (aka TLS_TX) interrupt handler. 7877 */ 7878 static bool tlstx_intr_handler(struct adapter *adap, int idx, int flags) 7879 { 7880 static const struct intr_details tlstx_int_cause_fields[] = { 7881 { F_KEX_CERR, "KEX SRAM Correctable error" }, 7882 { F_KEYLENERR, "IPsec Key length error" }, 7883 { F_INTF1_PERR, "Input Interface1 parity error" }, 7884 { F_INTF0_PERR, "Input Interface0 parity error" }, 7885 { F_KEX_PERR, "KEX SRAM Parity error" }, 7886 { 0 } 7887 }; 7888 struct intr_info ii = { 7889 .fatal = F_KEX_PERR | F_INTF0_PERR | F_INTF1_PERR, 7890 .flags = IHF_FATAL_IFF_ENABLED, 7891 .details = tlstx_int_cause_fields, 7892 .actions = NULL, 7893 }; 7894 char name[32]; 7895 int ch; 7896 bool fatal = false; 7897 7898 for (ch = 0; ch < NUM_TLS_TX_CH_INSTANCES; ch++) { 7899 snprintf(name, sizeof(name), "TLSTX%u_CH%u_INT_CAUSE", idx, ch); 7900 ii.name = &name[0]; 7901 ii.cause_reg = t7_tlstx_reg(idx, ch, A_TLS_TX_CH_INT_CAUSE); 7902 ii.enable_reg = t7_tlstx_reg(idx, ch, A_TLS_TX_CH_INT_ENABLE); 7903 fatal |= t4_handle_intr(adap, &ii, 0, flags); 7904 } 7905 7906 return (fatal); 7907 } 7908 7909 /* 7910 * HMA interrupt handler. 7911 */ 7912 static bool hma_intr_handler(struct adapter *adap, int idx, int flags) 7913 { 7914 static const struct intr_details hma_int_cause_fields[] = { 7915 { F_GK_UF_INT_CAUSE, "Gatekeeper underflow" }, 7916 { F_IDTF_INT_CAUSE, "Invalid descriptor fault" }, 7917 { F_OTF_INT_CAUSE, "Offset translation fault" }, 7918 { F_RTF_INT_CAUSE, "Region translation fault" }, 7919 { F_PCIEMST_INT_CAUSE, "PCIe master access error" }, 7920 { F_MAMST_INT_CAUSE, "MA master access error" }, 7921 { F_PERR_INT_CAUSE, "FIFO parity error" }, 7922 { 0 } 7923 }; 7924 static const struct intr_info hma_int_cause = { 7925 .name = "HMA_INT_CAUSE", 7926 .cause_reg = A_HMA_INT_CAUSE, 7927 .enable_reg = A_HMA_INT_ENABLE, 7928 .fatal = 7, 7929 .flags = 0, 7930 .details = hma_int_cause_fields, 7931 .actions = NULL, 7932 }; 7933 7934 return (t4_handle_intr(adap, &hma_int_cause, 0, flags)); 7935 } 7936 7937 /* 7938 * CRYPTO_KEY interrupt handler. 7939 */ 7940 static bool cryptokey_intr_handler(struct adapter *adap, int idx, int flags) 7941 { 7942 static const struct intr_details cryptokey_int_cause_fields[] = { 7943 { F_MA_FIFO_PERR, "MA arbiter FIFO parity error" }, 7944 { F_MA_RSP_PERR, "MA response IF parity error" }, 7945 { F_ING_CACHE_DATA_PERR, "Ingress key cache data parity error" }, 7946 { F_ING_CACHE_TAG_PERR, "Ingress key cache tag parity error" }, 7947 { F_LKP_KEY_REQ_PERR, "Ingress key req parity error" }, 7948 { F_LKP_CLIP_TCAM_PERR, "Ingress LKP CLIP TCAM parity error" }, 7949 { F_LKP_MAIN_TCAM_PERR, "Ingress LKP main TCAM parity error" }, 7950 { F_EGR_KEY_REQ_PERR, "Egress key req or FIFO3 parity error" }, 7951 { F_EGR_CACHE_DATA_PERR, "Egress key cache data parity error" }, 7952 { F_EGR_CACHE_TAG_PERR, "Egress key cache tag parity error" }, 7953 { F_CIM_PERR, "CIM interface parity error" }, 7954 { F_MA_INV_RSP_TAG, "MA invalid response tag" }, 7955 { F_ING_KEY_RANGE_ERR, "Ingress key range error" }, 7956 { F_ING_MFIFO_OVFL, "Ingress MFIFO overflow" }, 7957 { F_LKP_REQ_OVFL, "Ingress lookup FIFO overflow" }, 7958 { F_EOK_WAIT_ERR, "EOK wait error" }, 7959 { F_EGR_KEY_RANGE_ERR, "Egress key range error" }, 7960 { F_EGR_MFIFO_OVFL, "Egress MFIFO overflow" }, 7961 { F_SEQ_WRAP_HP_OVFL, "Sequence wrap (hi-pri)" }, 7962 { F_SEQ_WRAP_LP_OVFL, "Sequence wrap (lo-pri)" }, 7963 { F_EGR_SEQ_WRAP_HP, "Egress sequence wrap (hi-pri)" }, 7964 { F_EGR_SEQ_WRAP_LP, "Egress sequence wrap (lo-pri)" }, 7965 { 0 } 7966 }; 7967 static const struct intr_info cryptokey_int_cause = { 7968 .name = "CRYPTO_KEY_INT_CAUSE", 7969 .cause_reg = A_CRYPTO_KEY_INT_CAUSE, 7970 .enable_reg = A_CRYPTO_KEY_INT_ENABLE, 7971 .fatal = 0xffffffff, 7972 .flags = IHF_FATAL_IFF_ENABLED, 7973 .details = cryptokey_int_cause_fields, 7974 .actions = NULL, 7975 }; 7976 7977 return (t4_handle_intr(adap, &cryptokey_int_cause, 0, flags)); 7978 } 7979 7980 /* 7981 * GCACHE interrupt handler. 7982 */ 7983 static bool gcache_intr_handler(struct adapter *adap, int idx, int flags) 7984 { 7985 static const struct intr_details gcache_int_cause_fields[] = { 7986 { F_GC1_SRAM_RSP_DATAQ_PERR_INT_CAUSE, "GC1 SRAM rsp dataq perr" }, 7987 { F_GC0_SRAM_RSP_DATAQ_PERR_INT_CAUSE, "GC0 SRAM rsp dataq perr" }, 7988 { F_GC1_WQDATA_FIFO_PERR_INT_CAUSE, "GC1 wqdata FIFO perr" }, 7989 { F_GC0_WQDATA_FIFO_PERR_INT_CAUSE, "GC0 wqdata FIFO perr" }, 7990 { F_GC1_RDTAG_QUEUE_PERR_INT_CAUSE, "GC1 rdtag queue perr" }, 7991 { F_GC0_RDTAG_QUEUE_PERR_INT_CAUSE, "GC0 rdtag queue perr" }, 7992 { F_GC1_SRAM_RDTAG_QUEUE_PERR_INT_CAUSE, "GC1 SRAM rdtag queue perr" }, 7993 { F_GC0_SRAM_RDTAG_QUEUE_PERR_INT_CAUSE, "GC0 SRAM rdtag queue perr" }, 7994 { F_GC1_RSP_PERR_INT_CAUSE, "GC1 rsp perr" }, 7995 { F_GC0_RSP_PERR_INT_CAUSE, "GC0 rsp perr" }, 7996 { F_GC1_LRU_UERR_INT_CAUSE, "GC1 lru uerr" }, 7997 { F_GC0_LRU_UERR_INT_CAUSE, "GC0 lru uerr" }, 7998 { F_GC1_TAG_UERR_INT_CAUSE, "GC1 tag uerr" }, 7999 { F_GC0_TAG_UERR_INT_CAUSE, "GC0 tag uerr" }, 8000 { F_GC1_LRU_CERR_INT_CAUSE, "GC1 lru cerr" }, 8001 { F_GC0_LRU_CERR_INT_CAUSE, "GC0 lru cerr" }, 8002 { F_GC1_TAG_CERR_INT_CAUSE, "GC1 tag cerr" }, 8003 { F_GC0_TAG_CERR_INT_CAUSE, "GC0 tag cerr" }, 8004 { F_GC1_CE_INT_CAUSE, "GC1 correctable error" }, 8005 { F_GC0_CE_INT_CAUSE, "GC0 correctable error" }, 8006 { F_GC1_UE_INT_CAUSE, "GC1 uncorrectable error" }, 8007 { F_GC0_UE_INT_CAUSE, "GC0 uncorrectable error" }, 8008 { F_GC1_CMD_PAR_INT_CAUSE, "GC1 cmd perr" }, 8009 { F_GC1_DATA_PAR_INT_CAUSE, "GC1 data perr" }, 8010 { F_GC0_CMD_PAR_INT_CAUSE, "GC0 cmd perr" }, 8011 { F_GC0_DATA_PAR_INT_CAUSE, "GC0 data perr" }, 8012 { F_ILLADDRACCESS1_INT_CAUSE, "GC1 illegal address access" }, 8013 { F_ILLADDRACCESS0_INT_CAUSE, "GC0 illegal address access" }, 8014 { 0 } 8015 }; 8016 static const struct intr_info gcache_int_cause = { 8017 .name = "GCACHE_INT_CAUSE", 8018 .cause_reg = A_GCACHE_INT_CAUSE, 8019 .enable_reg = A_GCACHE_INT_ENABLE, 8020 .fatal = 0, 8021 .flags = 0, 8022 .details = gcache_int_cause_fields, 8023 .actions = NULL, 8024 }; 8025 return (t4_handle_intr(adap, &gcache_int_cause, 0, flags)); 8026 } 8027 8028 /* 8029 * ARM interrupt handler. 8030 */ 8031 static bool arm_intr_handler(struct adapter *adap, int idx, int flags) 8032 { 8033 static const struct intr_details arm_perr_int_cause0_details[] = { 8034 { F_INIC_WRDATA_FIFO_PERR, "INT CAUSE for INIC Write Data Fifo Parity Error" }, 8035 { F_INIC_RDATA_FIFO_PERR, "INT CAUSE for INIC Read Data Fifo Parity Error" }, 8036 { F_MSI_MEM_PERR, "INT CAUSE for MSI Memory Parity Error" }, 8037 { 0x18000000, "INT CAUSE for ARM Doorbell SRAM Parity Error" }, 8038 { F_EMMC_FIFOPARINT, "INT CAUSE for EMMC Fifo Parity Interrupt" }, 8039 { F_ICB_RAM_PERR, "INT CAUSE for ICB SRAM Parity Error" }, 8040 { F_MESS2AXI4_WRFIFO_PERR, "INT CAUSE for Message2AXI4 Write FIFO Parity Error" }, 8041 { F_RC_WFIFO_OUTPERR, "INT CAUSE for AXI2RC Write FIFO Parity Error" }, 8042 { 0x00600000, "INT CAUSE for AXI2RC SRAM Parity Error" }, 8043 { F_MSI_FIFO_PAR_ERR, "INT CAUSE for APB2MSI FIFO Parity Error" }, 8044 { F_INIC2MA_INTFPERR, "INT CAUSE for INIC to MA Interface Parity Error" }, 8045 { F_RDATAFIFO0_PERR, "INT CAUSE for AXI2MA M0 Read Data Fifo Parity Error" }, 8046 { F_RDATAFIFO1_PERR, "INT CAUSE for AXI2MA M1 Read Data Fifo Parity Error" }, 8047 { F_WRDATAFIFO0_PERR, "INT CAUSE for AXI2MA M0 Write Data Fifo Parity Error" }, 8048 { F_WRDATAFIFO1_PERR, "INT CAUSE for AXI2MA M1 Write Data Fifo Parity Error" }, 8049 { F_WR512DATAFIFO0_PERR, 8050 "INT CAUSE for AXI2MA M0 Write Data 512b Fifo Parity Error" }, 8051 { F_WR512DATAFIFO1_PERR, 8052 "INT CAUSE for AXI2MA M1 Write Data 512b Fifo Parity Error" }, 8053 { F_ROBUFF_PARERR3, "INT CAUSE for Reorder Buffer Parity Error" }, 8054 { F_ROBUFF_PARERR2, "INT CAUSE for Reorder Buffer Parity Error" }, 8055 { F_ROBUFF_PARERR1, "INT CAUSE for Reorder Buffer Parity Error" }, 8056 { F_ROBUFF_PARERR0, "INT CAUSE for Reorder Buffer Parity Error" }, 8057 { F_MA2AXI_REQDATAPARERR, "INT CAUSE for MA2AXI Request Data Parity Error" }, 8058 { F_MA2AXI_REQCTLPARERR, "INT CAUSE for MA2AXI Request Control Parity Error" }, 8059 { F_MA_RSPPERR, "INT CAUSE for MA Response Parity Error" }, 8060 { F_PCIE2MA_REQCTLPARERR, "INT CAUSE for PCIe to MA Control Parity Error" }, 8061 { F_PCIE2MA_REQDATAPARERR, "INT CAUSE for PCIe to MA Data Parity Error" }, 8062 { F_INIC2MA_REQCTLPARERR, "INT CAUSE for INIC to MA Control Parity Error" }, 8063 { F_INIC2MA_REQDATAPARERR, "INT CAUSE for INIC to MA Data Parity Error" }, 8064 { F_MA_RSPUE, "INT CAUSE for MA Response Uncorrectable Error" }, 8065 { F_APB2PL_RSPDATAPERR, "INT CAUSE for APB2PL Response Data Parity Error" }, 8066 { 0 } 8067 }; 8068 static const struct intr_info arm_perr_cause0 = { 8069 .name = "ARM_PERR_INT_CAUSE0", 8070 .cause_reg = A_ARM_PERR_INT_CAUSE0, 8071 .enable_reg = A_ARM_PERR_INT_ENB0, 8072 .fatal = 0xffffffff, 8073 .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, 8074 .details = arm_perr_int_cause0_details, 8075 .actions = NULL, 8076 }; 8077 static const struct intr_details arm_perr_int_cause1_details[] = { 8078 { F_ARWFIFO0_PERR, "AXI2MA M0 Read-Write FIFO Parity Error" }, 8079 { F_ARWFIFO1_PERR, "AXI2MA M1 Read-Write FIFO Parity Error" }, 8080 { F_ARWIDFIFO0_PERR, "AXI2MA M0 Read-Write ID FIFO Parity Error" }, 8081 { F_ARWIDFIFO1_PERR, "AXI2MA M1 Read-Write ID FIFO Parity Error" }, 8082 { F_ARIDFIFO0_PERR, "AXI2MA M0 Read FIFO Parity Error" }, 8083 { F_ARIDFIFO1_PERR, "AXI2MA M1 Read FIFO Parity Error" }, 8084 { F_RRSPADDR_FIFO0_PERR, "AXI2MA M0 Read Response Address FIFO Parity Error" }, 8085 { F_RRSPADDR_FIFO1_PERR, "AXI2MA M1 Read Response Address FIFO Parity Error" }, 8086 { F_WRSTRB_FIFO0_PERR, "AXI2MA M0 Write Strobe FIFO Parity Error" }, 8087 { F_WRSTRB_FIFO1_PERR, "AXI2MA M1 Write Strobe FIFO Parity Error" }, 8088 { F_MA2AXI_RSPDATAPARERR, "MA2AXI Response FIFO Parity Error" }, 8089 { F_MA2AXI_DATA_PAR_ERR, "MA2AXI Write Data FIFO Parity Error" }, 8090 { F_MA2AXI_WR_ORD_FIFO_PARERR, "MA2AXI Ordered Write Data FIFO Parity Error" }, 8091 { F_NVME_DB_EMU_TRACKER_FIFO_PERR, "NVMe DB Emulation Tracker FIFO Parity Error" }, 8092 { F_NVME_DB_EMU_QUEUE_AW_ADDR_FIFO_PERR, 8093 "NVMe DB Emulation Queue AW Addr Parity Error" }, 8094 { F_NVME_DB_EMU_INTERRUPT_OFFSET_FIFO_PERR, 8095 "NVMe DB Emulation Interrupt Offset FIFO Parity Error" }, 8096 { F_NVME_DB_EMU_ID_FIFO0_PERR, "NVMe DB Emulation ID FIFO0 Parity Error" }, 8097 { F_NVME_DB_EMU_ID_FIFO1_PERR, "NVMe DB Emulation ID FIFO1 Parity Error" }, 8098 { F_RC_ARWFIFO_PERR, "AXI2RC Read-Write FIFO Parity Error" }, 8099 { F_RC_ARIDBURSTADDRFIFO_PERR, 8100 "AXI2RC Read ID, Burst and Address FIFO Parity Error" }, 8101 { F_RC_CFG_FIFO_PERR, "AXI2RC Config FIFO Parity Error" }, 8102 { F_RC_RSPFIFO_PERR, "AXI2RC Response Parity Error" }, 8103 { F_INIC_ARIDFIFO_PERR, "CCI2INIC Read ID FIFO Parity Error" }, 8104 { F_INIC_ARWFIFO_PERR, "CCI2INIC Read-Write FIFO ontrol Parity Error" }, 8105 { F_AXI2MA_128_RD_ADDR_SIZE_FIFO_PERR, 8106 "AXI2MA(CCI2INIC) Read Address Size FIFO Parity Error" }, 8107 { F_AXI2RC_128_RD_ADDR_SIZE_FIFO_PERR, 8108 "AXI2RC Read Address Size FIFO Parity Error" }, 8109 { F_ARM_MA_512B_RD_ADDR_SIZE_FIFO0_PERR, 8110 "ARM_MA_512b Read Address Size FIFO0 Parity Error" }, 8111 { F_ARM_MA_512B_RD_ADDR_SIZE_FIFO1_PERR, 8112 "ARM_MA_512b Read Address Size FIFO1 Parity Error" }, 8113 { F_ARM_MA_512B_ARB_FIFO_PERR, "ARM_MA_512b Arbiter FIFO Parity Error" }, 8114 { F_PCIE_INIC_MA_ARB_FIFO_PERR, "PCIe-INIC Arbiter FIFO Parity Error" }, 8115 { F_PCIE_INIC_ARB_RSPPERR, "PCIe-INIC Arbiter Response Parity Error" }, 8116 { F_ITE_CACHE_PERR, "GIC500 ITE Cache SRAM Parity Error" }, 8117 { 0 } 8118 }; 8119 static const struct intr_info arm_perr_cause1 = { 8120 .name = "ARM_PERR_INT_CAUSE1", 8121 .cause_reg = A_ARM_PERR_INT_CAUSE1, 8122 .enable_reg = A_ARM_PERR_INT_ENB1, 8123 .fatal = 0xffffffff, 8124 .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, 8125 .details = arm_perr_int_cause1_details, 8126 .actions = NULL, 8127 }; 8128 static const struct intr_details arm_perr_int_cause2_details[] = { 8129 { F_INIC_WSTRB_FIFO_PERR, "AXI2MA_128 INIC Write Strobe FIFO Parity Error" }, 8130 { F_INIC_BID_FIFO_PERR, "AXI2MA_128 INIC bID FIFO Parity Error" }, 8131 { F_CC_SRAM_PKA_PERR, "CryptoCell ram_pka_wrapper FIFO Parity Error" }, 8132 { F_CC_SRAM_SEC_PERR, "CryptoCell sec_sram_wrapper FIFO Parity Error" }, 8133 { F_MESS2AXI4_PARERR, "Message2AXI4 IBQ I/P Interface Parity Error" }, 8134 { F_CCI2INIC_INTF_PARERR, "CCI2INIC Response Interface Parity Error" }, 8135 { 0 } 8136 }; 8137 static const struct intr_info arm_perr_cause2 = { 8138 .name = "ARM_PERR_INT_CAUSE2", 8139 .cause_reg = A_ARM_PERR_INT_CAUSE2, 8140 .enable_reg = A_ARM_PERR_INT_ENB2, 8141 .fatal = 0xffffffff, 8142 .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, 8143 .details = arm_perr_int_cause2_details, 8144 .actions = NULL, 8145 }; 8146 static const struct intr_details arm_cerr_int_cause0_details[] = { 8147 { F_WRDATA_FIFO0_CERR, "AXI2MA M0 Write Data FIFO Correctable Error" }, 8148 { F_WRDATA_FIFO1_CERR, "AXI2MA M1 Write Data FIFO Correctable Error" }, 8149 { F_WR512DATAFIFO0_CERR, "AXI2MA M0 Write Data 512b FIFO Correctable Error" }, 8150 { F_WR512DATAFIFO1_CERR, "AXI2MA M1 Write Data 512b FIFO Correctable Error" }, 8151 { F_RDATAFIFO0_CERR, "AXI2MA M0 Read Data FIFO Correctable Error" }, 8152 { F_RDATAFIFO1_CERR, "AXI2MA M1 Read Data FIFO Correctable Error" }, 8153 { F_ROBUFF_CORERR0, "Reorder Buffer Correctable Error" }, 8154 { F_ROBUFF_CORERR1, "Reorder Buffer Correctable Error" }, 8155 { F_ROBUFF_CORERR2, "Reorder Buffer Correctable Error" }, 8156 { F_ROBUFF_CORERR3, "Reorder Buffer Correctable Error" }, 8157 { F_MA2AXI_RSPDATACORERR, "MA2AXI Response FIFO Correctable Error" }, 8158 { 0x00180000, "AXI2RC SRAM Correctable Error" }, 8159 { F_RC_WFIFO_OUTCERR, "AXI2RC Write FIFO Correctable Error" }, 8160 { F_RC_RSPFIFO_CERR, "AXI2RC Response Correctable Error" }, 8161 { F_MSI_MEM_CERR, "MSI Memory FIFO Correctable Error" }, 8162 { F_INIC_WRDATA_FIFO_CERR, "INIC Write Data FIFO Correctable Error" }, 8163 { F_INIC_RDATAFIFO_CERR, "INIC Read Data FIFO Correctable Error" }, 8164 { 0x00003000, "ARM Doorbell SRAM Correctable Error" }, 8165 { F_ICB_RAM_CERR, "ICB SRAM Parity Error" }, 8166 { F_CC_SRAM_PKA_CERR, "CryptoCell ram_pka_wrapper FIFO Correctable Error" }, 8167 { F_CC_SRAM_SEC_CERR, "CryptoCell sec_sram_wrapper FIFO Correctable Error" }, 8168 { 0 } 8169 }; 8170 static const struct intr_info arm_cerr_cause0 = { 8171 .name = "ARM_CERR_INT_CAUSE0", 8172 .cause_reg = A_ARM_CERR_INT_CAUSE0, 8173 .enable_reg = A_ARM_CERR_INT_ENB0, 8174 .fatal = 0, 8175 .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, 8176 .details = arm_cerr_int_cause0_details, 8177 .actions = NULL, 8178 }; 8179 static const struct intr_details arm_err_int_cause0_details[] = { 8180 { F_STRB0_ERROR, "Strobe Error from AXI2MA 0" }, 8181 { F_STRB1_ERROR, "Strobe Error from AXI2MA 1" }, 8182 { F_PCIE_INIC_MA_ARB_INV_RSP_TAG, "Invalid Response Tag for PCIE-INIc MA ARB" }, 8183 { F_ERROR0_NOCMD_DATA, "AXI2MA 0 No Command Data Error" }, 8184 { F_ERROR1_NOCMD_DATA, "AXI2MA 1 No Command Data Error" }, 8185 { F_INIC_STRB_ERROR, "AXI2MA_128b INIC Strobe Error" }, 8186 { 0 } 8187 }; 8188 static const struct intr_info arm_err_cause0 = { 8189 .name = "ARM_ERR_INT_CAUSE0", 8190 .cause_reg = A_ARM_ERR_INT_CAUSE0, 8191 .enable_reg = A_ARM_ERR_INT_ENB0, 8192 .fatal = 0, 8193 .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, 8194 .details = arm_err_int_cause0_details, 8195 .actions = NULL, 8196 }; 8197 8198 static const struct intr_details arm_peripheral_int_cause_details[] = { 8199 { F_TIMER_INT, "TIMER_INT" }, 8200 { F_NVME_INT, "NVME_INT" }, 8201 { F_EMMC_WAKEUP_INT, "EMMC_WAKEUP_INT" }, 8202 { F_EMMC_INT, "EMMC_INT" }, 8203 { F_USB_MC_INT, "USB_MC_INT" }, 8204 { F_USB_DMA_INT, "USB_DMA_INT" }, 8205 { 0 } 8206 }; 8207 static const struct intr_info arm_periph_cause = { 8208 .name = "ARM_PERIPHERAL_INT_CAUSE", 8209 .cause_reg = A_ARM_PERIPHERAL_INT_CAUSE, 8210 .enable_reg = A_ARM_PERIPHERAL_INT_ENB, 8211 .fatal = 0, 8212 .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, 8213 .details = arm_peripheral_int_cause_details, 8214 .actions = NULL, 8215 }; 8216 static const struct intr_details arm_arm_uart_int_cause_details[] = { 8217 { F_RX_FIFO_NOT_EMPTY, "intcause for uart rx fifo" }, 8218 { F_TX_FIFO_EMPTY, "intcause for uart tx fifo" }, 8219 { 0 } 8220 }; 8221 static const struct intr_info arm_uart_cause = { 8222 .name = "ARM_ARM_UART_INT_CAUSE", 8223 .cause_reg = A_ARM_ARM_UART_INT_CAUSE, 8224 .enable_reg = A_ARM_ARM_UART_INT_EN, 8225 .fatal = 0, 8226 .flags = IHF_FATAL_IFF_ENABLED, 8227 .details = arm_arm_uart_int_cause_details, 8228 .actions = NULL, 8229 }; 8230 static const struct intr_details arm_nvme_db_emu_int_cause_details[] = { 8231 { F_INVALID_BRESP, "Invalid CCI Write Response" }, 8232 { F_DATA_LEN_OF, 8233 "Incorrect Write Request to be written to incorrect Devices/Regions" }, 8234 { F_INVALID_EMU_ADDR, "Invalid Emulation Address Range Configuration" }, 8235 { F_INVALID_AXI_ADDR_CFG, "Invalid AXI Address Configuration" }, 8236 { 0 } 8237 }; 8238 static const struct intr_info arm_nvme_db_emu_cause = { 8239 .name = "ARM_NVME_DB_EMU_INT_CAUSE", 8240 .cause_reg = A_ARM_NVME_DB_EMU_INT_CAUSE, 8241 .enable_reg = A_ARM_NVME_DB_EMU_INT_ENABLE, 8242 .fatal = 0, 8243 .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED, 8244 .details = arm_nvme_db_emu_int_cause_details, 8245 .actions = NULL, 8246 }; 8247 bool fatal = false; 8248 8249 fatal |= t4_handle_intr(adap, &arm_perr_cause0, 0, flags); 8250 fatal |= t4_handle_intr(adap, &arm_perr_cause1, 0, flags); 8251 fatal |= t4_handle_intr(adap, &arm_perr_cause2, 0, flags); 8252 fatal |= t4_handle_intr(adap, &arm_cerr_cause0, 0, flags); 8253 fatal |= t4_handle_intr(adap, &arm_err_cause0, 0, flags); 8254 fatal |= t4_handle_intr(adap, &arm_periph_cause, 0, flags); 8255 fatal |= t4_handle_intr(adap, &arm_nvme_db_emu_cause, 0, flags); 8256 fatal |= t4_handle_intr(adap, &arm_uart_cause, 0, flags); 8257 8258 return (fatal); 8259 } 8260 8261 static inline uint32_t 8262 get_ucause(struct adapter *sc, const struct intr_info *ii) 8263 { 8264 uint32_t cause; 8265 8266 cause = t4_read_reg(sc, ii->cause_reg); 8267 if (ii->flags & IHF_IGNORE_IF_DISABLED) 8268 cause &= t4_read_reg(sc, ii->enable_reg); 8269 return (cause); 8270 } 8271 8272 static uint32_t 8273 t4_perr_to_ic(struct adapter *adap, uint32_t perr) 8274 { 8275 uint32_t mask; 8276 8277 if (adap->chip_params->nchan > 2) 8278 mask = F_MAC0 | F_MAC1 | F_MAC2 | F_MAC3; 8279 else 8280 mask = F_MAC0 | F_MAC1; 8281 return (perr & mask ? perr | mask : perr); 8282 } 8283 8284 static uint32_t 8285 t7_perr_to_ic1(uint32_t perr) 8286 { 8287 uint32_t cause = 0; 8288 8289 if (perr & F_T7_PL_PERR_ULP_TX) 8290 cause |= F_T7_ULP_TX; 8291 if (perr & F_T7_PL_PERR_SGE) 8292 cause |= F_T7_SGE; 8293 if (perr & F_T7_PL_PERR_HMA) 8294 cause |= F_T7_HMA; 8295 if (perr & F_T7_PL_PERR_CPL_SWITCH) 8296 cause |= F_T7_CPL_SWITCH; 8297 if (perr & F_T7_PL_PERR_ULP_RX) 8298 cause |= F_T7_ULP_RX; 8299 if (perr & F_T7_PL_PERR_PM_RX) 8300 cause |= F_T7_PM_RX; 8301 if (perr & F_T7_PL_PERR_PM_TX) 8302 cause |= F_T7_PM_TX; 8303 if (perr & F_T7_PL_PERR_MA) 8304 cause |= F_T7_MA; 8305 if (perr & F_T7_PL_PERR_TP) 8306 cause |= F_T7_TP; 8307 if (perr & F_T7_PL_PERR_LE) 8308 cause |= F_T7_LE; 8309 if (perr & F_T7_PL_PERR_EDC1) 8310 cause |= F_T7_EDC1; 8311 if (perr & F_T7_PL_PERR_EDC0) 8312 cause |= F_T7_EDC0; 8313 if (perr & F_T7_PL_PERR_MC1) 8314 cause |= F_T7_MC1; 8315 if (perr & F_T7_PL_PERR_MC0) 8316 cause |= F_T7_MC0; 8317 if (perr & F_T7_PL_PERR_PCIE) 8318 cause |= F_T7_PCIE; 8319 if (perr & F_T7_PL_PERR_UART) 8320 cause |= F_T7_UART; 8321 if (perr & F_T7_PL_PERR_PMU) 8322 cause |= F_PMU; 8323 if (perr & F_T7_PL_PERR_MAC) 8324 cause |= F_MAC0 | F_MAC1 | F_MAC2 | F_MAC3; 8325 if (perr & F_T7_PL_PERR_SMB) 8326 cause |= F_SMB; 8327 if (perr & F_T7_PL_PERR_SF) 8328 cause |= F_SF; 8329 if (perr & F_T7_PL_PERR_PL) 8330 cause |= F_PL; 8331 if (perr & F_T7_PL_PERR_NCSI) 8332 cause |= F_NCSI; 8333 if (perr & F_T7_PL_PERR_MPS) 8334 cause |= F_MPS; 8335 if (perr & F_T7_PL_PERR_MI) 8336 cause |= F_MI; 8337 if (perr & F_T7_PL_PERR_DBG) 8338 cause |= F_DBG; 8339 if (perr & F_T7_PL_PERR_I2CM) 8340 cause |= F_I2CM; 8341 if (perr & F_T7_PL_PERR_CIM) 8342 cause |= F_CIM; 8343 8344 return (cause); 8345 } 8346 8347 static uint32_t 8348 t7_perr_to_ic2(uint32_t perr) 8349 { 8350 uint32_t cause = 0; 8351 8352 if (perr & F_T7_PL_PERR_CRYPTO_KEY) 8353 cause |= F_CRYPTO_KEY; 8354 if (perr & F_T7_PL_PERR_CRYPTO1) 8355 cause |= F_CRYPTO1; 8356 if (perr & F_T7_PL_PERR_CRYPTO0) 8357 cause |= F_CRYPTO0; 8358 if (perr & F_T7_PL_PERR_GCACHE) 8359 cause |= F_GCACHE; 8360 if (perr & F_T7_PL_PERR_ARM) 8361 cause |= F_ARM; 8362 8363 return (cause); 8364 } 8365 8366 /** 8367 * t4_slow_intr_handler - control path interrupt handler 8368 * @adap: the adapter 8369 * 8370 * T4 interrupt handler for non-data global interrupt events, e.g., errors. 8371 * The designation 'slow' is because it involves register reads, while 8372 * data interrupts typically don't involve any MMIOs. 8373 */ 8374 bool t4_slow_intr_handler(struct adapter *adap, int flags) 8375 { 8376 static const struct intr_details pl_int_cause_fields[] = { 8377 { F_MC1, "MC1" }, 8378 { F_UART, "UART" }, 8379 { F_ULP_TX, "ULP TX" }, 8380 { F_SGE, "SGE" }, 8381 { F_HMA, "HMA" }, 8382 { F_CPL_SWITCH, "CPL Switch" }, 8383 { F_ULP_RX, "ULP RX" }, 8384 { F_PM_RX, "PM RX" }, 8385 { F_PM_TX, "PM TX" }, 8386 { F_MA, "MA" }, 8387 { F_TP, "TP" }, 8388 { F_LE, "LE" }, 8389 { F_EDC1, "EDC1" }, 8390 { F_EDC0, "EDC0" }, 8391 { F_MC, "MC0" }, 8392 { F_PCIE, "PCIE" }, 8393 { F_PMU, "PMU" }, 8394 { F_MAC3, "MAC3" }, 8395 { F_MAC2, "MAC2" }, 8396 { F_MAC1, "MAC1" }, 8397 { F_MAC0, "MAC0" }, 8398 { F_SMB, "SMB" }, 8399 { F_SF, "SF" }, 8400 { F_PL, "PL" }, 8401 { F_NCSI, "NC-SI" }, 8402 { F_MPS, "MPS" }, 8403 { F_MI, "MI" }, 8404 { F_DBG, "DBG" }, 8405 { F_I2CM, "I2CM" }, 8406 { F_CIM, "CIM" }, 8407 { 0 } 8408 }; 8409 static const struct intr_action pl_int_cause_actions[] = { 8410 { F_ULP_TX, -1, ulptx_intr_handler }, 8411 { F_SGE, -1, sge_intr_handler }, 8412 { F_CPL_SWITCH, -1, cplsw_intr_handler }, 8413 { F_ULP_RX, -1, ulprx_intr_handler }, 8414 { F_PM_RX, -1, pmtx_intr_handler }, 8415 { F_PM_TX, -1, pmtx_intr_handler }, 8416 { F_MA, -1, ma_intr_handler }, 8417 { F_TP, -1, tp_intr_handler }, 8418 { F_LE, -1, le_intr_handler }, 8419 { F_EDC0, MEM_EDC0, mem_intr_handler }, 8420 { F_EDC1, MEM_EDC1, mem_intr_handler }, 8421 { F_MC0, MEM_MC0, mem_intr_handler }, 8422 { F_MC1, MEM_MC1, mem_intr_handler }, 8423 { F_PCIE, -1, pcie_intr_handler }, 8424 { F_MAC0, 0, mac_intr_handler }, 8425 { F_MAC1, 1, mac_intr_handler }, 8426 { F_MAC2, 2, mac_intr_handler }, 8427 { F_MAC3, 3, mac_intr_handler }, 8428 { F_SMB, -1, smb_intr_handler }, 8429 { F_PL, -1, plpl_intr_handler }, 8430 { F_NCSI, -1, ncsi_intr_handler }, 8431 { F_MPS, -1, mps_intr_handler }, 8432 { F_CIM, -1, cim_intr_handler }, 8433 { 0 } 8434 }; 8435 static const struct intr_info pl_int_cause = { 8436 .name = "PL_INT_CAUSE", 8437 .cause_reg = A_PL_INT_CAUSE, 8438 .enable_reg = A_PL_INT_ENABLE, 8439 .fatal = 0, 8440 .flags = IHF_IGNORE_IF_DISABLED, 8441 .details = pl_int_cause_fields, 8442 .actions = pl_int_cause_actions, 8443 }; 8444 static const struct intr_info pl_perr_cause = { 8445 .name = "PL_PERR_CAUSE", 8446 .cause_reg = A_PL_PERR_CAUSE, 8447 .enable_reg = A_PL_PERR_ENABLE, 8448 .fatal = 0xffffffff, 8449 .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED | 8450 IHF_CLR_DELAYED, 8451 .details = pl_int_cause_fields, 8452 .actions = NULL, 8453 }; 8454 static const struct intr_details t7_pl_int_cause_fields[] = { 8455 { F_T7_FLR, "FLR" }, 8456 { F_T7_SW_CIM, "SW CIM" }, 8457 { F_T7_ULP_TX, "ULP TX" }, 8458 { F_T7_SGE, "SGE" }, 8459 { F_T7_HMA, "HMA" }, 8460 { F_T7_CPL_SWITCH, "CPL Switch" }, 8461 { F_T7_ULP_RX, "ULP RX" }, 8462 { F_T7_PM_RX, "PM RX" }, 8463 { F_T7_PM_TX, "PM TX" }, 8464 { F_T7_MA, "MA" }, 8465 { F_T7_TP, "TP" }, 8466 { F_T7_LE, "LE" }, 8467 { F_T7_EDC1, "EDC1" }, 8468 { F_T7_EDC0, "EDC0" }, 8469 { F_T7_MC1, "MC1" }, 8470 { F_T7_MC0, "MC0" }, 8471 { F_T7_PCIE, "PCIE" }, 8472 { F_T7_UART, "UART" }, 8473 { F_PMU, "PMU" }, 8474 { F_MAC3, "MAC3" }, 8475 { F_MAC2, "MAC2" }, 8476 { F_MAC1, "MAC1" }, 8477 { F_MAC0, "MAC0" }, 8478 { F_SMB, "SMB" }, 8479 { F_SF, "SF" }, 8480 { F_PL, "PL" }, 8481 { F_NCSI, "NC-SI" }, 8482 { F_MPS, "MPS" }, 8483 { F_MI, "MI" }, 8484 { F_DBG, "DBG" }, 8485 { F_I2CM, "I2CM" }, 8486 { F_CIM, "CIM" }, 8487 { 0 } 8488 }; 8489 static const struct intr_action t7_pl_int_cause_actions[] = { 8490 { F_T7_ULP_TX, -1, ulptx_intr_handler }, 8491 { F_T7_SGE, -1, sge_intr_handler }, 8492 { F_T7_HMA, -1, hma_intr_handler }, 8493 { F_T7_CPL_SWITCH, -1, cplsw_intr_handler }, 8494 { F_T7_ULP_RX, -1, ulprx_intr_handler }, 8495 { F_T7_PM_RX, -1, pmrx_intr_handler }, 8496 { F_T7_PM_TX, -1, pmtx_intr_handler }, 8497 { F_T7_MA, -1, ma_intr_handler }, 8498 { F_T7_TP, -1, tp_intr_handler }, 8499 { F_T7_LE, -1, le_intr_handler }, 8500 { F_T7_EDC0, MEM_EDC0, mem_intr_handler }, 8501 { F_T7_EDC1, MEM_EDC1, mem_intr_handler }, 8502 { F_T7_MC0, MEM_MC0, mem_intr_handler }, 8503 { F_T7_MC1, MEM_MC1, mem_intr_handler }, 8504 { F_T7_PCIE, -1, pcie_intr_handler }, 8505 { F_MAC0, 0, mac_intr_handler }, 8506 { F_MAC1, 1, mac_intr_handler }, 8507 { F_MAC2, 2, mac_intr_handler }, 8508 { F_MAC3, 3, mac_intr_handler }, 8509 { F_SMB, -1, smb_intr_handler }, 8510 { F_PL, -1, plpl_intr_handler }, 8511 { F_NCSI, -1, ncsi_intr_handler }, 8512 { F_MPS, -1, mps_intr_handler }, 8513 { F_CIM, -1, cim_intr_handler }, 8514 { 0 } 8515 }; 8516 static const struct intr_info t7_pl_int_cause = { 8517 .name = "PL_INT_CAUSE", 8518 .cause_reg = A_PL_INT_CAUSE, 8519 .enable_reg = A_PL_INT_ENABLE, 8520 .fatal = 0, 8521 .flags = IHF_IGNORE_IF_DISABLED, 8522 .details = t7_pl_int_cause_fields, 8523 .actions = t7_pl_int_cause_actions, 8524 }; 8525 static const struct intr_details t7_pl_int_cause2_fields[] = { 8526 { F_CRYPTO_KEY, "CRYPTO KEY" }, 8527 { F_CRYPTO1, "CRYPTO1" }, 8528 { F_CRYPTO0, "CRYPTO0" }, 8529 { F_GCACHE, "GCACHE" }, 8530 { F_ARM, "ARM" }, 8531 { 0 } 8532 }; 8533 static const struct intr_action t7_pl_int_cause2_actions[] = { 8534 { F_CRYPTO_KEY, -1, cryptokey_intr_handler }, 8535 { F_CRYPTO1, 1, tlstx_intr_handler }, 8536 { F_CRYPTO0, 0, tlstx_intr_handler }, 8537 { F_GCACHE, -1, gcache_intr_handler }, 8538 { F_ARM, -1, arm_intr_handler }, 8539 { 0 } 8540 }; 8541 static const struct intr_info t7_pl_int_cause2 = { 8542 .name = "PL_INT_CAUSE2", 8543 .cause_reg = A_PL_INT_CAUSE2, 8544 .enable_reg = A_PL_INT_ENABLE2, 8545 .fatal = 0, 8546 .flags = IHF_IGNORE_IF_DISABLED, 8547 .details = t7_pl_int_cause2_fields, 8548 .actions = t7_pl_int_cause2_actions, 8549 }; 8550 static const struct intr_details t7_pl_perr_cause_fields[] = { 8551 { F_T7_PL_PERR_CRYPTO_KEY, "CRYPTO KEY" }, 8552 { F_T7_PL_PERR_CRYPTO1, "CRYPTO1" }, 8553 { F_T7_PL_PERR_CRYPTO0, "CRYPTO0" }, 8554 { F_T7_PL_PERR_GCACHE, "GCACHE" }, 8555 { F_T7_PL_PERR_ARM, "ARM" }, 8556 { F_T7_PL_PERR_ULP_TX, "ULP TX" }, 8557 { F_T7_PL_PERR_SGE, "SGE" }, 8558 { F_T7_PL_PERR_HMA, "HMA" }, 8559 { F_T7_PL_PERR_CPL_SWITCH, "CPL Switch" }, 8560 { F_T7_PL_PERR_ULP_RX, "ULP RX" }, 8561 { F_T7_PL_PERR_PM_RX, "PM RX" }, 8562 { F_T7_PL_PERR_PM_TX, "PM TX" }, 8563 { F_T7_PL_PERR_MA, "MA" }, 8564 { F_T7_PL_PERR_TP, "TP" }, 8565 { F_T7_PL_PERR_LE, "LE" }, 8566 { F_T7_PL_PERR_EDC1, "EDC1" }, 8567 { F_T7_PL_PERR_EDC0, "EDC0" }, 8568 { F_T7_PL_PERR_MC1, "MC1" }, 8569 { F_T7_PL_PERR_MC0, "MC0" }, 8570 { F_T7_PL_PERR_PCIE, "PCIE" }, 8571 { F_T7_PL_PERR_UART, "UART" }, 8572 { F_T7_PL_PERR_PMU, "PMU" }, 8573 { F_T7_PL_PERR_MAC, "MAC" }, 8574 { F_T7_PL_PERR_SMB, "SMB" }, 8575 { F_T7_PL_PERR_SF, "SF" }, 8576 { F_T7_PL_PERR_PL, "PL" }, 8577 { F_T7_PL_PERR_NCSI, "NC-SI" }, 8578 { F_T7_PL_PERR_MPS, "MPS" }, 8579 { F_T7_PL_PERR_MI, "MI" }, 8580 { F_T7_PL_PERR_DBG, "DBG" }, 8581 { F_T7_PL_PERR_I2CM, "I2CM" }, 8582 { F_T7_PL_PERR_CIM, "CIM" }, 8583 { 0 } 8584 }; 8585 static const struct intr_info t7_pl_perr_cause = { 8586 .name = "PL_PERR_CAUSE", 8587 .cause_reg = A_PL_PERR_CAUSE, 8588 .enable_reg = A_PL_PERR_ENABLE, 8589 .fatal = 0xffffffff, 8590 .flags = IHF_IGNORE_IF_DISABLED | IHF_FATAL_IFF_ENABLED | 8591 IHF_CLR_DELAYED, 8592 .details = t7_pl_perr_cause_fields, 8593 .actions = NULL, 8594 }; 8595 bool fatal = false; 8596 uint32_t perr; 8597 8598 if (chip_id(adap) < CHELSIO_T7) { 8599 perr = get_ucause(adap, &pl_perr_cause); 8600 fatal |= t4_handle_intr(adap, &pl_perr_cause, 0, flags); 8601 fatal |= t4_handle_intr(adap, &pl_int_cause, 8602 t4_perr_to_ic(adap, perr), flags); 8603 clear_int_cause_reg(adap, &pl_perr_cause, flags); 8604 } else { 8605 perr = get_ucause(adap, &t7_pl_perr_cause); 8606 fatal |= t4_handle_intr(adap, &t7_pl_perr_cause, 0, flags); 8607 fatal |= t4_handle_intr(adap, &t7_pl_int_cause, 8608 t7_perr_to_ic1(perr), flags); 8609 fatal |= t4_handle_intr(adap, &t7_pl_int_cause2, 8610 t7_perr_to_ic2(perr), flags); 8611 clear_int_cause_reg(adap, &t7_pl_perr_cause, flags); 8612 } 8613 return (fatal); 8614 } 8615 8616 void t4_intr_clear(struct adapter *adap) 8617 { 8618 #if 1 8619 if (chip_id(adap) >= CHELSIO_T7) 8620 t4_write_reg(adap, A_SGE_INT_CAUSE8, 0xffffffff); 8621 #endif 8622 (void)t4_slow_intr_handler(adap, 8623 IHF_NO_SHOW | IHF_RUN_ALL_ACTIONS | IHF_CLR_ALL_SET); 8624 } 8625 8626 /** 8627 * t4_intr_enable - enable interrupts 8628 * @adapter: the adapter whose interrupts should be enabled 8629 * 8630 * Enable PF-specific interrupts for the calling function and the top-level 8631 * interrupt concentrator for global interrupts. Interrupts are already 8632 * enabled at each module, here we just enable the roots of the interrupt 8633 * hierarchies. 8634 * 8635 * Note: this function should be called only when the driver manages 8636 * non PF-specific interrupts from the various HW modules. Only one PCI 8637 * function at a time should be doing this. 8638 */ 8639 void t4_intr_enable(struct adapter *adap) 8640 { 8641 u32 mask, val; 8642 8643 if (adap->intr_flags & IHF_INTR_CLEAR_ON_INIT) 8644 t4_intr_clear(adap); 8645 if (chip_id(adap) <= CHELSIO_T5) 8646 val = F_ERR_DROPPED_DB | F_ERR_EGR_CTXT_PRIO | F_DBFIFO_HP_INT | 8647 F_DBFIFO_LP_INT; 8648 else 8649 val = F_ERR_PCIE_ERROR0 | F_ERR_PCIE_ERROR1 | F_FATAL_WRE_LEN; 8650 val |= F_ERR_CPL_EXCEED_IQE_SIZE | F_ERR_INVALID_CIDX_INC | 8651 F_ERR_CPL_OPCODE_0 | F_ERR_DATA_CPL_ON_HIGH_QID1 | 8652 F_INGRESS_SIZE_ERR | F_ERR_DATA_CPL_ON_HIGH_QID0 | 8653 F_ERR_BAD_DB_PIDX3 | F_ERR_BAD_DB_PIDX2 | F_ERR_BAD_DB_PIDX1 | 8654 F_ERR_BAD_DB_PIDX0 | F_ERR_ING_CTXT_PRIO | F_EGRESS_SIZE_ERR; 8655 mask = val; 8656 t4_set_reg_field(adap, A_SGE_INT_ENABLE3, mask, val); 8657 if (chip_id(adap) >= CHELSIO_T7) 8658 t4_write_reg(adap, A_SGE_INT_ENABLE4, 0xffffffff); 8659 t4_write_reg(adap, MYPF_REG(A_PL_PF_INT_ENABLE), F_PFSW | F_PFCIM); 8660 t4_set_reg_field(adap, A_PL_INT_ENABLE, F_SF | F_I2CM, 0); 8661 #if 1 8662 if (chip_id(adap) >= CHELSIO_T7) 8663 t4_set_reg_field(adap, A_PL_INT_ENABLE, F_MAC0 | F_MAC1 | F_MAC2 | F_MAC3, 0); 8664 #endif 8665 t4_set_reg_field(adap, A_PL_INT_MAP0, 0, 1 << adap->pf); 8666 } 8667 8668 /** 8669 * t4_intr_disable - disable interrupts 8670 * @adap: the adapter whose interrupts should be disabled 8671 * 8672 * Disable interrupts. We only disable the top-level interrupt 8673 * concentrators. The caller must be a PCI function managing global 8674 * interrupts. 8675 */ 8676 void t4_intr_disable(struct adapter *adap) 8677 { 8678 8679 t4_write_reg(adap, MYPF_REG(A_PL_PF_INT_ENABLE), 0); 8680 t4_set_reg_field(adap, A_PL_INT_MAP0, 1 << adap->pf, 0); 8681 } 8682 8683 /** 8684 * hash_mac_addr - return the hash value of a MAC address 8685 * @addr: the 48-bit Ethernet MAC address 8686 * 8687 * Hashes a MAC address according to the hash function used by HW inexact 8688 * (hash) address matching. 8689 */ 8690 static int hash_mac_addr(const u8 *addr) 8691 { 8692 u32 a = ((u32)addr[0] << 16) | ((u32)addr[1] << 8) | addr[2]; 8693 u32 b = ((u32)addr[3] << 16) | ((u32)addr[4] << 8) | addr[5]; 8694 a ^= b; 8695 a ^= (a >> 12); 8696 a ^= (a >> 6); 8697 return a & 0x3f; 8698 } 8699 8700 /** 8701 * t4_config_rss_range - configure a portion of the RSS mapping table 8702 * @adapter: the adapter 8703 * @mbox: mbox to use for the FW command 8704 * @viid: virtual interface whose RSS subtable is to be written 8705 * @start: start entry in the table to write 8706 * @n: how many table entries to write 8707 * @rspq: values for the "response queue" (Ingress Queue) lookup table 8708 * @nrspq: number of values in @rspq 8709 * 8710 * Programs the selected part of the VI's RSS mapping table with the 8711 * provided values. If @nrspq < @n the supplied values are used repeatedly 8712 * until the full table range is populated. 8713 * 8714 * The caller must ensure the values in @rspq are in the range allowed for 8715 * @viid. 8716 */ 8717 int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid, 8718 int start, int n, const u16 *rspq, unsigned int nrspq) 8719 { 8720 int ret; 8721 const u16 *rsp = rspq; 8722 const u16 *rsp_end = rspq + nrspq; 8723 struct fw_rss_ind_tbl_cmd cmd; 8724 8725 memset(&cmd, 0, sizeof(cmd)); 8726 cmd.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_RSS_IND_TBL_CMD) | 8727 F_FW_CMD_REQUEST | F_FW_CMD_WRITE | 8728 V_FW_RSS_IND_TBL_CMD_VIID(viid)); 8729 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); 8730 8731 /* 8732 * Each firmware RSS command can accommodate up to 32 RSS Ingress 8733 * Queue Identifiers. These Ingress Queue IDs are packed three to 8734 * a 32-bit word as 10-bit values with the upper remaining 2 bits 8735 * reserved. 8736 */ 8737 while (n > 0) { 8738 int nq = min(n, 32); 8739 int nq_packed = 0; 8740 __be32 *qp = &cmd.iq0_to_iq2; 8741 8742 /* 8743 * Set up the firmware RSS command header to send the next 8744 * "nq" Ingress Queue IDs to the firmware. 8745 */ 8746 cmd.niqid = cpu_to_be16(nq); 8747 cmd.startidx = cpu_to_be16(start); 8748 8749 /* 8750 * "nq" more done for the start of the next loop. 8751 */ 8752 start += nq; 8753 n -= nq; 8754 8755 /* 8756 * While there are still Ingress Queue IDs to stuff into the 8757 * current firmware RSS command, retrieve them from the 8758 * Ingress Queue ID array and insert them into the command. 8759 */ 8760 while (nq > 0) { 8761 /* 8762 * Grab up to the next 3 Ingress Queue IDs (wrapping 8763 * around the Ingress Queue ID array if necessary) and 8764 * insert them into the firmware RSS command at the 8765 * current 3-tuple position within the commad. 8766 */ 8767 u16 qbuf[3]; 8768 u16 *qbp = qbuf; 8769 int nqbuf = min(3, nq); 8770 8771 nq -= nqbuf; 8772 qbuf[0] = qbuf[1] = qbuf[2] = 0; 8773 while (nqbuf && nq_packed < 32) { 8774 nqbuf--; 8775 nq_packed++; 8776 *qbp++ = *rsp++; 8777 if (rsp >= rsp_end) 8778 rsp = rspq; 8779 } 8780 *qp++ = cpu_to_be32(V_FW_RSS_IND_TBL_CMD_IQ0(qbuf[0]) | 8781 V_FW_RSS_IND_TBL_CMD_IQ1(qbuf[1]) | 8782 V_FW_RSS_IND_TBL_CMD_IQ2(qbuf[2])); 8783 } 8784 8785 /* 8786 * Send this portion of the RRS table update to the firmware; 8787 * bail out on any errors. 8788 */ 8789 ret = t4_wr_mbox(adapter, mbox, &cmd, sizeof(cmd), NULL); 8790 if (ret) 8791 return ret; 8792 } 8793 return 0; 8794 } 8795 8796 /** 8797 * t4_config_glbl_rss - configure the global RSS mode 8798 * @adapter: the adapter 8799 * @mbox: mbox to use for the FW command 8800 * @mode: global RSS mode 8801 * @flags: mode-specific flags 8802 * 8803 * Sets the global RSS mode. 8804 */ 8805 int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode, 8806 unsigned int flags) 8807 { 8808 struct fw_rss_glb_config_cmd c; 8809 8810 memset(&c, 0, sizeof(c)); 8811 c.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) | 8812 F_FW_CMD_REQUEST | F_FW_CMD_WRITE); 8813 c.retval_len16 = cpu_to_be32(FW_LEN16(c)); 8814 if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL) { 8815 c.u.manual.mode_pkd = 8816 cpu_to_be32(V_FW_RSS_GLB_CONFIG_CMD_MODE(mode)); 8817 } else if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL) { 8818 c.u.basicvirtual.mode_keymode = 8819 cpu_to_be32(V_FW_RSS_GLB_CONFIG_CMD_MODE(mode)); 8820 c.u.basicvirtual.synmapen_to_hashtoeplitz = cpu_to_be32(flags); 8821 } else 8822 return -EINVAL; 8823 return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL); 8824 } 8825 8826 /** 8827 * t4_config_vi_rss - configure per VI RSS settings 8828 * @adapter: the adapter 8829 * @mbox: mbox to use for the FW command 8830 * @viid: the VI id 8831 * @flags: RSS flags 8832 * @defq: id of the default RSS queue for the VI. 8833 * @skeyidx: RSS secret key table index for non-global mode 8834 * @skey: RSS vf_scramble key for VI. 8835 * 8836 * Configures VI-specific RSS properties. 8837 */ 8838 int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid, 8839 unsigned int flags, unsigned int defq, unsigned int skeyidx, 8840 unsigned int skey) 8841 { 8842 struct fw_rss_vi_config_cmd c; 8843 8844 memset(&c, 0, sizeof(c)); 8845 c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_RSS_VI_CONFIG_CMD) | 8846 F_FW_CMD_REQUEST | F_FW_CMD_WRITE | 8847 V_FW_RSS_VI_CONFIG_CMD_VIID(viid)); 8848 c.retval_len16 = cpu_to_be32(FW_LEN16(c)); 8849 c.u.basicvirtual.defaultq_to_udpen = cpu_to_be32(flags | 8850 V_FW_RSS_VI_CONFIG_CMD_DEFAULTQ(defq)); 8851 c.u.basicvirtual.secretkeyidx_pkd = cpu_to_be32( 8852 V_FW_RSS_VI_CONFIG_CMD_SECRETKEYIDX(skeyidx)); 8853 c.u.basicvirtual.secretkeyxor = cpu_to_be32(skey); 8854 8855 return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL); 8856 } 8857 8858 /* Read an RSS table row */ 8859 static int rd_rss_row(struct adapter *adap, int row, u32 *val) 8860 { 8861 if (chip_id(adap) < CHELSIO_T7) { 8862 t4_write_reg(adap, A_TP_RSS_LKP_TABLE, 0xfff00000 | row); 8863 return t4_wait_op_done_val(adap, A_TP_RSS_LKP_TABLE, 8864 F_LKPTBLROWVLD, 1, 5, 0, val); 8865 } else { 8866 t4_write_reg(adap, A_TP_RSS_CONFIG_SRAM, 0xB0000 | row); 8867 return t7_wait_sram_done(adap, A_TP_RSS_CONFIG_SRAM, 8868 A_TP_RSS_LKP_TABLE, 5, 0, val); 8869 } 8870 } 8871 8872 /** 8873 * t4_read_rss - read the contents of the RSS mapping table 8874 * @adapter: the adapter 8875 * @map: holds the contents of the RSS mapping table 8876 * 8877 * Reads the contents of the RSS hash->queue mapping table. 8878 */ 8879 int t4_read_rss(struct adapter *adapter, u16 *map) 8880 { 8881 u32 val; 8882 int i, ret; 8883 int rss_nentries = adapter->chip_params->rss_nentries; 8884 8885 for (i = 0; i < rss_nentries / 2; ++i) { 8886 ret = rd_rss_row(adapter, i, &val); 8887 if (ret) 8888 return ret; 8889 *map++ = G_LKPTBLQUEUE0(val); 8890 *map++ = G_LKPTBLQUEUE1(val); 8891 } 8892 return 0; 8893 } 8894 8895 /** 8896 * t4_tp_fw_ldst_rw - Access TP indirect register through LDST 8897 * @adap: the adapter 8898 * @cmd: TP fw ldst address space type 8899 * @vals: where the indirect register values are stored/written 8900 * @nregs: how many indirect registers to read/write 8901 * @start_idx: index of first indirect register to read/write 8902 * @rw: Read (1) or Write (0) 8903 * @sleep_ok: if true we may sleep while awaiting command completion 8904 * 8905 * Access TP indirect registers through LDST 8906 **/ 8907 static int t4_tp_fw_ldst_rw(struct adapter *adap, int cmd, u32 *vals, 8908 unsigned int nregs, unsigned int start_index, 8909 unsigned int rw, bool sleep_ok) 8910 { 8911 int ret = 0; 8912 unsigned int i; 8913 struct fw_ldst_cmd c; 8914 8915 for (i = 0; i < nregs; i++) { 8916 memset(&c, 0, sizeof(c)); 8917 c.op_to_addrspace = cpu_to_be32(V_FW_CMD_OP(FW_LDST_CMD) | 8918 F_FW_CMD_REQUEST | 8919 (rw ? F_FW_CMD_READ : 8920 F_FW_CMD_WRITE) | 8921 V_FW_LDST_CMD_ADDRSPACE(cmd)); 8922 c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c)); 8923 8924 c.u.addrval.addr = cpu_to_be32(start_index + i); 8925 c.u.addrval.val = rw ? 0 : cpu_to_be32(vals[i]); 8926 ret = t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c, 8927 sleep_ok); 8928 if (ret) 8929 return ret; 8930 8931 if (rw) 8932 vals[i] = be32_to_cpu(c.u.addrval.val); 8933 } 8934 return 0; 8935 } 8936 8937 /** 8938 * t4_tp_indirect_rw - Read/Write TP indirect register through LDST or backdoor 8939 * @adap: the adapter 8940 * @reg_addr: Address Register 8941 * @reg_data: Data register 8942 * @buff: where the indirect register values are stored/written 8943 * @nregs: how many indirect registers to read/write 8944 * @start_index: index of first indirect register to read/write 8945 * @rw: READ(1) or WRITE(0) 8946 * @sleep_ok: if true we may sleep while awaiting command completion 8947 * 8948 * Read/Write TP indirect registers through LDST if possible. 8949 * Else, use backdoor access 8950 **/ 8951 static void t4_tp_indirect_rw(struct adapter *adap, u32 reg_addr, u32 reg_data, 8952 u32 *buff, u32 nregs, u32 start_index, int rw, 8953 bool sleep_ok) 8954 { 8955 int rc = -EINVAL; 8956 int cmd; 8957 8958 switch (reg_addr) { 8959 case A_TP_PIO_ADDR: 8960 cmd = FW_LDST_ADDRSPC_TP_PIO; 8961 break; 8962 case A_TP_TM_PIO_ADDR: 8963 cmd = FW_LDST_ADDRSPC_TP_TM_PIO; 8964 break; 8965 case A_TP_MIB_INDEX: 8966 cmd = FW_LDST_ADDRSPC_TP_MIB; 8967 break; 8968 default: 8969 goto indirect_access; 8970 } 8971 8972 if (t4_use_ldst(adap)) 8973 rc = t4_tp_fw_ldst_rw(adap, cmd, buff, nregs, start_index, rw, 8974 sleep_ok); 8975 8976 indirect_access: 8977 8978 if (rc) { 8979 if (rw) 8980 t4_read_indirect(adap, reg_addr, reg_data, buff, nregs, 8981 start_index); 8982 else 8983 t4_write_indirect(adap, reg_addr, reg_data, buff, nregs, 8984 start_index); 8985 } 8986 } 8987 8988 /** 8989 * t4_tp_pio_read - Read TP PIO registers 8990 * @adap: the adapter 8991 * @buff: where the indirect register values are written 8992 * @nregs: how many indirect registers to read 8993 * @start_index: index of first indirect register to read 8994 * @sleep_ok: if true we may sleep while awaiting command completion 8995 * 8996 * Read TP PIO Registers 8997 **/ 8998 void t4_tp_pio_read(struct adapter *adap, u32 *buff, u32 nregs, 8999 u32 start_index, bool sleep_ok) 9000 { 9001 t4_tp_indirect_rw(adap, A_TP_PIO_ADDR, A_TP_PIO_DATA, buff, nregs, 9002 start_index, 1, sleep_ok); 9003 } 9004 9005 /** 9006 * t4_tp_pio_write - Write TP PIO registers 9007 * @adap: the adapter 9008 * @buff: where the indirect register values are stored 9009 * @nregs: how many indirect registers to write 9010 * @start_index: index of first indirect register to write 9011 * @sleep_ok: if true we may sleep while awaiting command completion 9012 * 9013 * Write TP PIO Registers 9014 **/ 9015 void t4_tp_pio_write(struct adapter *adap, const u32 *buff, u32 nregs, 9016 u32 start_index, bool sleep_ok) 9017 { 9018 t4_tp_indirect_rw(adap, A_TP_PIO_ADDR, A_TP_PIO_DATA, 9019 __DECONST(u32 *, buff), nregs, start_index, 0, sleep_ok); 9020 } 9021 9022 /** 9023 * t4_tp_tm_pio_read - Read TP TM PIO registers 9024 * @adap: the adapter 9025 * @buff: where the indirect register values are written 9026 * @nregs: how many indirect registers to read 9027 * @start_index: index of first indirect register to read 9028 * @sleep_ok: if true we may sleep while awaiting command completion 9029 * 9030 * Read TP TM PIO Registers 9031 **/ 9032 void t4_tp_tm_pio_read(struct adapter *adap, u32 *buff, u32 nregs, 9033 u32 start_index, bool sleep_ok) 9034 { 9035 t4_tp_indirect_rw(adap, A_TP_TM_PIO_ADDR, A_TP_TM_PIO_DATA, buff, 9036 nregs, start_index, 1, sleep_ok); 9037 } 9038 9039 /** 9040 * t4_tp_mib_read - Read TP MIB registers 9041 * @adap: the adapter 9042 * @buff: where the indirect register values are written 9043 * @nregs: how many indirect registers to read 9044 * @start_index: index of first indirect register to read 9045 * @sleep_ok: if true we may sleep while awaiting command completion 9046 * 9047 * Read TP MIB Registers 9048 **/ 9049 void t4_tp_mib_read(struct adapter *adap, u32 *buff, u32 nregs, u32 start_index, 9050 bool sleep_ok) 9051 { 9052 t4_tp_indirect_rw(adap, A_TP_MIB_INDEX, A_TP_MIB_DATA, buff, nregs, 9053 start_index, 1, sleep_ok); 9054 } 9055 9056 /** 9057 * t4_read_rss_key - read the global RSS key 9058 * @adap: the adapter 9059 * @key: 10-entry array holding the 320-bit RSS key 9060 * @sleep_ok: if true we may sleep while awaiting command completion 9061 * 9062 * Reads the global 320-bit RSS key. 9063 */ 9064 void t4_read_rss_key(struct adapter *adap, u32 *key, bool sleep_ok) 9065 { 9066 t4_tp_pio_read(adap, key, 10, A_TP_RSS_SECRET_KEY0, sleep_ok); 9067 } 9068 9069 /** 9070 * t4_write_rss_key - program one of the RSS keys 9071 * @adap: the adapter 9072 * @key: 10-entry array holding the 320-bit RSS key 9073 * @idx: which RSS key to write 9074 * @sleep_ok: if true we may sleep while awaiting command completion 9075 * 9076 * Writes one of the RSS keys with the given 320-bit value. If @idx is 9077 * 0..15 the corresponding entry in the RSS key table is written, 9078 * otherwise the global RSS key is written. 9079 */ 9080 void t4_write_rss_key(struct adapter *adap, const u32 *key, int idx, 9081 bool sleep_ok) 9082 { 9083 u8 rss_key_addr_cnt = 16; 9084 u32 vrt = t4_read_reg(adap, A_TP_RSS_CONFIG_VRT); 9085 9086 /* 9087 * T6 and later: for KeyMode 3 (per-vf and per-vf scramble), 9088 * allows access to key addresses 16-63 by using KeyWrAddrX 9089 * as index[5:4](upper 2) into key table 9090 */ 9091 if ((chip_id(adap) > CHELSIO_T5) && 9092 (vrt & F_KEYEXTEND) && (G_KEYMODE(vrt) == 3)) 9093 rss_key_addr_cnt = 32; 9094 9095 t4_tp_pio_write(adap, key, 10, A_TP_RSS_SECRET_KEY0, sleep_ok); 9096 9097 if (idx >= 0 && idx < rss_key_addr_cnt) { 9098 if (rss_key_addr_cnt > 16) 9099 t4_write_reg(adap, A_TP_RSS_CONFIG_VRT, 9100 vrt | V_KEYWRADDRX(idx >> 4) | 9101 V_T6_VFWRADDR(idx) | F_KEYWREN); 9102 else 9103 t4_write_reg(adap, A_TP_RSS_CONFIG_VRT, 9104 vrt| V_KEYWRADDR(idx) | F_KEYWREN); 9105 } 9106 } 9107 9108 /** 9109 * t4_read_rss_pf_config - read PF RSS Configuration Table 9110 * @adapter: the adapter 9111 * @index: the entry in the PF RSS table to read 9112 * @valp: where to store the returned value 9113 * @sleep_ok: if true we may sleep while awaiting command completion 9114 * 9115 * Reads the PF RSS Configuration Table at the specified index and returns 9116 * the value found there. 9117 */ 9118 void t4_read_rss_pf_config(struct adapter *adapter, unsigned int index, 9119 u32 *valp, bool sleep_ok) 9120 { 9121 t4_tp_pio_read(adapter, valp, 1, A_TP_RSS_PF0_CONFIG + index, sleep_ok); 9122 } 9123 9124 /** 9125 * t4_write_rss_pf_config - write PF RSS Configuration Table 9126 * @adapter: the adapter 9127 * @index: the entry in the VF RSS table to read 9128 * @val: the value to store 9129 * @sleep_ok: if true we may sleep while awaiting command completion 9130 * 9131 * Writes the PF RSS Configuration Table at the specified index with the 9132 * specified value. 9133 */ 9134 void t4_write_rss_pf_config(struct adapter *adapter, unsigned int index, 9135 u32 val, bool sleep_ok) 9136 { 9137 t4_tp_pio_write(adapter, &val, 1, A_TP_RSS_PF0_CONFIG + index, 9138 sleep_ok); 9139 } 9140 9141 /** 9142 * t4_read_rss_vf_config - read VF RSS Configuration Table 9143 * @adapter: the adapter 9144 * @index: the entry in the VF RSS table to read 9145 * @vfl: where to store the returned VFL 9146 * @vfh: where to store the returned VFH 9147 * @sleep_ok: if true we may sleep while awaiting command completion 9148 * 9149 * Reads the VF RSS Configuration Table at the specified index and returns 9150 * the (VFL, VFH) values found there. 9151 */ 9152 void t4_read_rss_vf_config(struct adapter *adapter, unsigned int index, 9153 u32 *vfl, u32 *vfh, bool sleep_ok) 9154 { 9155 u32 vrt, mask, data; 9156 9157 if (chip_id(adapter) <= CHELSIO_T5) { 9158 mask = V_VFWRADDR(M_VFWRADDR); 9159 data = V_VFWRADDR(index); 9160 } else { 9161 mask = V_T6_VFWRADDR(M_T6_VFWRADDR); 9162 data = V_T6_VFWRADDR(index); 9163 } 9164 /* 9165 * Request that the index'th VF Table values be read into VFL/VFH. 9166 */ 9167 vrt = t4_read_reg(adapter, A_TP_RSS_CONFIG_VRT); 9168 vrt &= ~(F_VFRDRG | F_VFWREN | F_KEYWREN | mask); 9169 vrt |= data | F_VFRDEN; 9170 t4_write_reg(adapter, A_TP_RSS_CONFIG_VRT, vrt); 9171 9172 /* 9173 * Grab the VFL/VFH values ... 9174 */ 9175 t4_tp_pio_read(adapter, vfl, 1, A_TP_RSS_VFL_CONFIG, sleep_ok); 9176 t4_tp_pio_read(adapter, vfh, 1, A_TP_RSS_VFH_CONFIG, sleep_ok); 9177 } 9178 9179 /** 9180 * t4_write_rss_vf_config - write VF RSS Configuration Table 9181 * 9182 * @adapter: the adapter 9183 * @index: the entry in the VF RSS table to write 9184 * @vfl: the VFL to store 9185 * @vfh: the VFH to store 9186 * 9187 * Writes the VF RSS Configuration Table at the specified index with the 9188 * specified (VFL, VFH) values. 9189 */ 9190 void t4_write_rss_vf_config(struct adapter *adapter, unsigned int index, 9191 u32 vfl, u32 vfh, bool sleep_ok) 9192 { 9193 u32 vrt, mask, data; 9194 9195 if (chip_id(adapter) <= CHELSIO_T5) { 9196 mask = V_VFWRADDR(M_VFWRADDR); 9197 data = V_VFWRADDR(index); 9198 } else { 9199 mask = V_T6_VFWRADDR(M_T6_VFWRADDR); 9200 data = V_T6_VFWRADDR(index); 9201 } 9202 9203 /* 9204 * Load up VFL/VFH with the values to be written ... 9205 */ 9206 t4_tp_pio_write(adapter, &vfl, 1, A_TP_RSS_VFL_CONFIG, sleep_ok); 9207 t4_tp_pio_write(adapter, &vfh, 1, A_TP_RSS_VFH_CONFIG, sleep_ok); 9208 9209 /* 9210 * Write the VFL/VFH into the VF Table at index'th location. 9211 */ 9212 vrt = t4_read_reg(adapter, A_TP_RSS_CONFIG_VRT); 9213 vrt &= ~(F_VFRDRG | F_VFWREN | F_KEYWREN | mask); 9214 vrt |= data | F_VFRDEN; 9215 t4_write_reg(adapter, A_TP_RSS_CONFIG_VRT, vrt); 9216 } 9217 9218 /** 9219 * t4_read_rss_pf_map - read PF RSS Map 9220 * @adapter: the adapter 9221 * @sleep_ok: if true we may sleep while awaiting command completion 9222 * 9223 * Reads the PF RSS Map register and returns its value. 9224 */ 9225 u32 t4_read_rss_pf_map(struct adapter *adapter, bool sleep_ok) 9226 { 9227 u32 pfmap; 9228 9229 t4_tp_pio_read(adapter, &pfmap, 1, A_TP_RSS_PF_MAP, sleep_ok); 9230 9231 return pfmap; 9232 } 9233 9234 /** 9235 * t4_write_rss_pf_map - write PF RSS Map 9236 * @adapter: the adapter 9237 * @pfmap: PF RSS Map value 9238 * 9239 * Writes the specified value to the PF RSS Map register. 9240 */ 9241 void t4_write_rss_pf_map(struct adapter *adapter, u32 pfmap, bool sleep_ok) 9242 { 9243 t4_tp_pio_write(adapter, &pfmap, 1, A_TP_RSS_PF_MAP, sleep_ok); 9244 } 9245 9246 /** 9247 * t4_read_rss_pf_mask - read PF RSS Mask 9248 * @adapter: the adapter 9249 * @sleep_ok: if true we may sleep while awaiting command completion 9250 * 9251 * Reads the PF RSS Mask register and returns its value. 9252 */ 9253 u32 t4_read_rss_pf_mask(struct adapter *adapter, bool sleep_ok) 9254 { 9255 u32 pfmask; 9256 9257 t4_tp_pio_read(adapter, &pfmask, 1, A_TP_RSS_PF_MSK, sleep_ok); 9258 9259 return pfmask; 9260 } 9261 9262 /** 9263 * t4_write_rss_pf_mask - write PF RSS Mask 9264 * @adapter: the adapter 9265 * @pfmask: PF RSS Mask value 9266 * 9267 * Writes the specified value to the PF RSS Mask register. 9268 */ 9269 void t4_write_rss_pf_mask(struct adapter *adapter, u32 pfmask, bool sleep_ok) 9270 { 9271 t4_tp_pio_write(adapter, &pfmask, 1, A_TP_RSS_PF_MSK, sleep_ok); 9272 } 9273 9274 /** 9275 * t4_tp_get_tcp_stats - read TP's TCP MIB counters 9276 * @adap: the adapter 9277 * @v4: holds the TCP/IP counter values 9278 * @v6: holds the TCP/IPv6 counter values 9279 * @sleep_ok: if true we may sleep while awaiting command completion 9280 * 9281 * Returns the values of TP's TCP/IP and TCP/IPv6 MIB counters. 9282 * Either @v4 or @v6 may be %NULL to skip the corresponding stats. 9283 */ 9284 void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4, 9285 struct tp_tcp_stats *v6, bool sleep_ok) 9286 { 9287 u32 val[A_TP_MIB_TCP_RXT_SEG_LO - A_TP_MIB_TCP_OUT_RST + 1]; 9288 9289 #define STAT_IDX(x) ((A_TP_MIB_TCP_##x) - A_TP_MIB_TCP_OUT_RST) 9290 #define STAT(x) val[STAT_IDX(x)] 9291 #define STAT64(x) (((u64)STAT(x##_HI) << 32) | STAT(x##_LO)) 9292 9293 if (v4) { 9294 t4_tp_mib_read(adap, val, ARRAY_SIZE(val), 9295 A_TP_MIB_TCP_OUT_RST, sleep_ok); 9296 v4->tcp_out_rsts = STAT(OUT_RST); 9297 v4->tcp_in_segs = STAT64(IN_SEG); 9298 v4->tcp_out_segs = STAT64(OUT_SEG); 9299 v4->tcp_retrans_segs = STAT64(RXT_SEG); 9300 } 9301 if (v6) { 9302 t4_tp_mib_read(adap, val, ARRAY_SIZE(val), 9303 A_TP_MIB_TCP_V6OUT_RST, sleep_ok); 9304 v6->tcp_out_rsts = STAT(OUT_RST); 9305 v6->tcp_in_segs = STAT64(IN_SEG); 9306 v6->tcp_out_segs = STAT64(OUT_SEG); 9307 v6->tcp_retrans_segs = STAT64(RXT_SEG); 9308 } 9309 #undef STAT64 9310 #undef STAT 9311 #undef STAT_IDX 9312 } 9313 9314 /** 9315 * t4_tp_get_err_stats - read TP's error MIB counters 9316 * @adap: the adapter 9317 * @st: holds the counter values 9318 * @sleep_ok: if true we may sleep while awaiting command completion 9319 * 9320 * Returns the values of TP's error counters. 9321 */ 9322 void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st, 9323 bool sleep_ok) 9324 { 9325 int nchan = adap->chip_params->nchan; 9326 9327 t4_tp_mib_read(adap, st->mac_in_errs, nchan, A_TP_MIB_MAC_IN_ERR_0, 9328 sleep_ok); 9329 9330 t4_tp_mib_read(adap, st->hdr_in_errs, nchan, A_TP_MIB_HDR_IN_ERR_0, 9331 sleep_ok); 9332 9333 t4_tp_mib_read(adap, st->tcp_in_errs, nchan, A_TP_MIB_TCP_IN_ERR_0, 9334 sleep_ok); 9335 9336 t4_tp_mib_read(adap, st->tnl_cong_drops, nchan, 9337 A_TP_MIB_TNL_CNG_DROP_0, sleep_ok); 9338 9339 t4_tp_mib_read(adap, st->ofld_chan_drops, nchan, 9340 A_TP_MIB_OFD_CHN_DROP_0, sleep_ok); 9341 9342 t4_tp_mib_read(adap, st->tnl_tx_drops, nchan, A_TP_MIB_TNL_DROP_0, 9343 sleep_ok); 9344 9345 t4_tp_mib_read(adap, st->ofld_vlan_drops, nchan, 9346 A_TP_MIB_OFD_VLN_DROP_0, sleep_ok); 9347 9348 t4_tp_mib_read(adap, st->tcp6_in_errs, nchan, 9349 A_TP_MIB_TCP_V6IN_ERR_0, sleep_ok); 9350 9351 t4_tp_mib_read(adap, &st->ofld_no_neigh, 2, A_TP_MIB_OFD_ARP_DROP, 9352 sleep_ok); 9353 } 9354 9355 /** 9356 * t4_tp_get_err_stats - read TP's error MIB counters 9357 * @adap: the adapter 9358 * @st: holds the counter values 9359 * @sleep_ok: if true we may sleep while awaiting command completion 9360 * 9361 * Returns the values of TP's error counters. 9362 */ 9363 void t4_tp_get_tnl_stats(struct adapter *adap, struct tp_tnl_stats *st, 9364 bool sleep_ok) 9365 { 9366 int nchan = adap->chip_params->nchan; 9367 9368 t4_tp_mib_read(adap, st->out_pkt, nchan, A_TP_MIB_TNL_OUT_PKT_0, 9369 sleep_ok); 9370 t4_tp_mib_read(adap, st->in_pkt, nchan, A_TP_MIB_TNL_IN_PKT_0, 9371 sleep_ok); 9372 } 9373 9374 /** 9375 * t4_tp_get_proxy_stats - read TP's proxy MIB counters 9376 * @adap: the adapter 9377 * @st: holds the counter values 9378 * 9379 * Returns the values of TP's proxy counters. 9380 */ 9381 void t4_tp_get_proxy_stats(struct adapter *adap, struct tp_proxy_stats *st, 9382 bool sleep_ok) 9383 { 9384 int nchan = adap->chip_params->nchan; 9385 9386 t4_tp_mib_read(adap, st->proxy, nchan, A_TP_MIB_TNL_LPBK_0, sleep_ok); 9387 } 9388 9389 /** 9390 * t4_tp_get_cpl_stats - read TP's CPL MIB counters 9391 * @adap: the adapter 9392 * @st: holds the counter values 9393 * @sleep_ok: if true we may sleep while awaiting command completion 9394 * 9395 * Returns the values of TP's CPL counters. 9396 */ 9397 void t4_tp_get_cpl_stats(struct adapter *adap, struct tp_cpl_stats *st, 9398 bool sleep_ok) 9399 { 9400 int nchan = adap->chip_params->nchan; 9401 9402 t4_tp_mib_read(adap, st->req, nchan, A_TP_MIB_CPL_IN_REQ_0, sleep_ok); 9403 9404 t4_tp_mib_read(adap, st->rsp, nchan, A_TP_MIB_CPL_OUT_RSP_0, sleep_ok); 9405 } 9406 9407 /** 9408 * t4_tp_get_rdma_stats - read TP's RDMA MIB counters 9409 * @adap: the adapter 9410 * @st: holds the counter values 9411 * 9412 * Returns the values of TP's RDMA counters. 9413 */ 9414 void t4_tp_get_rdma_stats(struct adapter *adap, struct tp_rdma_stats *st, 9415 bool sleep_ok) 9416 { 9417 t4_tp_mib_read(adap, &st->rqe_dfr_pkt, 2, A_TP_MIB_RQE_DFR_PKT, 9418 sleep_ok); 9419 9420 if (chip_id(adap) >= CHELSIO_T7) 9421 /* read RDMA stats IN and OUT for all ports at once */ 9422 t4_tp_mib_read(adap, &st->pkts_in[0], 28, A_TP_MIB_RDMA_IN_PKT_0, 9423 sleep_ok); 9424 } 9425 9426 /** 9427 * t4_get_fcoe_stats - read TP's FCoE MIB counters for a port 9428 * @adap: the adapter 9429 * @idx: the port index 9430 * @st: holds the counter values 9431 * @sleep_ok: if true we may sleep while awaiting command completion 9432 * 9433 * Returns the values of TP's FCoE counters for the selected port. 9434 */ 9435 void t4_get_fcoe_stats(struct adapter *adap, unsigned int idx, 9436 struct tp_fcoe_stats *st, bool sleep_ok) 9437 { 9438 u32 val[2]; 9439 9440 t4_tp_mib_read(adap, &st->frames_ddp, 1, A_TP_MIB_FCOE_DDP_0 + idx, 9441 sleep_ok); 9442 9443 t4_tp_mib_read(adap, &st->frames_drop, 1, 9444 A_TP_MIB_FCOE_DROP_0 + idx, sleep_ok); 9445 9446 t4_tp_mib_read(adap, val, 2, A_TP_MIB_FCOE_BYTE_0_HI + 2 * idx, 9447 sleep_ok); 9448 9449 st->octets_ddp = ((u64)val[0] << 32) | val[1]; 9450 } 9451 9452 /** 9453 * t4_get_usm_stats - read TP's non-TCP DDP MIB counters 9454 * @adap: the adapter 9455 * @st: holds the counter values 9456 * @sleep_ok: if true we may sleep while awaiting command completion 9457 * 9458 * Returns the values of TP's counters for non-TCP directly-placed packets. 9459 */ 9460 void t4_get_usm_stats(struct adapter *adap, struct tp_usm_stats *st, 9461 bool sleep_ok) 9462 { 9463 u32 val[4]; 9464 9465 t4_tp_mib_read(adap, val, 4, A_TP_MIB_USM_PKTS, sleep_ok); 9466 9467 st->frames = val[0]; 9468 st->drops = val[1]; 9469 st->octets = ((u64)val[2] << 32) | val[3]; 9470 } 9471 9472 /** 9473 * t4_tp_get_tid_stats - read TP's tid MIB counters. 9474 * @adap: the adapter 9475 * @st: holds the counter values 9476 * @sleep_ok: if true we may sleep while awaiting command completion 9477 * 9478 * Returns the values of TP's counters for tids. 9479 */ 9480 void t4_tp_get_tid_stats(struct adapter *adap, struct tp_tid_stats *st, 9481 bool sleep_ok) 9482 { 9483 9484 t4_tp_mib_read(adap, &st->del, 4, A_TP_MIB_TID_DEL, sleep_ok); 9485 } 9486 9487 /** 9488 * t4_read_mtu_tbl - returns the values in the HW path MTU table 9489 * @adap: the adapter 9490 * @mtus: where to store the MTU values 9491 * @mtu_log: where to store the MTU base-2 log (may be %NULL) 9492 * 9493 * Reads the HW path MTU table. 9494 */ 9495 void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log) 9496 { 9497 u32 v; 9498 int i; 9499 9500 for (i = 0; i < NMTUS; ++i) { 9501 t4_write_reg(adap, A_TP_MTU_TABLE, 9502 V_MTUINDEX(0xff) | V_MTUVALUE(i)); 9503 v = t4_read_reg(adap, A_TP_MTU_TABLE); 9504 mtus[i] = G_MTUVALUE(v); 9505 if (mtu_log) 9506 mtu_log[i] = G_MTUWIDTH(v); 9507 } 9508 } 9509 9510 /** 9511 * t4_read_cong_tbl - reads the congestion control table 9512 * @adap: the adapter 9513 * @incr: where to store the alpha values 9514 * 9515 * Reads the additive increments programmed into the HW congestion 9516 * control table. 9517 */ 9518 void t4_read_cong_tbl(struct adapter *adap, u16 incr[NMTUS][NCCTRL_WIN]) 9519 { 9520 unsigned int mtu, w; 9521 9522 for (mtu = 0; mtu < NMTUS; ++mtu) 9523 for (w = 0; w < NCCTRL_WIN; ++w) { 9524 t4_write_reg(adap, A_TP_CCTRL_TABLE, 9525 V_ROWINDEX(0xffff) | (mtu << 5) | w); 9526 incr[mtu][w] = (u16)t4_read_reg(adap, 9527 A_TP_CCTRL_TABLE) & 0x1fff; 9528 } 9529 } 9530 9531 /** 9532 * t4_tp_wr_bits_indirect - set/clear bits in an indirect TP register 9533 * @adap: the adapter 9534 * @addr: the indirect TP register address 9535 * @mask: specifies the field within the register to modify 9536 * @val: new value for the field 9537 * 9538 * Sets a field of an indirect TP register to the given value. 9539 */ 9540 void t4_tp_wr_bits_indirect(struct adapter *adap, unsigned int addr, 9541 unsigned int mask, unsigned int val) 9542 { 9543 t4_write_reg(adap, A_TP_PIO_ADDR, addr); 9544 val |= t4_read_reg(adap, A_TP_PIO_DATA) & ~mask; 9545 t4_write_reg(adap, A_TP_PIO_DATA, val); 9546 } 9547 9548 /** 9549 * init_cong_ctrl - initialize congestion control parameters 9550 * @a: the alpha values for congestion control 9551 * @b: the beta values for congestion control 9552 * 9553 * Initialize the congestion control parameters. 9554 */ 9555 static void init_cong_ctrl(unsigned short *a, unsigned short *b) 9556 { 9557 a[0] = a[1] = a[2] = a[3] = a[4] = a[5] = a[6] = a[7] = a[8] = 1; 9558 a[9] = 2; 9559 a[10] = 3; 9560 a[11] = 4; 9561 a[12] = 5; 9562 a[13] = 6; 9563 a[14] = 7; 9564 a[15] = 8; 9565 a[16] = 9; 9566 a[17] = 10; 9567 a[18] = 14; 9568 a[19] = 17; 9569 a[20] = 21; 9570 a[21] = 25; 9571 a[22] = 30; 9572 a[23] = 35; 9573 a[24] = 45; 9574 a[25] = 60; 9575 a[26] = 80; 9576 a[27] = 100; 9577 a[28] = 200; 9578 a[29] = 300; 9579 a[30] = 400; 9580 a[31] = 500; 9581 9582 b[0] = b[1] = b[2] = b[3] = b[4] = b[5] = b[6] = b[7] = b[8] = 0; 9583 b[9] = b[10] = 1; 9584 b[11] = b[12] = 2; 9585 b[13] = b[14] = b[15] = b[16] = 3; 9586 b[17] = b[18] = b[19] = b[20] = b[21] = 4; 9587 b[22] = b[23] = b[24] = b[25] = b[26] = b[27] = 5; 9588 b[28] = b[29] = 6; 9589 b[30] = b[31] = 7; 9590 } 9591 9592 /* The minimum additive increment value for the congestion control table */ 9593 #define CC_MIN_INCR 2U 9594 9595 /** 9596 * t4_load_mtus - write the MTU and congestion control HW tables 9597 * @adap: the adapter 9598 * @mtus: the values for the MTU table 9599 * @alpha: the values for the congestion control alpha parameter 9600 * @beta: the values for the congestion control beta parameter 9601 * 9602 * Write the HW MTU table with the supplied MTUs and the high-speed 9603 * congestion control table with the supplied alpha, beta, and MTUs. 9604 * We write the two tables together because the additive increments 9605 * depend on the MTUs. 9606 */ 9607 void t4_load_mtus(struct adapter *adap, const unsigned short *mtus, 9608 const unsigned short *alpha, const unsigned short *beta) 9609 { 9610 static const unsigned int avg_pkts[NCCTRL_WIN] = { 9611 2, 6, 10, 14, 20, 28, 40, 56, 80, 112, 160, 224, 320, 448, 640, 9612 896, 1281, 1792, 2560, 3584, 5120, 7168, 10240, 14336, 20480, 9613 28672, 40960, 57344, 81920, 114688, 163840, 229376 9614 }; 9615 9616 unsigned int i, w; 9617 9618 for (i = 0; i < NMTUS; ++i) { 9619 unsigned int mtu = mtus[i]; 9620 unsigned int log2 = fls(mtu); 9621 9622 if (!(mtu & ((1 << log2) >> 2))) /* round */ 9623 log2--; 9624 t4_write_reg(adap, A_TP_MTU_TABLE, V_MTUINDEX(i) | 9625 V_MTUWIDTH(log2) | V_MTUVALUE(mtu)); 9626 9627 for (w = 0; w < NCCTRL_WIN; ++w) { 9628 unsigned int inc; 9629 9630 inc = max(((mtu - 40) * alpha[w]) / avg_pkts[w], 9631 CC_MIN_INCR); 9632 9633 t4_write_reg(adap, A_TP_CCTRL_TABLE, (i << 21) | 9634 (w << 16) | (beta[w] << 13) | inc); 9635 } 9636 } 9637 } 9638 9639 /** 9640 * t4_set_pace_tbl - set the pace table 9641 * @adap: the adapter 9642 * @pace_vals: the pace values in microseconds 9643 * @start: index of the first entry in the HW pace table to set 9644 * @n: how many entries to set 9645 * 9646 * Sets (a subset of the) HW pace table. 9647 */ 9648 int t4_set_pace_tbl(struct adapter *adap, const unsigned int *pace_vals, 9649 unsigned int start, unsigned int n) 9650 { 9651 unsigned int vals[NTX_SCHED], i; 9652 unsigned int tick_ns = dack_ticks_to_usec(adap, 1000); 9653 9654 if (n > NTX_SCHED) 9655 return -ERANGE; 9656 9657 /* convert values from us to dack ticks, rounding to closest value */ 9658 for (i = 0; i < n; i++, pace_vals++) { 9659 vals[i] = (1000 * *pace_vals + tick_ns / 2) / tick_ns; 9660 if (vals[i] > 0x7ff) 9661 return -ERANGE; 9662 if (*pace_vals && vals[i] == 0) 9663 return -ERANGE; 9664 } 9665 for (i = 0; i < n; i++, start++) 9666 t4_write_reg(adap, A_TP_PACE_TABLE, (start << 16) | vals[i]); 9667 return 0; 9668 } 9669 9670 /** 9671 * t4_set_sched_bps - set the bit rate for a HW traffic scheduler 9672 * @adap: the adapter 9673 * @kbps: target rate in Kbps 9674 * @sched: the scheduler index 9675 * 9676 * Configure a Tx HW scheduler for the target rate. 9677 */ 9678 int t4_set_sched_bps(struct adapter *adap, int sched, unsigned int kbps) 9679 { 9680 unsigned int v, tps, cpt, bpt, delta, mindelta = ~0; 9681 unsigned int clk = adap->params.vpd.cclk * 1000; 9682 unsigned int selected_cpt = 0, selected_bpt = 0; 9683 9684 if (kbps > 0) { 9685 kbps *= 125; /* -> bytes */ 9686 for (cpt = 1; cpt <= 255; cpt++) { 9687 tps = clk / cpt; 9688 bpt = (kbps + tps / 2) / tps; 9689 if (bpt > 0 && bpt <= 255) { 9690 v = bpt * tps; 9691 delta = v >= kbps ? v - kbps : kbps - v; 9692 if (delta < mindelta) { 9693 mindelta = delta; 9694 selected_cpt = cpt; 9695 selected_bpt = bpt; 9696 } 9697 } else if (selected_cpt) 9698 break; 9699 } 9700 if (!selected_cpt) 9701 return -EINVAL; 9702 } 9703 t4_write_reg(adap, A_TP_TM_PIO_ADDR, 9704 A_TP_TX_MOD_Q1_Q0_RATE_LIMIT - sched / 2); 9705 v = t4_read_reg(adap, A_TP_TM_PIO_DATA); 9706 if (sched & 1) 9707 v = (v & 0xffff) | (selected_cpt << 16) | (selected_bpt << 24); 9708 else 9709 v = (v & 0xffff0000) | selected_cpt | (selected_bpt << 8); 9710 t4_write_reg(adap, A_TP_TM_PIO_DATA, v); 9711 return 0; 9712 } 9713 9714 /** 9715 * t4_set_sched_ipg - set the IPG for a Tx HW packet rate scheduler 9716 * @adap: the adapter 9717 * @sched: the scheduler index 9718 * @ipg: the interpacket delay in tenths of nanoseconds 9719 * 9720 * Set the interpacket delay for a HW packet rate scheduler. 9721 */ 9722 int t4_set_sched_ipg(struct adapter *adap, int sched, unsigned int ipg) 9723 { 9724 unsigned int v, addr = A_TP_TX_MOD_Q1_Q0_TIMER_SEPARATOR - sched / 2; 9725 9726 /* convert ipg to nearest number of core clocks */ 9727 ipg *= core_ticks_per_usec(adap); 9728 ipg = (ipg + 5000) / 10000; 9729 if (ipg > M_TXTIMERSEPQ0) 9730 return -EINVAL; 9731 9732 t4_write_reg(adap, A_TP_TM_PIO_ADDR, addr); 9733 v = t4_read_reg(adap, A_TP_TM_PIO_DATA); 9734 if (sched & 1) 9735 v = (v & V_TXTIMERSEPQ0(M_TXTIMERSEPQ0)) | V_TXTIMERSEPQ1(ipg); 9736 else 9737 v = (v & V_TXTIMERSEPQ1(M_TXTIMERSEPQ1)) | V_TXTIMERSEPQ0(ipg); 9738 t4_write_reg(adap, A_TP_TM_PIO_DATA, v); 9739 t4_read_reg(adap, A_TP_TM_PIO_DATA); 9740 return 0; 9741 } 9742 9743 /* 9744 * Calculates a rate in bytes/s given the number of 256-byte units per 4K core 9745 * clocks. The formula is 9746 * 9747 * bytes/s = bytes256 * 256 * ClkFreq / 4096 9748 * 9749 * which is equivalent to 9750 * 9751 * bytes/s = 62.5 * bytes256 * ClkFreq_ms 9752 */ 9753 static u64 chan_rate(struct adapter *adap, unsigned int bytes256) 9754 { 9755 u64 v = (u64)bytes256 * adap->params.vpd.cclk; 9756 9757 return v * 62 + v / 2; 9758 } 9759 9760 /** 9761 * t4_get_chan_txrate - get the current per channel Tx rates 9762 * @adap: the adapter 9763 * @nic_rate: rates for NIC traffic 9764 * @ofld_rate: rates for offloaded traffic 9765 * 9766 * Return the current Tx rates in bytes/s for NIC and offloaded traffic 9767 * for each channel. 9768 */ 9769 void t4_get_chan_txrate(struct adapter *adap, u64 *nic_rate, u64 *ofld_rate) 9770 { 9771 u32 v; 9772 9773 v = t4_read_reg(adap, A_TP_TX_TRATE); 9774 nic_rate[0] = chan_rate(adap, G_TNLRATE0(v)); 9775 nic_rate[1] = chan_rate(adap, G_TNLRATE1(v)); 9776 if (adap->chip_params->nchan > 2) { 9777 nic_rate[2] = chan_rate(adap, G_TNLRATE2(v)); 9778 nic_rate[3] = chan_rate(adap, G_TNLRATE3(v)); 9779 } 9780 9781 v = t4_read_reg(adap, A_TP_TX_ORATE); 9782 ofld_rate[0] = chan_rate(adap, G_OFDRATE0(v)); 9783 ofld_rate[1] = chan_rate(adap, G_OFDRATE1(v)); 9784 if (adap->chip_params->nchan > 2) { 9785 ofld_rate[2] = chan_rate(adap, G_OFDRATE2(v)); 9786 ofld_rate[3] = chan_rate(adap, G_OFDRATE3(v)); 9787 } 9788 } 9789 9790 /** 9791 * t4_set_trace_filter - configure one of the tracing filters 9792 * @adap: the adapter 9793 * @tp: the desired trace filter parameters 9794 * @idx: which filter to configure 9795 * @enable: whether to enable or disable the filter 9796 * 9797 * Configures one of the tracing filters available in HW. If @tp is %NULL 9798 * it indicates that the filter is already written in the register and it 9799 * just needs to be enabled or disabled. 9800 */ 9801 int t4_set_trace_filter(struct adapter *adap, const struct trace_params *tp, 9802 int idx, int enable) 9803 { 9804 int i, ofst; 9805 u32 match_ctl_a, match_ctl_b; 9806 u32 data_reg, mask_reg, cfg; 9807 u32 en = is_t4(adap) ? F_TFEN : F_T5_TFEN; 9808 9809 if (idx < 0 || idx >= NTRACE) 9810 return -EINVAL; 9811 9812 if (chip_id(adap) >= CHELSIO_T7) { 9813 match_ctl_a = T7_MPS_TRC_FILTER_MATCH_CTL_A(idx); 9814 match_ctl_b = T7_MPS_TRC_FILTER_MATCH_CTL_B(idx); 9815 } else { 9816 match_ctl_a = MPS_TRC_FILTER_MATCH_CTL_A(idx); 9817 match_ctl_b = MPS_TRC_FILTER_MATCH_CTL_B(idx); 9818 } 9819 9820 if (tp == NULL || !enable) { 9821 t4_set_reg_field(adap, match_ctl_a, en, enable ? en : 0); 9822 return 0; 9823 } 9824 9825 /* 9826 * TODO - After T4 data book is updated, specify the exact 9827 * section below. 9828 * 9829 * See T4 data book - MPS section for a complete description 9830 * of the below if..else handling of A_MPS_TRC_CFG register 9831 * value. 9832 */ 9833 cfg = t4_read_reg(adap, A_MPS_TRC_CFG); 9834 if (cfg & F_TRCMULTIFILTER) { 9835 /* 9836 * If multiple tracers are enabled, then maximum 9837 * capture size is 2.5KB (FIFO size of a single channel) 9838 * minus 2 flits for CPL_TRACE_PKT header. 9839 */ 9840 if (tp->snap_len > ((10 * 1024 / 4) - (2 * 8))) 9841 return -EINVAL; 9842 } else { 9843 /* 9844 * If multiple tracers are disabled, to avoid deadlocks 9845 * maximum packet capture size of 9600 bytes is recommended. 9846 * Also in this mode, only trace0 can be enabled and running. 9847 */ 9848 if (tp->snap_len > 9600 || idx) 9849 return -EINVAL; 9850 } 9851 9852 if (tp->port > (is_t4(adap) ? 11 : 19) || tp->invert > 1 || 9853 tp->skip_len > M_TFLENGTH || tp->skip_ofst > M_TFOFFSET || 9854 tp->min_len > M_TFMINPKTSIZE) 9855 return -EINVAL; 9856 9857 /* stop the tracer we'll be changing */ 9858 t4_set_reg_field(adap, match_ctl_a, en, 0); 9859 9860 ofst = (A_MPS_TRC_FILTER1_MATCH - A_MPS_TRC_FILTER0_MATCH) * idx; 9861 data_reg = A_MPS_TRC_FILTER0_MATCH + ofst; 9862 mask_reg = A_MPS_TRC_FILTER0_DONT_CARE + ofst; 9863 9864 for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) { 9865 t4_write_reg(adap, data_reg, tp->data[i]); 9866 t4_write_reg(adap, mask_reg, ~tp->mask[i]); 9867 } 9868 t4_write_reg(adap, match_ctl_b, V_TFCAPTUREMAX(tp->snap_len) | 9869 V_TFMINPKTSIZE(tp->min_len)); 9870 t4_write_reg(adap, match_ctl_a, V_TFOFFSET(tp->skip_ofst) | 9871 V_TFLENGTH(tp->skip_len) | en | (is_t4(adap) ? 9872 V_TFPORT(tp->port) | V_TFINVERTMATCH(tp->invert) : 9873 V_T5_TFPORT(tp->port) | V_T5_TFINVERTMATCH(tp->invert))); 9874 9875 return 0; 9876 } 9877 9878 /** 9879 * t4_get_trace_filter - query one of the tracing filters 9880 * @adap: the adapter 9881 * @tp: the current trace filter parameters 9882 * @idx: which trace filter to query 9883 * @enabled: non-zero if the filter is enabled 9884 * 9885 * Returns the current settings of one of the HW tracing filters. 9886 */ 9887 void t4_get_trace_filter(struct adapter *adap, struct trace_params *tp, int idx, 9888 int *enabled) 9889 { 9890 u32 ctla, ctlb; 9891 int i, ofst; 9892 u32 data_reg, mask_reg; 9893 9894 if (chip_id(adap) >= CHELSIO_T7) { 9895 ctla = t4_read_reg(adap, T7_MPS_TRC_FILTER_MATCH_CTL_A(idx)); 9896 ctlb = t4_read_reg(adap, T7_MPS_TRC_FILTER_MATCH_CTL_B(idx)); 9897 } else { 9898 ctla = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A(idx)); 9899 ctlb = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B(idx)); 9900 } 9901 9902 if (is_t4(adap)) { 9903 *enabled = !!(ctla & F_TFEN); 9904 tp->port = G_TFPORT(ctla); 9905 tp->invert = !!(ctla & F_TFINVERTMATCH); 9906 } else { 9907 *enabled = !!(ctla & F_T5_TFEN); 9908 tp->port = G_T5_TFPORT(ctla); 9909 tp->invert = !!(ctla & F_T5_TFINVERTMATCH); 9910 } 9911 tp->snap_len = G_TFCAPTUREMAX(ctlb); 9912 tp->min_len = G_TFMINPKTSIZE(ctlb); 9913 tp->skip_ofst = G_TFOFFSET(ctla); 9914 tp->skip_len = G_TFLENGTH(ctla); 9915 9916 ofst = (A_MPS_TRC_FILTER1_MATCH - A_MPS_TRC_FILTER0_MATCH) * idx; 9917 data_reg = A_MPS_TRC_FILTER0_MATCH + ofst; 9918 mask_reg = A_MPS_TRC_FILTER0_DONT_CARE + ofst; 9919 9920 for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) { 9921 tp->mask[i] = ~t4_read_reg(adap, mask_reg); 9922 tp->data[i] = t4_read_reg(adap, data_reg) & tp->mask[i]; 9923 } 9924 } 9925 9926 /** 9927 * t4_set_trace_rss_control - configure the trace rss control register 9928 * @adap: the adapter 9929 * @chan: the channel number for RSS control 9930 * @qid: queue number 9931 * 9932 * Configures the MPS tracing RSS control parameter for specified 9933 * @chan channel and @qid queue number. 9934 */ 9935 void t4_set_trace_rss_control(struct adapter *adap, u8 chan, u16 qid) 9936 { 9937 u32 mps_trc_rss_control; 9938 9939 switch (chip_id(adap)) { 9940 case CHELSIO_T4: 9941 mps_trc_rss_control = A_MPS_TRC_RSS_CONTROL; 9942 break; 9943 case CHELSIO_T5: 9944 case CHELSIO_T6: 9945 mps_trc_rss_control = A_MPS_T5_TRC_RSS_CONTROL; 9946 break; 9947 case CHELSIO_T7: 9948 default: 9949 mps_trc_rss_control = A_T7_MPS_T5_TRC_RSS_CONTROL; 9950 break; 9951 } 9952 9953 t4_write_reg(adap, mps_trc_rss_control, 9954 V_RSSCONTROL(chan) | V_QUEUENUMBER(qid)); 9955 } 9956 9957 /** 9958 * t4_pmtx_get_stats - returns the HW stats from PMTX 9959 * @adap: the adapter 9960 * @cnt: where to store the count statistics 9961 * @cycles: where to store the cycle statistics 9962 * 9963 * Returns performance statistics from PMTX. 9964 */ 9965 void t4_pmtx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[]) 9966 { 9967 int i; 9968 u32 data[2]; 9969 9970 for (i = 0; i < adap->chip_params->pm_stats_cnt; i++) { 9971 t4_write_reg(adap, A_PM_TX_STAT_CONFIG, i + 1); 9972 cnt[i] = t4_read_reg(adap, A_PM_TX_STAT_COUNT); 9973 if (is_t4(adap)) 9974 cycles[i] = t4_read_reg64(adap, A_PM_TX_STAT_LSB); 9975 else { 9976 t4_read_indirect(adap, A_PM_TX_DBG_CTRL, 9977 A_PM_TX_DBG_DATA, data, 2, 9978 chip_id(adap) >= CHELSIO_T7 ? 9979 A_T7_PM_TX_DBG_STAT_MSB : 9980 A_PM_TX_DBG_STAT_MSB); 9981 cycles[i] = (((u64)data[0] << 32) | data[1]); 9982 } 9983 } 9984 } 9985 9986 /** 9987 * t4_pmrx_get_stats - returns the HW stats from PMRX 9988 * @adap: the adapter 9989 * @cnt: where to store the count statistics 9990 * @cycles: where to store the cycle statistics 9991 * 9992 * Returns performance statistics from PMRX. 9993 */ 9994 void t4_pmrx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[]) 9995 { 9996 int i; 9997 u32 data[2]; 9998 9999 for (i = 0; i < adap->chip_params->pm_stats_cnt; i++) { 10000 t4_write_reg(adap, A_PM_RX_STAT_CONFIG, i + 1); 10001 cnt[i] = t4_read_reg(adap, A_PM_RX_STAT_COUNT); 10002 if (is_t4(adap)) { 10003 cycles[i] = t4_read_reg64(adap, A_PM_RX_STAT_LSB); 10004 } else { 10005 t4_read_indirect(adap, A_PM_RX_DBG_CTRL, 10006 A_PM_RX_DBG_DATA, data, 2, 10007 A_PM_RX_DBG_STAT_MSB); 10008 cycles[i] = (((u64)data[0] << 32) | data[1]); 10009 } 10010 } 10011 } 10012 10013 /** 10014 * t4_pmrx_cache_get_stats - returns the HW PMRX cache stats 10015 * @adap: the adapter 10016 * @stats: where to store the statistics 10017 * 10018 * Returns performance statistics of PMRX cache. 10019 */ 10020 void t4_pmrx_cache_get_stats(struct adapter *adap, u32 stats[]) 10021 { 10022 u8 i, j; 10023 10024 for (i = 0, j = 0; i < T7_PM_RX_CACHE_NSTATS / 3; i++, j += 3) { 10025 t4_write_reg(adap, A_PM_RX_STAT_CONFIG, 0x100 + i); 10026 stats[j] = t4_read_reg(adap, A_PM_RX_STAT_COUNT); 10027 t4_read_indirect(adap, A_PM_RX_DBG_CTRL, A_PM_RX_DBG_DATA, 10028 &stats[j + 1], 2, A_PM_RX_DBG_STAT_MSB); 10029 } 10030 } 10031 10032 /** 10033 * t4_get_mps_bg_map - return the buffer groups associated with a port 10034 * @adap: the adapter 10035 * @idx: the port index 10036 * 10037 * Returns a bitmap indicating which MPS buffer groups are associated 10038 * with the given port. Bit i is set if buffer group i is used by the 10039 * port. 10040 */ 10041 static unsigned int t4_get_mps_bg_map(struct adapter *adap, int idx) 10042 { 10043 u32 n; 10044 10045 if (adap->params.mps_bg_map != UINT32_MAX) 10046 return ((adap->params.mps_bg_map >> (idx << 3)) & 0xff); 10047 10048 n = adap->params.nports; 10049 MPASS(n > 0 && n <= MAX_NPORTS); 10050 if (n == 1) 10051 return idx == 0 ? 0xf : 0; 10052 if (n == 2 && chip_id(adap) <= CHELSIO_T5) 10053 return idx < 2 ? (3 << (2 * idx)) : 0; 10054 return 1 << idx; 10055 } 10056 10057 /* 10058 * TP RX e-channels associated with the port. 10059 */ 10060 static unsigned int t4_get_rx_e_chan_map(struct adapter *adap, int idx) 10061 { 10062 const u32 n = adap->params.nports; 10063 const u32 all_chan = (1 << adap->chip_params->nchan) - 1; 10064 10065 switch (adap->params.tp.lb_mode) { 10066 case 0: 10067 if (n == 1) 10068 return (all_chan); 10069 if (n == 2 && chip_id(adap) <= CHELSIO_T5) 10070 return (3 << (2 * idx)); 10071 return (1 << idx); 10072 case 1: 10073 MPASS(n == 1); 10074 return (all_chan); 10075 case 2: 10076 MPASS(n <= 2); 10077 return (3 << (2 * idx)); 10078 default: 10079 CH_ERR(adap, "Unsupported LB mode %d\n", 10080 adap->params.tp.lb_mode); 10081 return (0); 10082 } 10083 } 10084 10085 /* 10086 * TP RX c-channel associated with the port. 10087 */ 10088 static unsigned int t4_get_rx_c_chan(struct adapter *adap, int idx) 10089 { 10090 if (adap->params.tp_ch_map != UINT32_MAX) 10091 return (adap->params.tp_ch_map >> (8 * idx)) & 0xff; 10092 return 0; 10093 } 10094 10095 /* 10096 * TP TX c-channel associated with the port. 10097 */ 10098 static unsigned int t4_get_tx_c_chan(struct adapter *adap, int idx) 10099 { 10100 if (adap->params.tx_tp_ch_map != UINT32_MAX) 10101 return (adap->params.tx_tp_ch_map >> (8 * idx)) & 0xff; 10102 return idx; 10103 } 10104 10105 /** 10106 * t4_get_port_type_description - return Port Type string description 10107 * @port_type: firmware Port Type enumeration 10108 */ 10109 const char *t4_get_port_type_description(enum fw_port_type port_type) 10110 { 10111 static const char *const port_type_description[] = { 10112 "Fiber_XFI", 10113 "Fiber_XAUI", 10114 "BT_SGMII", 10115 "BT_XFI", 10116 "BT_XAUI", 10117 "KX4", 10118 "CX4", 10119 "KX", 10120 "KR", 10121 "SFP", 10122 "BP_AP", 10123 "BP4_AP", 10124 "QSFP_10G", 10125 "QSA", 10126 "QSFP", 10127 "BP40_BA", 10128 "KR4_100G", 10129 "CR4_QSFP", 10130 "CR_QSFP", 10131 "CR2_QSFP", 10132 "SFP28", 10133 "KR_SFP28", 10134 "KR_XLAUI", 10135 }; 10136 10137 if (port_type < ARRAY_SIZE(port_type_description)) 10138 return port_type_description[port_type]; 10139 return "UNKNOWN"; 10140 } 10141 10142 /** 10143 * t4_get_port_stats_offset - collect port stats relative to a previous 10144 * snapshot 10145 * @adap: The adapter 10146 * @idx: The port 10147 * @stats: Current stats to fill 10148 * @offset: Previous stats snapshot 10149 */ 10150 void t4_get_port_stats_offset(struct adapter *adap, int idx, 10151 struct port_stats *stats, 10152 struct port_stats *offset) 10153 { 10154 u64 *s, *o; 10155 int i; 10156 10157 t4_get_port_stats(adap, idx, stats); 10158 for (i = 0, s = (u64 *)stats, o = (u64 *)offset ; 10159 i < (sizeof(struct port_stats)/sizeof(u64)) ; 10160 i++, s++, o++) 10161 *s -= *o; 10162 } 10163 10164 /** 10165 * t4_get_port_stats - collect port statistics 10166 * @adap: the adapter 10167 * @idx: the port index 10168 * @p: the stats structure to fill 10169 * 10170 * Collect statistics related to the given port from HW. 10171 */ 10172 void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p) 10173 { 10174 struct port_info *pi; 10175 int port_id, tx_chan; 10176 u32 bgmap, stat_ctl; 10177 10178 port_id = adap->port_map[idx]; 10179 MPASS(port_id >= 0 && port_id <= adap->params.nports); 10180 pi = adap->port[port_id]; 10181 10182 #define GET_STAT(name) \ 10183 t4_read_reg64(adap, \ 10184 t4_port_reg(adap, tx_chan, A_MPS_PORT_STAT_##name##_L)); 10185 memset(p, 0, sizeof(*p)); 10186 for (tx_chan = pi->tx_chan; 10187 tx_chan < pi->tx_chan + adap->params.tp.lb_nchan; tx_chan++) { 10188 p->tx_pause += GET_STAT(TX_PORT_PAUSE); 10189 p->tx_octets += GET_STAT(TX_PORT_BYTES); 10190 p->tx_frames += GET_STAT(TX_PORT_FRAMES); 10191 p->tx_bcast_frames += GET_STAT(TX_PORT_BCAST); 10192 p->tx_mcast_frames += GET_STAT(TX_PORT_MCAST); 10193 p->tx_ucast_frames += GET_STAT(TX_PORT_UCAST); 10194 p->tx_error_frames += GET_STAT(TX_PORT_ERROR); 10195 p->tx_frames_64 += GET_STAT(TX_PORT_64B); 10196 p->tx_frames_65_127 += GET_STAT(TX_PORT_65B_127B); 10197 p->tx_frames_128_255 += GET_STAT(TX_PORT_128B_255B); 10198 p->tx_frames_256_511 += GET_STAT(TX_PORT_256B_511B); 10199 p->tx_frames_512_1023 += GET_STAT(TX_PORT_512B_1023B); 10200 p->tx_frames_1024_1518 += GET_STAT(TX_PORT_1024B_1518B); 10201 p->tx_frames_1519_max += GET_STAT(TX_PORT_1519B_MAX); 10202 p->tx_drop += GET_STAT(TX_PORT_DROP); 10203 p->tx_ppp0 += GET_STAT(TX_PORT_PPP0); 10204 p->tx_ppp1 += GET_STAT(TX_PORT_PPP1); 10205 p->tx_ppp2 += GET_STAT(TX_PORT_PPP2); 10206 p->tx_ppp3 += GET_STAT(TX_PORT_PPP3); 10207 p->tx_ppp4 += GET_STAT(TX_PORT_PPP4); 10208 p->tx_ppp5 += GET_STAT(TX_PORT_PPP5); 10209 p->tx_ppp6 += GET_STAT(TX_PORT_PPP6); 10210 p->tx_ppp7 += GET_STAT(TX_PORT_PPP7); 10211 10212 p->rx_pause += GET_STAT(RX_PORT_PAUSE); 10213 p->rx_octets += GET_STAT(RX_PORT_BYTES); 10214 p->rx_frames += GET_STAT(RX_PORT_FRAMES); 10215 p->rx_bcast_frames += GET_STAT(RX_PORT_BCAST); 10216 p->rx_mcast_frames += GET_STAT(RX_PORT_MCAST); 10217 p->rx_ucast_frames += GET_STAT(RX_PORT_UCAST); 10218 p->rx_too_long += GET_STAT(RX_PORT_MTU_ERROR); 10219 p->rx_jabber += GET_STAT(RX_PORT_MTU_CRC_ERROR); 10220 p->rx_len_err += GET_STAT(RX_PORT_LEN_ERROR); 10221 p->rx_symbol_err += GET_STAT(RX_PORT_SYM_ERROR); 10222 p->rx_runt += GET_STAT(RX_PORT_LESS_64B); 10223 p->rx_frames_64 += GET_STAT(RX_PORT_64B); 10224 p->rx_frames_65_127 += GET_STAT(RX_PORT_65B_127B); 10225 p->rx_frames_128_255 += GET_STAT(RX_PORT_128B_255B); 10226 p->rx_frames_256_511 += GET_STAT(RX_PORT_256B_511B); 10227 p->rx_frames_512_1023 += GET_STAT(RX_PORT_512B_1023B); 10228 p->rx_frames_1024_1518 += GET_STAT(RX_PORT_1024B_1518B); 10229 p->rx_frames_1519_max += GET_STAT(RX_PORT_1519B_MAX); 10230 p->rx_ppp0 += GET_STAT(RX_PORT_PPP0); 10231 p->rx_ppp1 += GET_STAT(RX_PORT_PPP1); 10232 p->rx_ppp2 += GET_STAT(RX_PORT_PPP2); 10233 p->rx_ppp3 += GET_STAT(RX_PORT_PPP3); 10234 p->rx_ppp4 += GET_STAT(RX_PORT_PPP4); 10235 p->rx_ppp5 += GET_STAT(RX_PORT_PPP5); 10236 p->rx_ppp6 += GET_STAT(RX_PORT_PPP6); 10237 p->rx_ppp7 += GET_STAT(RX_PORT_PPP7); 10238 if (!is_t6(adap)) { 10239 MPASS(pi->fcs_reg == A_MPS_PORT_STAT_RX_PORT_CRC_ERROR_L); 10240 p->rx_fcs_err += GET_STAT(RX_PORT_CRC_ERROR); 10241 } 10242 } 10243 #undef GET_STAT 10244 10245 if (is_t6(adap) && pi->fcs_reg != -1) 10246 p->rx_fcs_err = t4_read_reg64(adap, 10247 t4_port_reg(adap, pi->tx_chan, pi->fcs_reg)) - pi->fcs_base; 10248 10249 if (chip_id(adap) >= CHELSIO_T5) { 10250 stat_ctl = t4_read_reg(adap, A_MPS_STAT_CTL); 10251 if (stat_ctl & F_COUNTPAUSESTATTX) { 10252 p->tx_frames -= p->tx_pause; 10253 p->tx_octets -= p->tx_pause * 64; 10254 } 10255 if (stat_ctl & F_COUNTPAUSEMCTX) 10256 p->tx_mcast_frames -= p->tx_pause; 10257 if (stat_ctl & F_COUNTPAUSESTATRX) { 10258 p->rx_frames -= p->rx_pause; 10259 p->rx_octets -= p->rx_pause * 64; 10260 } 10261 if (stat_ctl & F_COUNTPAUSEMCRX) 10262 p->rx_mcast_frames -= p->rx_pause; 10263 } 10264 10265 #define GET_STAT_COM(name) t4_read_reg64(adap, A_MPS_STAT_##name##_L) 10266 bgmap = pi->mps_bg_map; 10267 p->rx_ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_DROP_FRAME) : 0; 10268 p->rx_ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_MAC_DROP_FRAME) : 0; 10269 p->rx_ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_MAC_DROP_FRAME) : 0; 10270 p->rx_ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_MAC_DROP_FRAME) : 0; 10271 p->rx_trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_TRUNC_FRAME) : 0; 10272 p->rx_trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_MAC_TRUNC_FRAME) : 0; 10273 p->rx_trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_MAC_TRUNC_FRAME) : 0; 10274 p->rx_trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_MAC_TRUNC_FRAME) : 0; 10275 #undef GET_STAT_COM 10276 } 10277 10278 /** 10279 * t4_get_lb_stats - collect loopback port statistics 10280 * @adap: the adapter 10281 * @idx: the loopback port index 10282 * @p: the stats structure to fill 10283 * 10284 * Return HW statistics for the given loopback port. 10285 */ 10286 void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p) 10287 { 10288 10289 #define GET_STAT(name) \ 10290 t4_read_reg64(adap, \ 10291 t4_port_reg(adap, idx, A_MPS_PORT_STAT_LB_PORT_##name##_L)) 10292 #define GET_STAT_COM(name) t4_read_reg64(adap, A_MPS_STAT_##name##_L) 10293 10294 p->octets = GET_STAT(BYTES); 10295 p->frames = GET_STAT(FRAMES); 10296 p->bcast_frames = GET_STAT(BCAST); 10297 p->mcast_frames = GET_STAT(MCAST); 10298 p->ucast_frames = GET_STAT(UCAST); 10299 p->error_frames = GET_STAT(ERROR); 10300 10301 p->frames_64 = GET_STAT(64B); 10302 p->frames_65_127 = GET_STAT(65B_127B); 10303 p->frames_128_255 = GET_STAT(128B_255B); 10304 p->frames_256_511 = GET_STAT(256B_511B); 10305 p->frames_512_1023 = GET_STAT(512B_1023B); 10306 p->frames_1024_1518 = GET_STAT(1024B_1518B); 10307 p->frames_1519_max = GET_STAT(1519B_MAX); 10308 p->drop = GET_STAT(DROP_FRAMES); 10309 10310 if (idx < adap->params.nports) { 10311 u32 bg = adap2pinfo(adap, idx)->mps_bg_map; 10312 10313 p->ovflow0 = (bg & 1) ? GET_STAT_COM(RX_BG_0_LB_DROP_FRAME) : 0; 10314 p->ovflow1 = (bg & 2) ? GET_STAT_COM(RX_BG_1_LB_DROP_FRAME) : 0; 10315 p->ovflow2 = (bg & 4) ? GET_STAT_COM(RX_BG_2_LB_DROP_FRAME) : 0; 10316 p->ovflow3 = (bg & 8) ? GET_STAT_COM(RX_BG_3_LB_DROP_FRAME) : 0; 10317 p->trunc0 = (bg & 1) ? GET_STAT_COM(RX_BG_0_LB_TRUNC_FRAME) : 0; 10318 p->trunc1 = (bg & 2) ? GET_STAT_COM(RX_BG_1_LB_TRUNC_FRAME) : 0; 10319 p->trunc2 = (bg & 4) ? GET_STAT_COM(RX_BG_2_LB_TRUNC_FRAME) : 0; 10320 p->trunc3 = (bg & 8) ? GET_STAT_COM(RX_BG_3_LB_TRUNC_FRAME) : 0; 10321 } 10322 10323 #undef GET_STAT 10324 #undef GET_STAT_COM 10325 } 10326 10327 /** 10328 * t4_wol_magic_enable - enable/disable magic packet WoL 10329 * @adap: the adapter 10330 * @port: the physical port index 10331 * @addr: MAC address expected in magic packets, %NULL to disable 10332 * 10333 * Enables/disables magic packet wake-on-LAN for the selected port. 10334 */ 10335 void t4_wol_magic_enable(struct adapter *adap, unsigned int port, 10336 const u8 *addr) 10337 { 10338 u32 mag_id_reg_l, mag_id_reg_h, port_cfg_reg; 10339 10340 if (is_t4(adap)) { 10341 mag_id_reg_l = PORT_REG(port, A_XGMAC_PORT_MAGIC_MACID_LO); 10342 mag_id_reg_h = PORT_REG(port, A_XGMAC_PORT_MAGIC_MACID_HI); 10343 port_cfg_reg = PORT_REG(port, A_XGMAC_PORT_CFG2); 10344 } else if (chip_id(adap) < CHELSIO_T7) { 10345 mag_id_reg_l = T5_PORT_REG(port, A_MAC_PORT_MAGIC_MACID_LO); 10346 mag_id_reg_h = T5_PORT_REG(port, A_MAC_PORT_MAGIC_MACID_HI); 10347 port_cfg_reg = T5_PORT_REG(port, A_MAC_PORT_CFG2); 10348 } else { 10349 mag_id_reg_l = T7_PORT_REG(port, A_T7_MAC_PORT_MAGIC_MACID_LO); 10350 mag_id_reg_h = T7_PORT_REG(port, A_T7_MAC_PORT_MAGIC_MACID_HI); 10351 port_cfg_reg = T7_PORT_REG(port, A_MAC_PORT_CFG2); 10352 } 10353 10354 if (addr) { 10355 t4_write_reg(adap, mag_id_reg_l, 10356 (addr[2] << 24) | (addr[3] << 16) | 10357 (addr[4] << 8) | addr[5]); 10358 t4_write_reg(adap, mag_id_reg_h, 10359 (addr[0] << 8) | addr[1]); 10360 } 10361 t4_set_reg_field(adap, port_cfg_reg, F_MAGICEN, 10362 V_MAGICEN(addr != NULL)); 10363 } 10364 10365 /** 10366 * t4_wol_pat_enable - enable/disable pattern-based WoL 10367 * @adap: the adapter 10368 * @port: the physical port index 10369 * @map: bitmap of which HW pattern filters to set 10370 * @mask0: byte mask for bytes 0-63 of a packet 10371 * @mask1: byte mask for bytes 64-127 of a packet 10372 * @crc: Ethernet CRC for selected bytes 10373 * @enable: enable/disable switch 10374 * 10375 * Sets the pattern filters indicated in @map to mask out the bytes 10376 * specified in @mask0/@mask1 in received packets and compare the CRC of 10377 * the resulting packet against @crc. If @enable is %true pattern-based 10378 * WoL is enabled, otherwise disabled. 10379 */ 10380 int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map, 10381 u64 mask0, u64 mask1, unsigned int crc, bool enable) 10382 { 10383 int i; 10384 u32 port_cfg_reg; 10385 10386 if (is_t4(adap)) 10387 port_cfg_reg = PORT_REG(port, A_XGMAC_PORT_CFG2); 10388 else if (chip_id(adap) < CHELSIO_T7) 10389 port_cfg_reg = T5_PORT_REG(port, A_MAC_PORT_CFG2); 10390 else 10391 port_cfg_reg = T7_PORT_REG(port, A_MAC_PORT_CFG2); 10392 10393 if (!enable) { 10394 t4_set_reg_field(adap, port_cfg_reg, F_PATEN, 0); 10395 return 0; 10396 } 10397 if (map > 0xff) 10398 return -EINVAL; 10399 10400 #define EPIO_REG(name) \ 10401 (is_t4(adap) ? PORT_REG(port, A_XGMAC_PORT_EPIO_##name) : \ 10402 T5_PORT_REG(port, A_MAC_PORT_EPIO_##name)) 10403 10404 t4_write_reg(adap, EPIO_REG(DATA1), mask0 >> 32); 10405 t4_write_reg(adap, EPIO_REG(DATA2), mask1); 10406 t4_write_reg(adap, EPIO_REG(DATA3), mask1 >> 32); 10407 10408 for (i = 0; i < NWOL_PAT; i++, map >>= 1) { 10409 if (!(map & 1)) 10410 continue; 10411 10412 /* write byte masks */ 10413 t4_write_reg(adap, EPIO_REG(DATA0), mask0); 10414 t4_write_reg(adap, EPIO_REG(OP), V_ADDRESS(i) | F_EPIOWR); 10415 t4_read_reg(adap, EPIO_REG(OP)); /* flush */ 10416 if (t4_read_reg(adap, EPIO_REG(OP)) & F_BUSY) 10417 return -ETIMEDOUT; 10418 10419 /* write CRC */ 10420 t4_write_reg(adap, EPIO_REG(DATA0), crc); 10421 t4_write_reg(adap, EPIO_REG(OP), V_ADDRESS(i + 32) | F_EPIOWR); 10422 t4_read_reg(adap, EPIO_REG(OP)); /* flush */ 10423 if (t4_read_reg(adap, EPIO_REG(OP)) & F_BUSY) 10424 return -ETIMEDOUT; 10425 } 10426 #undef EPIO_REG 10427 10428 t4_set_reg_field(adap, port_cfg_reg, 0, F_PATEN); 10429 return 0; 10430 } 10431 10432 /* t4_mk_filtdelwr - create a delete filter WR 10433 * @ftid: the filter ID 10434 * @wr: the filter work request to populate 10435 * @qid: ingress queue to receive the delete notification 10436 * 10437 * Creates a filter work request to delete the supplied filter. If @qid is 10438 * negative the delete notification is suppressed. 10439 */ 10440 void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid) 10441 { 10442 memset(wr, 0, sizeof(*wr)); 10443 wr->op_pkd = cpu_to_be32(V_FW_WR_OP(FW_FILTER_WR)); 10444 wr->len16_pkd = cpu_to_be32(V_FW_WR_LEN16(sizeof(*wr) / 16)); 10445 wr->tid_to_iq = cpu_to_be32(V_FW_FILTER_WR_TID(ftid) | 10446 V_FW_FILTER_WR_NOREPLY(qid < 0)); 10447 wr->del_filter_to_l2tix = cpu_to_be32(F_FW_FILTER_WR_DEL_FILTER); 10448 if (qid >= 0) 10449 wr->rx_chan_rx_rpl_iq = 10450 cpu_to_be16(V_FW_FILTER_WR_RX_RPL_IQ(qid)); 10451 } 10452 10453 #define INIT_CMD(var, cmd, rd_wr) do { \ 10454 (var).op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_##cmd##_CMD) | \ 10455 F_FW_CMD_REQUEST | \ 10456 F_FW_CMD_##rd_wr); \ 10457 (var).retval_len16 = cpu_to_be32(FW_LEN16(var)); \ 10458 } while (0) 10459 10460 int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox, 10461 u32 addr, u32 val) 10462 { 10463 u32 ldst_addrspace; 10464 struct fw_ldst_cmd c; 10465 10466 memset(&c, 0, sizeof(c)); 10467 ldst_addrspace = V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FIRMWARE); 10468 c.op_to_addrspace = cpu_to_be32(V_FW_CMD_OP(FW_LDST_CMD) | 10469 F_FW_CMD_REQUEST | 10470 F_FW_CMD_WRITE | 10471 ldst_addrspace); 10472 c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c)); 10473 c.u.addrval.addr = cpu_to_be32(addr); 10474 c.u.addrval.val = cpu_to_be32(val); 10475 10476 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 10477 } 10478 10479 /** 10480 * t4_mdio_rd - read a PHY register through MDIO 10481 * @adap: the adapter 10482 * @mbox: mailbox to use for the FW command 10483 * @phy_addr: the PHY address 10484 * @mmd: the PHY MMD to access (0 for clause 22 PHYs) 10485 * @reg: the register to read 10486 * @valp: where to store the value 10487 * 10488 * Issues a FW command through the given mailbox to read a PHY register. 10489 */ 10490 int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, 10491 unsigned int mmd, unsigned int reg, unsigned int *valp) 10492 { 10493 int ret; 10494 u32 ldst_addrspace; 10495 struct fw_ldst_cmd c; 10496 10497 memset(&c, 0, sizeof(c)); 10498 ldst_addrspace = V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO); 10499 c.op_to_addrspace = cpu_to_be32(V_FW_CMD_OP(FW_LDST_CMD) | 10500 F_FW_CMD_REQUEST | F_FW_CMD_READ | 10501 ldst_addrspace); 10502 c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c)); 10503 c.u.mdio.paddr_mmd = cpu_to_be16(V_FW_LDST_CMD_PADDR(phy_addr) | 10504 V_FW_LDST_CMD_MMD(mmd)); 10505 c.u.mdio.raddr = cpu_to_be16(reg); 10506 10507 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); 10508 if (ret == 0) 10509 *valp = be16_to_cpu(c.u.mdio.rval); 10510 return ret; 10511 } 10512 10513 /** 10514 * t4_mdio_wr - write a PHY register through MDIO 10515 * @adap: the adapter 10516 * @mbox: mailbox to use for the FW command 10517 * @phy_addr: the PHY address 10518 * @mmd: the PHY MMD to access (0 for clause 22 PHYs) 10519 * @reg: the register to write 10520 * @valp: value to write 10521 * 10522 * Issues a FW command through the given mailbox to write a PHY register. 10523 */ 10524 int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, 10525 unsigned int mmd, unsigned int reg, unsigned int val) 10526 { 10527 u32 ldst_addrspace; 10528 struct fw_ldst_cmd c; 10529 10530 memset(&c, 0, sizeof(c)); 10531 ldst_addrspace = V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MDIO); 10532 c.op_to_addrspace = cpu_to_be32(V_FW_CMD_OP(FW_LDST_CMD) | 10533 F_FW_CMD_REQUEST | F_FW_CMD_WRITE | 10534 ldst_addrspace); 10535 c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c)); 10536 c.u.mdio.paddr_mmd = cpu_to_be16(V_FW_LDST_CMD_PADDR(phy_addr) | 10537 V_FW_LDST_CMD_MMD(mmd)); 10538 c.u.mdio.raddr = cpu_to_be16(reg); 10539 c.u.mdio.rval = cpu_to_be16(val); 10540 10541 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 10542 } 10543 10544 /** 10545 * 10546 * t4_sge_decode_idma_state - decode the idma state 10547 * @adap: the adapter 10548 * @state: the state idma is stuck in 10549 */ 10550 void t4_sge_decode_idma_state(struct adapter *adapter, int state) 10551 { 10552 static const char * const t4_decode[] = { 10553 "IDMA_IDLE", 10554 "IDMA_PUSH_MORE_CPL_FIFO", 10555 "IDMA_PUSH_CPL_MSG_HEADER_TO_FIFO", 10556 "Not used", 10557 "IDMA_PHYSADDR_SEND_PCIEHDR", 10558 "IDMA_PHYSADDR_SEND_PAYLOAD_FIRST", 10559 "IDMA_PHYSADDR_SEND_PAYLOAD", 10560 "IDMA_SEND_FIFO_TO_IMSG", 10561 "IDMA_FL_REQ_DATA_FL_PREP", 10562 "IDMA_FL_REQ_DATA_FL", 10563 "IDMA_FL_DROP", 10564 "IDMA_FL_H_REQ_HEADER_FL", 10565 "IDMA_FL_H_SEND_PCIEHDR", 10566 "IDMA_FL_H_PUSH_CPL_FIFO", 10567 "IDMA_FL_H_SEND_CPL", 10568 "IDMA_FL_H_SEND_IP_HDR_FIRST", 10569 "IDMA_FL_H_SEND_IP_HDR", 10570 "IDMA_FL_H_REQ_NEXT_HEADER_FL", 10571 "IDMA_FL_H_SEND_NEXT_PCIEHDR", 10572 "IDMA_FL_H_SEND_IP_HDR_PADDING", 10573 "IDMA_FL_D_SEND_PCIEHDR", 10574 "IDMA_FL_D_SEND_CPL_AND_IP_HDR", 10575 "IDMA_FL_D_REQ_NEXT_DATA_FL", 10576 "IDMA_FL_SEND_PCIEHDR", 10577 "IDMA_FL_PUSH_CPL_FIFO", 10578 "IDMA_FL_SEND_CPL", 10579 "IDMA_FL_SEND_PAYLOAD_FIRST", 10580 "IDMA_FL_SEND_PAYLOAD", 10581 "IDMA_FL_REQ_NEXT_DATA_FL", 10582 "IDMA_FL_SEND_NEXT_PCIEHDR", 10583 "IDMA_FL_SEND_PADDING", 10584 "IDMA_FL_SEND_COMPLETION_TO_IMSG", 10585 "IDMA_FL_SEND_FIFO_TO_IMSG", 10586 "IDMA_FL_REQ_DATAFL_DONE", 10587 "IDMA_FL_REQ_HEADERFL_DONE", 10588 }; 10589 static const char * const t5_decode[] = { 10590 "IDMA_IDLE", 10591 "IDMA_ALMOST_IDLE", 10592 "IDMA_PUSH_MORE_CPL_FIFO", 10593 "IDMA_PUSH_CPL_MSG_HEADER_TO_FIFO", 10594 "IDMA_SGEFLRFLUSH_SEND_PCIEHDR", 10595 "IDMA_PHYSADDR_SEND_PCIEHDR", 10596 "IDMA_PHYSADDR_SEND_PAYLOAD_FIRST", 10597 "IDMA_PHYSADDR_SEND_PAYLOAD", 10598 "IDMA_SEND_FIFO_TO_IMSG", 10599 "IDMA_FL_REQ_DATA_FL", 10600 "IDMA_FL_DROP", 10601 "IDMA_FL_DROP_SEND_INC", 10602 "IDMA_FL_H_REQ_HEADER_FL", 10603 "IDMA_FL_H_SEND_PCIEHDR", 10604 "IDMA_FL_H_PUSH_CPL_FIFO", 10605 "IDMA_FL_H_SEND_CPL", 10606 "IDMA_FL_H_SEND_IP_HDR_FIRST", 10607 "IDMA_FL_H_SEND_IP_HDR", 10608 "IDMA_FL_H_REQ_NEXT_HEADER_FL", 10609 "IDMA_FL_H_SEND_NEXT_PCIEHDR", 10610 "IDMA_FL_H_SEND_IP_HDR_PADDING", 10611 "IDMA_FL_D_SEND_PCIEHDR", 10612 "IDMA_FL_D_SEND_CPL_AND_IP_HDR", 10613 "IDMA_FL_D_REQ_NEXT_DATA_FL", 10614 "IDMA_FL_SEND_PCIEHDR", 10615 "IDMA_FL_PUSH_CPL_FIFO", 10616 "IDMA_FL_SEND_CPL", 10617 "IDMA_FL_SEND_PAYLOAD_FIRST", 10618 "IDMA_FL_SEND_PAYLOAD", 10619 "IDMA_FL_REQ_NEXT_DATA_FL", 10620 "IDMA_FL_SEND_NEXT_PCIEHDR", 10621 "IDMA_FL_SEND_PADDING", 10622 "IDMA_FL_SEND_COMPLETION_TO_IMSG", 10623 }; 10624 static const char * const t6_decode[] = { 10625 "IDMA_IDLE", 10626 "IDMA_PUSH_MORE_CPL_FIFO", 10627 "IDMA_PUSH_CPL_MSG_HEADER_TO_FIFO", 10628 "IDMA_SGEFLRFLUSH_SEND_PCIEHDR", 10629 "IDMA_PHYSADDR_SEND_PCIEHDR", 10630 "IDMA_PHYSADDR_SEND_PAYLOAD_FIRST", 10631 "IDMA_PHYSADDR_SEND_PAYLOAD", 10632 "IDMA_FL_REQ_DATA_FL", 10633 "IDMA_FL_DROP", 10634 "IDMA_FL_DROP_SEND_INC", 10635 "IDMA_FL_H_REQ_HEADER_FL", 10636 "IDMA_FL_H_SEND_PCIEHDR", 10637 "IDMA_FL_H_PUSH_CPL_FIFO", 10638 "IDMA_FL_H_SEND_CPL", 10639 "IDMA_FL_H_SEND_IP_HDR_FIRST", 10640 "IDMA_FL_H_SEND_IP_HDR", 10641 "IDMA_FL_H_REQ_NEXT_HEADER_FL", 10642 "IDMA_FL_H_SEND_NEXT_PCIEHDR", 10643 "IDMA_FL_H_SEND_IP_HDR_PADDING", 10644 "IDMA_FL_D_SEND_PCIEHDR", 10645 "IDMA_FL_D_SEND_CPL_AND_IP_HDR", 10646 "IDMA_FL_D_REQ_NEXT_DATA_FL", 10647 "IDMA_FL_SEND_PCIEHDR", 10648 "IDMA_FL_PUSH_CPL_FIFO", 10649 "IDMA_FL_SEND_CPL", 10650 "IDMA_FL_SEND_PAYLOAD_FIRST", 10651 "IDMA_FL_SEND_PAYLOAD", 10652 "IDMA_FL_REQ_NEXT_DATA_FL", 10653 "IDMA_FL_SEND_NEXT_PCIEHDR", 10654 "IDMA_FL_SEND_PADDING", 10655 "IDMA_FL_SEND_COMPLETION_TO_IMSG", 10656 }; 10657 static const u32 sge_regs[] = { 10658 A_SGE_DEBUG_DATA_LOW_INDEX_2, 10659 A_SGE_DEBUG_DATA_LOW_INDEX_3, 10660 A_SGE_DEBUG_DATA_HIGH_INDEX_10, 10661 }; 10662 const char * const *sge_idma_decode; 10663 int sge_idma_decode_nstates; 10664 int i; 10665 unsigned int chip_version = chip_id(adapter); 10666 10667 /* Select the right set of decode strings to dump depending on the 10668 * adapter chip type. 10669 */ 10670 switch (chip_version) { 10671 case CHELSIO_T4: 10672 sge_idma_decode = (const char * const *)t4_decode; 10673 sge_idma_decode_nstates = ARRAY_SIZE(t4_decode); 10674 break; 10675 10676 case CHELSIO_T5: 10677 sge_idma_decode = (const char * const *)t5_decode; 10678 sge_idma_decode_nstates = ARRAY_SIZE(t5_decode); 10679 break; 10680 10681 case CHELSIO_T6: 10682 case CHELSIO_T7: 10683 sge_idma_decode = (const char * const *)t6_decode; 10684 sge_idma_decode_nstates = ARRAY_SIZE(t6_decode); 10685 break; 10686 10687 default: 10688 CH_ERR(adapter, "Unsupported chip version %d\n", chip_version); 10689 return; 10690 } 10691 10692 if (state < sge_idma_decode_nstates) 10693 CH_WARN(adapter, "idma state %s\n", sge_idma_decode[state]); 10694 else 10695 CH_WARN(adapter, "idma state %d unknown\n", state); 10696 10697 for (i = 0; i < ARRAY_SIZE(sge_regs); i++) 10698 CH_WARN(adapter, "SGE register %#x value %#x\n", 10699 sge_regs[i], t4_read_reg(adapter, sge_regs[i])); 10700 } 10701 10702 /** 10703 * t4_sge_ctxt_flush - flush the SGE context cache 10704 * @adap: the adapter 10705 * @mbox: mailbox to use for the FW command 10706 * 10707 * Issues a FW command through the given mailbox to flush the 10708 * SGE context cache. 10709 */ 10710 int t4_sge_ctxt_flush(struct adapter *adap, unsigned int mbox, int ctxt_type) 10711 { 10712 int ret; 10713 u32 ldst_addrspace; 10714 struct fw_ldst_cmd c; 10715 10716 memset(&c, 0, sizeof(c)); 10717 ldst_addrspace = V_FW_LDST_CMD_ADDRSPACE(ctxt_type == CTXT_EGRESS ? 10718 FW_LDST_ADDRSPC_SGE_EGRC : 10719 FW_LDST_ADDRSPC_SGE_INGC); 10720 c.op_to_addrspace = cpu_to_be32(V_FW_CMD_OP(FW_LDST_CMD) | 10721 F_FW_CMD_REQUEST | F_FW_CMD_READ | 10722 ldst_addrspace); 10723 c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c)); 10724 c.u.idctxt.msg_ctxtflush = cpu_to_be32(F_FW_LDST_CMD_CTXTFLUSH); 10725 10726 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); 10727 return ret; 10728 } 10729 10730 /** 10731 * t4_fw_hello - establish communication with FW 10732 * @adap: the adapter 10733 * @mbox: mailbox to use for the FW command 10734 * @evt_mbox: mailbox to receive async FW events 10735 * @master: specifies the caller's willingness to be the device master 10736 * @state: returns the current device state (if non-NULL) 10737 * 10738 * Issues a command to establish communication with FW. Returns either 10739 * an error (negative integer) or the mailbox of the Master PF. 10740 */ 10741 int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, 10742 enum dev_master master, enum dev_state *state) 10743 { 10744 int ret; 10745 struct fw_hello_cmd c; 10746 u32 v; 10747 unsigned int master_mbox; 10748 int retries = FW_CMD_HELLO_RETRIES; 10749 10750 retry: 10751 memset(&c, 0, sizeof(c)); 10752 INIT_CMD(c, HELLO, WRITE); 10753 c.err_to_clearinit = cpu_to_be32( 10754 V_FW_HELLO_CMD_MASTERDIS(master == MASTER_CANT) | 10755 V_FW_HELLO_CMD_MASTERFORCE(master == MASTER_MUST) | 10756 V_FW_HELLO_CMD_MBMASTER(master == MASTER_MUST ? 10757 mbox : M_FW_HELLO_CMD_MBMASTER) | 10758 V_FW_HELLO_CMD_MBASYNCNOT(evt_mbox) | 10759 V_FW_HELLO_CMD_STAGE(FW_HELLO_CMD_STAGE_OS) | 10760 F_FW_HELLO_CMD_CLEARINIT); 10761 10762 /* 10763 * Issue the HELLO command to the firmware. If it's not successful 10764 * but indicates that we got a "busy" or "timeout" condition, retry 10765 * the HELLO until we exhaust our retry limit. If we do exceed our 10766 * retry limit, check to see if the firmware left us any error 10767 * information and report that if so ... 10768 */ 10769 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); 10770 if (ret != FW_SUCCESS) { 10771 if ((ret == -EBUSY || ret == -ETIMEDOUT) && retries-- > 0) 10772 goto retry; 10773 return ret; 10774 } 10775 10776 v = be32_to_cpu(c.err_to_clearinit); 10777 master_mbox = G_FW_HELLO_CMD_MBMASTER(v); 10778 if (state) { 10779 if (v & F_FW_HELLO_CMD_ERR) 10780 *state = DEV_STATE_ERR; 10781 else if (v & F_FW_HELLO_CMD_INIT) 10782 *state = DEV_STATE_INIT; 10783 else 10784 *state = DEV_STATE_UNINIT; 10785 } 10786 10787 /* 10788 * If we're not the Master PF then we need to wait around for the 10789 * Master PF Driver to finish setting up the adapter. 10790 * 10791 * Note that we also do this wait if we're a non-Master-capable PF and 10792 * there is no current Master PF; a Master PF may show up momentarily 10793 * and we wouldn't want to fail pointlessly. (This can happen when an 10794 * OS loads lots of different drivers rapidly at the same time). In 10795 * this case, the Master PF returned by the firmware will be 10796 * M_PCIE_FW_MASTER so the test below will work ... 10797 */ 10798 if ((v & (F_FW_HELLO_CMD_ERR|F_FW_HELLO_CMD_INIT)) == 0 && 10799 master_mbox != mbox) { 10800 int waiting = FW_CMD_HELLO_TIMEOUT; 10801 10802 /* 10803 * Wait for the firmware to either indicate an error or 10804 * initialized state. If we see either of these we bail out 10805 * and report the issue to the caller. If we exhaust the 10806 * "hello timeout" and we haven't exhausted our retries, try 10807 * again. Otherwise bail with a timeout error. 10808 */ 10809 for (;;) { 10810 u32 pcie_fw; 10811 10812 msleep(50); 10813 waiting -= 50; 10814 10815 /* 10816 * If neither Error nor Initialialized are indicated 10817 * by the firmware keep waiting till we exhaust our 10818 * timeout ... and then retry if we haven't exhausted 10819 * our retries ... 10820 */ 10821 pcie_fw = t4_read_reg(adap, A_PCIE_FW); 10822 if (!(pcie_fw & (F_PCIE_FW_ERR|F_PCIE_FW_INIT))) { 10823 if (waiting <= 0) { 10824 if (retries-- > 0) 10825 goto retry; 10826 10827 return -ETIMEDOUT; 10828 } 10829 continue; 10830 } 10831 10832 /* 10833 * We either have an Error or Initialized condition 10834 * report errors preferentially. 10835 */ 10836 if (state) { 10837 if (pcie_fw & F_PCIE_FW_ERR) 10838 *state = DEV_STATE_ERR; 10839 else if (pcie_fw & F_PCIE_FW_INIT) 10840 *state = DEV_STATE_INIT; 10841 } 10842 10843 /* 10844 * If we arrived before a Master PF was selected and 10845 * there's not a valid Master PF, grab its identity 10846 * for our caller. 10847 */ 10848 if (master_mbox == M_PCIE_FW_MASTER && 10849 (pcie_fw & F_PCIE_FW_MASTER_VLD)) 10850 master_mbox = G_PCIE_FW_MASTER(pcie_fw); 10851 break; 10852 } 10853 } 10854 10855 return master_mbox; 10856 } 10857 10858 /** 10859 * t4_fw_bye - end communication with FW 10860 * @adap: the adapter 10861 * @mbox: mailbox to use for the FW command 10862 * 10863 * Issues a command to terminate communication with FW. 10864 */ 10865 int t4_fw_bye(struct adapter *adap, unsigned int mbox) 10866 { 10867 struct fw_bye_cmd c; 10868 10869 memset(&c, 0, sizeof(c)); 10870 INIT_CMD(c, BYE, WRITE); 10871 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 10872 } 10873 10874 /** 10875 * t4_fw_reset - issue a reset to FW 10876 * @adap: the adapter 10877 * @mbox: mailbox to use for the FW command 10878 * @reset: specifies the type of reset to perform 10879 * 10880 * Issues a reset command of the specified type to FW. 10881 */ 10882 int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset) 10883 { 10884 struct fw_reset_cmd c; 10885 10886 memset(&c, 0, sizeof(c)); 10887 INIT_CMD(c, RESET, WRITE); 10888 c.val = cpu_to_be32(reset); 10889 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 10890 } 10891 10892 /** 10893 * t4_fw_halt - issue a reset/halt to FW and put uP into RESET 10894 * @adap: the adapter 10895 * @mbox: mailbox to use for the FW RESET command (if desired) 10896 * @force: force uP into RESET even if FW RESET command fails 10897 * 10898 * Issues a RESET command to firmware (if desired) with a HALT indication 10899 * and then puts the microprocessor into RESET state. The RESET command 10900 * will only be issued if a legitimate mailbox is provided (mbox <= 10901 * M_PCIE_FW_MASTER). 10902 * 10903 * This is generally used in order for the host to safely manipulate the 10904 * adapter without fear of conflicting with whatever the firmware might 10905 * be doing. The only way out of this state is to RESTART the firmware 10906 * ... 10907 */ 10908 int t4_fw_halt(struct adapter *adap, unsigned int mbox, int force) 10909 { 10910 int ret = 0; 10911 10912 /* 10913 * If a legitimate mailbox is provided, issue a RESET command 10914 * with a HALT indication. 10915 */ 10916 if (adap->flags & FW_OK && mbox <= M_PCIE_FW_MASTER) { 10917 struct fw_reset_cmd c; 10918 10919 memset(&c, 0, sizeof(c)); 10920 INIT_CMD(c, RESET, WRITE); 10921 c.val = cpu_to_be32(F_PIORST | F_PIORSTMODE); 10922 c.halt_pkd = cpu_to_be32(F_FW_RESET_CMD_HALT); 10923 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 10924 } 10925 10926 /* 10927 * Normally we won't complete the operation if the firmware RESET 10928 * command fails but if our caller insists we'll go ahead and put the 10929 * uP into RESET. This can be useful if the firmware is hung or even 10930 * missing ... We'll have to take the risk of putting the uP into 10931 * RESET without the cooperation of firmware in that case. 10932 * 10933 * We also force the firmware's HALT flag to be on in case we bypassed 10934 * the firmware RESET command above or we're dealing with old firmware 10935 * which doesn't have the HALT capability. This will serve as a flag 10936 * for the incoming firmware to know that it's coming out of a HALT 10937 * rather than a RESET ... if it's new enough to understand that ... 10938 */ 10939 if (ret == 0 || force) { 10940 t4_set_reg_field(adap, A_CIM_BOOT_CFG, F_UPCRST, F_UPCRST); 10941 t4_set_reg_field(adap, A_PCIE_FW, F_PCIE_FW_HALT, 10942 F_PCIE_FW_HALT); 10943 } 10944 10945 /* 10946 * And we always return the result of the firmware RESET command 10947 * even when we force the uP into RESET ... 10948 */ 10949 return ret; 10950 } 10951 10952 /** 10953 * t4_fw_restart - restart the firmware by taking the uP out of RESET 10954 * @adap: the adapter 10955 * 10956 * Restart firmware previously halted by t4_fw_halt(). On successful 10957 * return the previous PF Master remains as the new PF Master and there 10958 * is no need to issue a new HELLO command, etc. 10959 */ 10960 int t4_fw_restart(struct adapter *adap, unsigned int mbox) 10961 { 10962 int ms; 10963 10964 t4_set_reg_field(adap, A_CIM_BOOT_CFG, F_UPCRST, 0); 10965 for (ms = 0; ms < FW_CMD_MAX_TIMEOUT; ) { 10966 if (!(t4_read_reg(adap, A_PCIE_FW) & F_PCIE_FW_HALT)) 10967 return FW_SUCCESS; 10968 msleep(100); 10969 ms += 100; 10970 } 10971 10972 return -ETIMEDOUT; 10973 } 10974 10975 /** 10976 * t4_fw_upgrade - perform all of the steps necessary to upgrade FW 10977 * @adap: the adapter 10978 * @mbox: mailbox to use for the FW RESET command (if desired) 10979 * @fw_data: the firmware image to write 10980 * @size: image size 10981 * @force: force upgrade even if firmware doesn't cooperate 10982 * 10983 * Perform all of the steps necessary for upgrading an adapter's 10984 * firmware image. Normally this requires the cooperation of the 10985 * existing firmware in order to halt all existing activities 10986 * but if an invalid mailbox token is passed in we skip that step 10987 * (though we'll still put the adapter microprocessor into RESET in 10988 * that case). 10989 * 10990 * On successful return the new firmware will have been loaded and 10991 * the adapter will have been fully RESET losing all previous setup 10992 * state. On unsuccessful return the adapter may be completely hosed ... 10993 * positive errno indicates that the adapter is ~probably~ intact, a 10994 * negative errno indicates that things are looking bad ... 10995 */ 10996 int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, 10997 const u8 *fw_data, unsigned int size, int force) 10998 { 10999 const struct fw_hdr *fw_hdr = (const struct fw_hdr *)fw_data; 11000 unsigned int bootstrap = 11001 be32_to_cpu(fw_hdr->magic) == FW_HDR_MAGIC_BOOTSTRAP; 11002 int ret; 11003 11004 if (!t4_fw_matches_chip(adap, fw_hdr)) 11005 return -EINVAL; 11006 11007 if (!bootstrap) { 11008 ret = t4_fw_halt(adap, mbox, force); 11009 if (ret < 0 && !force) 11010 return ret; 11011 } 11012 11013 ret = t4_load_fw(adap, fw_data, size); 11014 if (ret < 0 || bootstrap) 11015 return ret; 11016 11017 return t4_fw_restart(adap, mbox); 11018 } 11019 11020 /** 11021 * t4_fw_initialize - ask FW to initialize the device 11022 * @adap: the adapter 11023 * @mbox: mailbox to use for the FW command 11024 * 11025 * Issues a command to FW to partially initialize the device. This 11026 * performs initialization that generally doesn't depend on user input. 11027 */ 11028 int t4_fw_initialize(struct adapter *adap, unsigned int mbox) 11029 { 11030 struct fw_initialize_cmd c; 11031 11032 memset(&c, 0, sizeof(c)); 11033 INIT_CMD(c, INITIALIZE, WRITE); 11034 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 11035 } 11036 11037 /** 11038 * t4_query_params_rw - query FW or device parameters 11039 * @adap: the adapter 11040 * @mbox: mailbox to use for the FW command 11041 * @pf: the PF 11042 * @vf: the VF 11043 * @nparams: the number of parameters 11044 * @params: the parameter names 11045 * @val: the parameter values 11046 * @rw: Write and read flag 11047 * 11048 * Reads the value of FW or device parameters. Up to 7 parameters can be 11049 * queried at once. 11050 */ 11051 int t4_query_params_rw(struct adapter *adap, unsigned int mbox, unsigned int pf, 11052 unsigned int vf, unsigned int nparams, const u32 *params, 11053 u32 *val, int rw) 11054 { 11055 int i, ret; 11056 struct fw_params_cmd c; 11057 __be32 *p = &c.param[0].mnem; 11058 11059 if (nparams > 7) 11060 return -EINVAL; 11061 11062 memset(&c, 0, sizeof(c)); 11063 c.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_PARAMS_CMD) | 11064 F_FW_CMD_REQUEST | F_FW_CMD_READ | 11065 V_FW_PARAMS_CMD_PFN(pf) | 11066 V_FW_PARAMS_CMD_VFN(vf)); 11067 c.retval_len16 = cpu_to_be32(FW_LEN16(c)); 11068 11069 for (i = 0; i < nparams; i++) { 11070 *p++ = cpu_to_be32(*params++); 11071 if (rw) 11072 *p = cpu_to_be32(*(val + i)); 11073 p++; 11074 } 11075 11076 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); 11077 11078 /* 11079 * We always copy back the results, even if there's an error. We'll 11080 * get an error if any of the parameters was unknown to the Firmware, 11081 * but there will be results for the others ... (Older Firmware 11082 * stopped at the first unknown parameter; newer Firmware processes 11083 * them all and flags the unknown parameters with a return value of 11084 * ~0UL.) 11085 */ 11086 for (i = 0, p = &c.param[0].val; i < nparams; i++, p += 2) 11087 *val++ = be32_to_cpu(*p); 11088 11089 return ret; 11090 } 11091 11092 int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf, 11093 unsigned int vf, unsigned int nparams, const u32 *params, 11094 u32 *val) 11095 { 11096 return t4_query_params_rw(adap, mbox, pf, vf, nparams, params, val, 0); 11097 } 11098 11099 /** 11100 * t4_set_params_timeout - sets FW or device parameters 11101 * @adap: the adapter 11102 * @mbox: mailbox to use for the FW command 11103 * @pf: the PF 11104 * @vf: the VF 11105 * @nparams: the number of parameters 11106 * @params: the parameter names 11107 * @val: the parameter values 11108 * @timeout: the timeout time 11109 * 11110 * Sets the value of FW or device parameters. Up to 7 parameters can be 11111 * specified at once. 11112 */ 11113 int t4_set_params_timeout(struct adapter *adap, unsigned int mbox, 11114 unsigned int pf, unsigned int vf, 11115 unsigned int nparams, const u32 *params, 11116 const u32 *val, int timeout) 11117 { 11118 struct fw_params_cmd c; 11119 __be32 *p = &c.param[0].mnem; 11120 11121 if (nparams > 7) 11122 return -EINVAL; 11123 11124 memset(&c, 0, sizeof(c)); 11125 c.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_PARAMS_CMD) | 11126 F_FW_CMD_REQUEST | F_FW_CMD_WRITE | 11127 V_FW_PARAMS_CMD_PFN(pf) | 11128 V_FW_PARAMS_CMD_VFN(vf)); 11129 c.retval_len16 = cpu_to_be32(FW_LEN16(c)); 11130 11131 while (nparams--) { 11132 *p++ = cpu_to_be32(*params++); 11133 *p++ = cpu_to_be32(*val++); 11134 } 11135 11136 return t4_wr_mbox_timeout(adap, mbox, &c, sizeof(c), NULL, timeout); 11137 } 11138 11139 /** 11140 * t4_set_params - sets FW or device parameters 11141 * @adap: the adapter 11142 * @mbox: mailbox to use for the FW command 11143 * @pf: the PF 11144 * @vf: the VF 11145 * @nparams: the number of parameters 11146 * @params: the parameter names 11147 * @val: the parameter values 11148 * 11149 * Sets the value of FW or device parameters. Up to 7 parameters can be 11150 * specified at once. 11151 */ 11152 int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf, 11153 unsigned int vf, unsigned int nparams, const u32 *params, 11154 const u32 *val) 11155 { 11156 return t4_set_params_timeout(adap, mbox, pf, vf, nparams, params, val, 11157 FW_CMD_MAX_TIMEOUT); 11158 } 11159 11160 /** 11161 * t4_cfg_pfvf - configure PF/VF resource limits 11162 * @adap: the adapter 11163 * @mbox: mailbox to use for the FW command 11164 * @pf: the PF being configured 11165 * @vf: the VF being configured 11166 * @txq: the max number of egress queues 11167 * @txq_eth_ctrl: the max number of egress Ethernet or control queues 11168 * @rxqi: the max number of interrupt-capable ingress queues 11169 * @rxq: the max number of interruptless ingress queues 11170 * @tc: the PCI traffic class 11171 * @vi: the max number of virtual interfaces 11172 * @cmask: the channel access rights mask for the PF/VF 11173 * @pmask: the port access rights mask for the PF/VF 11174 * @nexact: the maximum number of exact MPS filters 11175 * @rcaps: read capabilities 11176 * @wxcaps: write/execute capabilities 11177 * 11178 * Configures resource limits and capabilities for a physical or virtual 11179 * function. 11180 */ 11181 int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf, 11182 unsigned int vf, unsigned int txq, unsigned int txq_eth_ctrl, 11183 unsigned int rxqi, unsigned int rxq, unsigned int tc, 11184 unsigned int vi, unsigned int cmask, unsigned int pmask, 11185 unsigned int nexact, unsigned int rcaps, unsigned int wxcaps) 11186 { 11187 struct fw_pfvf_cmd c; 11188 11189 memset(&c, 0, sizeof(c)); 11190 c.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_PFVF_CMD) | F_FW_CMD_REQUEST | 11191 F_FW_CMD_WRITE | V_FW_PFVF_CMD_PFN(pf) | 11192 V_FW_PFVF_CMD_VFN(vf)); 11193 c.retval_len16 = cpu_to_be32(FW_LEN16(c)); 11194 c.niqflint_niq = cpu_to_be32(V_FW_PFVF_CMD_NIQFLINT(rxqi) | 11195 V_FW_PFVF_CMD_NIQ(rxq)); 11196 c.type_to_neq = cpu_to_be32(V_FW_PFVF_CMD_CMASK(cmask) | 11197 V_FW_PFVF_CMD_PMASK(pmask) | 11198 V_FW_PFVF_CMD_NEQ(txq)); 11199 c.tc_to_nexactf = cpu_to_be32(V_FW_PFVF_CMD_TC(tc) | 11200 V_FW_PFVF_CMD_NVI(vi) | 11201 V_FW_PFVF_CMD_NEXACTF(nexact)); 11202 c.r_caps_to_nethctrl = cpu_to_be32(V_FW_PFVF_CMD_R_CAPS(rcaps) | 11203 V_FW_PFVF_CMD_WX_CAPS(wxcaps) | 11204 V_FW_PFVF_CMD_NETHCTRL(txq_eth_ctrl)); 11205 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 11206 } 11207 11208 /** 11209 * t4_alloc_vi_func - allocate a virtual interface 11210 * @adap: the adapter 11211 * @mbox: mailbox to use for the FW command 11212 * @port: physical port associated with the VI 11213 * @pf: the PF owning the VI 11214 * @vf: the VF owning the VI 11215 * @nmac: number of MAC addresses needed (1 to 5) 11216 * @mac: the MAC addresses of the VI 11217 * @rss_size: size of RSS table slice associated with this VI 11218 * @portfunc: which Port Application Function MAC Address is desired 11219 * @idstype: Intrusion Detection Type 11220 * 11221 * Allocates a virtual interface for the given physical port. If @mac is 11222 * not %NULL it contains the MAC addresses of the VI as assigned by FW. 11223 * If @rss_size is %NULL the VI is not assigned any RSS slice by FW. 11224 * @mac should be large enough to hold @nmac Ethernet addresses, they are 11225 * stored consecutively so the space needed is @nmac * 6 bytes. 11226 * Returns a negative error number or the non-negative VI id. 11227 */ 11228 int t4_alloc_vi_func(struct adapter *adap, unsigned int mbox, 11229 unsigned int port, unsigned int pf, unsigned int vf, 11230 unsigned int nmac, u8 *mac, u16 *rss_size, 11231 uint8_t *vfvld, uint16_t *vin, 11232 unsigned int portfunc, unsigned int idstype) 11233 { 11234 int ret; 11235 struct fw_vi_cmd c; 11236 11237 memset(&c, 0, sizeof(c)); 11238 c.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_VI_CMD) | F_FW_CMD_REQUEST | 11239 F_FW_CMD_WRITE | F_FW_CMD_EXEC | 11240 V_FW_VI_CMD_PFN(pf) | V_FW_VI_CMD_VFN(vf)); 11241 c.alloc_to_len16 = cpu_to_be32(F_FW_VI_CMD_ALLOC | FW_LEN16(c)); 11242 c.type_to_viid = cpu_to_be16(V_FW_VI_CMD_TYPE(idstype) | 11243 V_FW_VI_CMD_FUNC(portfunc)); 11244 c.portid_pkd = V_FW_VI_CMD_PORTID(port); 11245 c.nmac = nmac - 1; 11246 if(!rss_size) 11247 c.norss_rsssize = F_FW_VI_CMD_NORSS; 11248 11249 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); 11250 if (ret) 11251 return ret; 11252 ret = G_FW_VI_CMD_VIID(be16_to_cpu(c.type_to_viid)); 11253 11254 if (mac) { 11255 memcpy(mac, c.mac, sizeof(c.mac)); 11256 switch (nmac) { 11257 case 5: 11258 memcpy(mac + 24, c.nmac3, sizeof(c.nmac3)); 11259 case 4: 11260 memcpy(mac + 18, c.nmac2, sizeof(c.nmac2)); 11261 case 3: 11262 memcpy(mac + 12, c.nmac1, sizeof(c.nmac1)); 11263 case 2: 11264 memcpy(mac + 6, c.nmac0, sizeof(c.nmac0)); 11265 } 11266 } 11267 if (rss_size) 11268 *rss_size = G_FW_VI_CMD_RSSSIZE(be16_to_cpu(c.norss_rsssize)); 11269 if (vfvld) { 11270 *vfvld = adap->params.viid_smt_extn_support ? 11271 G_FW_VI_CMD_VFVLD(be32_to_cpu(c.alloc_to_len16)) : 11272 G_FW_VIID_VIVLD(ret); 11273 } 11274 if (vin) { 11275 *vin = adap->params.viid_smt_extn_support ? 11276 G_FW_VI_CMD_VIN(be32_to_cpu(c.alloc_to_len16)) : 11277 G_FW_VIID_VIN(ret); 11278 } 11279 11280 return ret; 11281 } 11282 11283 /** 11284 * t4_alloc_vi - allocate an [Ethernet Function] virtual interface 11285 * @adap: the adapter 11286 * @mbox: mailbox to use for the FW command 11287 * @port: physical port associated with the VI 11288 * @pf: the PF owning the VI 11289 * @vf: the VF owning the VI 11290 * @nmac: number of MAC addresses needed (1 to 5) 11291 * @mac: the MAC addresses of the VI 11292 * @rss_size: size of RSS table slice associated with this VI 11293 * 11294 * backwards compatible and convieniance routine to allocate a Virtual 11295 * Interface with a Ethernet Port Application Function and Intrustion 11296 * Detection System disabled. 11297 */ 11298 int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port, 11299 unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac, 11300 u16 *rss_size, uint8_t *vfvld, uint16_t *vin) 11301 { 11302 return t4_alloc_vi_func(adap, mbox, port, pf, vf, nmac, mac, rss_size, 11303 vfvld, vin, FW_VI_FUNC_ETH, 0); 11304 } 11305 11306 /** 11307 * t4_free_vi - free a virtual interface 11308 * @adap: the adapter 11309 * @mbox: mailbox to use for the FW command 11310 * @pf: the PF owning the VI 11311 * @vf: the VF owning the VI 11312 * @viid: virtual interface identifiler 11313 * 11314 * Free a previously allocated virtual interface. 11315 */ 11316 int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf, 11317 unsigned int vf, unsigned int viid) 11318 { 11319 struct fw_vi_cmd c; 11320 11321 memset(&c, 0, sizeof(c)); 11322 c.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_VI_CMD) | 11323 F_FW_CMD_REQUEST | 11324 F_FW_CMD_EXEC | 11325 V_FW_VI_CMD_PFN(pf) | 11326 V_FW_VI_CMD_VFN(vf)); 11327 c.alloc_to_len16 = cpu_to_be32(F_FW_VI_CMD_FREE | FW_LEN16(c)); 11328 c.type_to_viid = cpu_to_be16(V_FW_VI_CMD_VIID(viid)); 11329 11330 return t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); 11331 } 11332 11333 /** 11334 * t4_set_rxmode - set Rx properties of a virtual interface 11335 * @adap: the adapter 11336 * @mbox: mailbox to use for the FW command 11337 * @viid: the VI id 11338 * @mtu: the new MTU or -1 11339 * @promisc: 1 to enable promiscuous mode, 0 to disable it, -1 no change 11340 * @all_multi: 1 to enable all-multi mode, 0 to disable it, -1 no change 11341 * @bcast: 1 to enable broadcast Rx, 0 to disable it, -1 no change 11342 * @vlanex: 1 to enable HW VLAN extraction, 0 to disable it, -1 no change 11343 * @sleep_ok: if true we may sleep while awaiting command completion 11344 * 11345 * Sets Rx properties of a virtual interface. 11346 */ 11347 int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid, 11348 int mtu, int promisc, int all_multi, int bcast, int vlanex, 11349 bool sleep_ok) 11350 { 11351 struct fw_vi_rxmode_cmd c; 11352 11353 /* convert to FW values */ 11354 if (mtu < 0) 11355 mtu = M_FW_VI_RXMODE_CMD_MTU; 11356 if (promisc < 0) 11357 promisc = M_FW_VI_RXMODE_CMD_PROMISCEN; 11358 if (all_multi < 0) 11359 all_multi = M_FW_VI_RXMODE_CMD_ALLMULTIEN; 11360 if (bcast < 0) 11361 bcast = M_FW_VI_RXMODE_CMD_BROADCASTEN; 11362 if (vlanex < 0) 11363 vlanex = M_FW_VI_RXMODE_CMD_VLANEXEN; 11364 11365 memset(&c, 0, sizeof(c)); 11366 c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_VI_RXMODE_CMD) | 11367 F_FW_CMD_REQUEST | F_FW_CMD_WRITE | 11368 V_FW_VI_RXMODE_CMD_VIID(viid)); 11369 c.retval_len16 = cpu_to_be32(FW_LEN16(c)); 11370 c.mtu_to_vlanexen = 11371 cpu_to_be32(V_FW_VI_RXMODE_CMD_MTU(mtu) | 11372 V_FW_VI_RXMODE_CMD_PROMISCEN(promisc) | 11373 V_FW_VI_RXMODE_CMD_ALLMULTIEN(all_multi) | 11374 V_FW_VI_RXMODE_CMD_BROADCASTEN(bcast) | 11375 V_FW_VI_RXMODE_CMD_VLANEXEN(vlanex)); 11376 return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok); 11377 } 11378 11379 /** 11380 * t4_alloc_encap_mac_filt - Adds a mac entry in mps tcam with VNI support 11381 * @adap: the adapter 11382 * @viid: the VI id 11383 * @mac: the MAC address 11384 * @mask: the mask 11385 * @vni: the VNI id for the tunnel protocol 11386 * @vni_mask: mask for the VNI id 11387 * @dip_hit: to enable DIP match for the MPS entry 11388 * @lookup_type: MAC address for inner (1) or outer (0) header 11389 * @sleep_ok: call is allowed to sleep 11390 * 11391 * Allocates an MPS entry with specified MAC address and VNI value. 11392 * 11393 * Returns a negative error number or the allocated index for this mac. 11394 */ 11395 int t4_alloc_encap_mac_filt(struct adapter *adap, unsigned int viid, 11396 const u8 *addr, const u8 *mask, unsigned int vni, 11397 unsigned int vni_mask, u8 dip_hit, u8 lookup_type, 11398 bool sleep_ok) 11399 { 11400 struct fw_vi_mac_cmd c; 11401 struct fw_vi_mac_vni *p = c.u.exact_vni; 11402 int ret = 0; 11403 u32 val; 11404 11405 memset(&c, 0, sizeof(c)); 11406 c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_VI_MAC_CMD) | 11407 F_FW_CMD_REQUEST | F_FW_CMD_WRITE | 11408 V_FW_VI_MAC_CMD_VIID(viid)); 11409 val = V_FW_CMD_LEN16(1) | 11410 V_FW_VI_MAC_CMD_ENTRY_TYPE(FW_VI_MAC_TYPE_EXACTMAC_VNI); 11411 c.freemacs_to_len16 = cpu_to_be32(val); 11412 p->valid_to_idx = cpu_to_be16(F_FW_VI_MAC_CMD_VALID | 11413 V_FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC)); 11414 memcpy(p->macaddr, addr, sizeof(p->macaddr)); 11415 memcpy(p->macaddr_mask, mask, sizeof(p->macaddr_mask)); 11416 11417 p->lookup_type_to_vni = cpu_to_be32(V_FW_VI_MAC_CMD_VNI(vni) | 11418 V_FW_VI_MAC_CMD_DIP_HIT(dip_hit) | 11419 V_FW_VI_MAC_CMD_LOOKUP_TYPE(lookup_type)); 11420 p->vni_mask_pkd = cpu_to_be32(V_FW_VI_MAC_CMD_VNI_MASK(vni_mask)); 11421 11422 ret = t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c, sleep_ok); 11423 if (ret == 0) 11424 ret = G_FW_VI_MAC_CMD_IDX(be16_to_cpu(p->valid_to_idx)); 11425 return ret; 11426 } 11427 11428 /** 11429 * t4_alloc_raw_mac_filt - Adds a mac entry in mps tcam 11430 * @adap: the adapter 11431 * @viid: the VI id 11432 * @mac: the MAC address 11433 * @mask: the mask 11434 * @idx: index at which to add this entry 11435 * @port_id: the port index 11436 * @lookup_type: MAC address for inner (1) or outer (0) header 11437 * @sleep_ok: call is allowed to sleep 11438 * 11439 * Adds the mac entry at the specified index using raw mac interface. 11440 * 11441 * Returns a negative error number or the allocated index for this mac. 11442 */ 11443 int t4_alloc_raw_mac_filt(struct adapter *adap, unsigned int viid, 11444 const u8 *addr, const u8 *mask, unsigned int idx, 11445 u8 lookup_type, u8 port_id, bool sleep_ok) 11446 { 11447 int ret = 0; 11448 struct fw_vi_mac_cmd c; 11449 struct fw_vi_mac_raw *p = &c.u.raw; 11450 u32 val; 11451 11452 memset(&c, 0, sizeof(c)); 11453 c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_VI_MAC_CMD) | 11454 F_FW_CMD_REQUEST | F_FW_CMD_WRITE | 11455 V_FW_VI_MAC_CMD_VIID(viid)); 11456 val = V_FW_CMD_LEN16(1) | 11457 V_FW_VI_MAC_CMD_ENTRY_TYPE(FW_VI_MAC_TYPE_RAW); 11458 c.freemacs_to_len16 = cpu_to_be32(val); 11459 11460 /* Specify that this is an inner mac address */ 11461 p->raw_idx_pkd = cpu_to_be32(V_FW_VI_MAC_CMD_RAW_IDX(idx)); 11462 11463 /* Lookup Type. Outer header: 0, Inner header: 1 */ 11464 p->data0_pkd = cpu_to_be32(V_DATALKPTYPE(lookup_type) | 11465 V_DATAPORTNUM(port_id)); 11466 /* Lookup mask and port mask */ 11467 p->data0m_pkd = cpu_to_be64(V_DATALKPTYPE(M_DATALKPTYPE) | 11468 V_DATAPORTNUM(M_DATAPORTNUM)); 11469 11470 /* Copy the address and the mask */ 11471 memcpy((u8 *)&p->data1[0] + 2, addr, ETHER_ADDR_LEN); 11472 memcpy((u8 *)&p->data1m[0] + 2, mask, ETHER_ADDR_LEN); 11473 11474 ret = t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c, sleep_ok); 11475 if (ret == 0) { 11476 ret = G_FW_VI_MAC_CMD_RAW_IDX(be32_to_cpu(p->raw_idx_pkd)); 11477 if (ret != idx) 11478 ret = -ENOMEM; 11479 } 11480 11481 return ret; 11482 } 11483 11484 /** 11485 * t4_alloc_mac_filt - allocates exact-match filters for MAC addresses 11486 * @adap: the adapter 11487 * @mbox: mailbox to use for the FW command 11488 * @viid: the VI id 11489 * @free: if true any existing filters for this VI id are first removed 11490 * @naddr: the number of MAC addresses to allocate filters for (up to 7) 11491 * @addr: the MAC address(es) 11492 * @idx: where to store the index of each allocated filter 11493 * @hash: pointer to hash address filter bitmap 11494 * @sleep_ok: call is allowed to sleep 11495 * 11496 * Allocates an exact-match filter for each of the supplied addresses and 11497 * sets it to the corresponding address. If @idx is not %NULL it should 11498 * have at least @naddr entries, each of which will be set to the index of 11499 * the filter allocated for the corresponding MAC address. If a filter 11500 * could not be allocated for an address its index is set to 0xffff. 11501 * If @hash is not %NULL addresses that fail to allocate an exact filter 11502 * are hashed and update the hash filter bitmap pointed at by @hash. 11503 * 11504 * Returns a negative error number or the number of filters allocated. 11505 */ 11506 int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, 11507 unsigned int viid, bool free, unsigned int naddr, 11508 const u8 **addr, u16 *idx, u64 *hash, bool sleep_ok) 11509 { 11510 int offset, ret = 0; 11511 struct fw_vi_mac_cmd c; 11512 unsigned int nfilters = 0; 11513 unsigned int max_naddr = adap->chip_params->mps_tcam_size; 11514 unsigned int rem = naddr; 11515 11516 if (naddr > max_naddr) 11517 return -EINVAL; 11518 11519 for (offset = 0; offset < naddr ; /**/) { 11520 unsigned int fw_naddr = (rem < ARRAY_SIZE(c.u.exact) 11521 ? rem 11522 : ARRAY_SIZE(c.u.exact)); 11523 size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd, 11524 u.exact[fw_naddr]), 16); 11525 struct fw_vi_mac_exact *p; 11526 int i; 11527 11528 memset(&c, 0, sizeof(c)); 11529 c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_VI_MAC_CMD) | 11530 F_FW_CMD_REQUEST | 11531 F_FW_CMD_WRITE | 11532 V_FW_CMD_EXEC(free) | 11533 V_FW_VI_MAC_CMD_VIID(viid)); 11534 c.freemacs_to_len16 = cpu_to_be32(V_FW_VI_MAC_CMD_FREEMACS(free) | 11535 V_FW_CMD_LEN16(len16)); 11536 11537 for (i = 0, p = c.u.exact; i < fw_naddr; i++, p++) { 11538 p->valid_to_idx = 11539 cpu_to_be16(F_FW_VI_MAC_CMD_VALID | 11540 V_FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC)); 11541 memcpy(p->macaddr, addr[offset+i], sizeof(p->macaddr)); 11542 } 11543 11544 /* 11545 * It's okay if we run out of space in our MAC address arena. 11546 * Some of the addresses we submit may get stored so we need 11547 * to run through the reply to see what the results were ... 11548 */ 11549 ret = t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), &c, sleep_ok); 11550 if (ret && ret != -FW_ENOMEM) 11551 break; 11552 11553 for (i = 0, p = c.u.exact; i < fw_naddr; i++, p++) { 11554 u16 index = G_FW_VI_MAC_CMD_IDX( 11555 be16_to_cpu(p->valid_to_idx)); 11556 11557 if (idx) 11558 idx[offset+i] = (index >= max_naddr 11559 ? 0xffff 11560 : index); 11561 if (index < max_naddr) 11562 nfilters++; 11563 else if (hash) 11564 *hash |= (1ULL << hash_mac_addr(addr[offset+i])); 11565 } 11566 11567 free = false; 11568 offset += fw_naddr; 11569 rem -= fw_naddr; 11570 } 11571 11572 if (ret == 0 || ret == -FW_ENOMEM) 11573 ret = nfilters; 11574 return ret; 11575 } 11576 11577 /** 11578 * t4_free_encap_mac_filt - frees MPS entry at given index 11579 * @adap: the adapter 11580 * @viid: the VI id 11581 * @idx: index of MPS entry to be freed 11582 * @sleep_ok: call is allowed to sleep 11583 * 11584 * Frees the MPS entry at supplied index 11585 * 11586 * Returns a negative error number or zero on success 11587 */ 11588 int t4_free_encap_mac_filt(struct adapter *adap, unsigned int viid, 11589 int idx, bool sleep_ok) 11590 { 11591 struct fw_vi_mac_exact *p; 11592 struct fw_vi_mac_cmd c; 11593 u8 addr[] = {0,0,0,0,0,0}; 11594 int ret = 0; 11595 u32 exact; 11596 11597 memset(&c, 0, sizeof(c)); 11598 c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_VI_MAC_CMD) | 11599 F_FW_CMD_REQUEST | 11600 F_FW_CMD_WRITE | 11601 V_FW_CMD_EXEC(0) | 11602 V_FW_VI_MAC_CMD_VIID(viid)); 11603 exact = V_FW_VI_MAC_CMD_ENTRY_TYPE(FW_VI_MAC_TYPE_EXACTMAC); 11604 c.freemacs_to_len16 = cpu_to_be32(V_FW_VI_MAC_CMD_FREEMACS(0) | 11605 exact | 11606 V_FW_CMD_LEN16(1)); 11607 p = c.u.exact; 11608 p->valid_to_idx = cpu_to_be16(F_FW_VI_MAC_CMD_VALID | 11609 V_FW_VI_MAC_CMD_IDX(idx)); 11610 memcpy(p->macaddr, addr, sizeof(p->macaddr)); 11611 11612 ret = t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c, sleep_ok); 11613 return ret; 11614 } 11615 11616 /** 11617 * t4_free_raw_mac_filt - Frees a raw mac entry in mps tcam 11618 * @adap: the adapter 11619 * @viid: the VI id 11620 * @addr: the MAC address 11621 * @mask: the mask 11622 * @idx: index of the entry in mps tcam 11623 * @lookup_type: MAC address for inner (1) or outer (0) header 11624 * @port_id: the port index 11625 * @sleep_ok: call is allowed to sleep 11626 * 11627 * Removes the mac entry at the specified index using raw mac interface. 11628 * 11629 * Returns a negative error number on failure. 11630 */ 11631 int t4_free_raw_mac_filt(struct adapter *adap, unsigned int viid, 11632 const u8 *addr, const u8 *mask, unsigned int idx, 11633 u8 lookup_type, u8 port_id, bool sleep_ok) 11634 { 11635 struct fw_vi_mac_cmd c; 11636 struct fw_vi_mac_raw *p = &c.u.raw; 11637 u32 raw; 11638 11639 memset(&c, 0, sizeof(c)); 11640 c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_VI_MAC_CMD) | 11641 F_FW_CMD_REQUEST | F_FW_CMD_WRITE | 11642 V_FW_CMD_EXEC(0) | 11643 V_FW_VI_MAC_CMD_VIID(viid)); 11644 raw = V_FW_VI_MAC_CMD_ENTRY_TYPE(FW_VI_MAC_TYPE_RAW); 11645 c.freemacs_to_len16 = cpu_to_be32(V_FW_VI_MAC_CMD_FREEMACS(0) | 11646 raw | 11647 V_FW_CMD_LEN16(1)); 11648 11649 p->raw_idx_pkd = cpu_to_be32(V_FW_VI_MAC_CMD_RAW_IDX(idx) | 11650 FW_VI_MAC_ID_BASED_FREE); 11651 11652 /* Lookup Type. Outer header: 0, Inner header: 1 */ 11653 p->data0_pkd = cpu_to_be32(V_DATALKPTYPE(lookup_type) | 11654 V_DATAPORTNUM(port_id)); 11655 /* Lookup mask and port mask */ 11656 p->data0m_pkd = cpu_to_be64(V_DATALKPTYPE(M_DATALKPTYPE) | 11657 V_DATAPORTNUM(M_DATAPORTNUM)); 11658 11659 /* Copy the address and the mask */ 11660 memcpy((u8 *)&p->data1[0] + 2, addr, ETHER_ADDR_LEN); 11661 memcpy((u8 *)&p->data1m[0] + 2, mask, ETHER_ADDR_LEN); 11662 11663 return t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c, sleep_ok); 11664 } 11665 11666 /** 11667 * t4_free_mac_filt - frees exact-match filters of given MAC addresses 11668 * @adap: the adapter 11669 * @mbox: mailbox to use for the FW command 11670 * @viid: the VI id 11671 * @naddr: the number of MAC addresses to allocate filters for (up to 7) 11672 * @addr: the MAC address(es) 11673 * @sleep_ok: call is allowed to sleep 11674 * 11675 * Frees the exact-match filter for each of the supplied addresses 11676 * 11677 * Returns a negative error number or the number of filters freed. 11678 */ 11679 int t4_free_mac_filt(struct adapter *adap, unsigned int mbox, 11680 unsigned int viid, unsigned int naddr, 11681 const u8 **addr, bool sleep_ok) 11682 { 11683 int offset, ret = 0; 11684 struct fw_vi_mac_cmd c; 11685 unsigned int nfilters = 0; 11686 unsigned int max_naddr = adap->chip_params->mps_tcam_size; 11687 unsigned int rem = naddr; 11688 11689 if (naddr > max_naddr) 11690 return -EINVAL; 11691 11692 for (offset = 0; offset < (int)naddr ; /**/) { 11693 unsigned int fw_naddr = (rem < ARRAY_SIZE(c.u.exact) 11694 ? rem 11695 : ARRAY_SIZE(c.u.exact)); 11696 size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd, 11697 u.exact[fw_naddr]), 16); 11698 struct fw_vi_mac_exact *p; 11699 int i; 11700 11701 memset(&c, 0, sizeof(c)); 11702 c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_VI_MAC_CMD) | 11703 F_FW_CMD_REQUEST | 11704 F_FW_CMD_WRITE | 11705 V_FW_CMD_EXEC(0) | 11706 V_FW_VI_MAC_CMD_VIID(viid)); 11707 c.freemacs_to_len16 = 11708 cpu_to_be32(V_FW_VI_MAC_CMD_FREEMACS(0) | 11709 V_FW_CMD_LEN16(len16)); 11710 11711 for (i = 0, p = c.u.exact; i < (int)fw_naddr; i++, p++) { 11712 p->valid_to_idx = cpu_to_be16( 11713 F_FW_VI_MAC_CMD_VALID | 11714 V_FW_VI_MAC_CMD_IDX(FW_VI_MAC_MAC_BASED_FREE)); 11715 memcpy(p->macaddr, addr[offset+i], sizeof(p->macaddr)); 11716 } 11717 11718 ret = t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), &c, sleep_ok); 11719 if (ret) 11720 break; 11721 11722 for (i = 0, p = c.u.exact; i < fw_naddr; i++, p++) { 11723 u16 index = G_FW_VI_MAC_CMD_IDX( 11724 be16_to_cpu(p->valid_to_idx)); 11725 11726 if (index < max_naddr) 11727 nfilters++; 11728 } 11729 11730 offset += fw_naddr; 11731 rem -= fw_naddr; 11732 } 11733 11734 if (ret == 0) 11735 ret = nfilters; 11736 return ret; 11737 } 11738 11739 /** 11740 * t4_change_mac - modifies the exact-match filter for a MAC address 11741 * @adap: the adapter 11742 * @mbox: mailbox to use for the FW command 11743 * @viid: the VI id 11744 * @idx: index of existing filter for old value of MAC address, or -1 11745 * @addr: the new MAC address value 11746 * @persist: whether a new MAC allocation should be persistent 11747 * @smt_idx: add MAC to SMT and return its index, or NULL 11748 * 11749 * Modifies an exact-match filter and sets it to the new MAC address if 11750 * @idx >= 0, or adds the MAC address to a new filter if @idx < 0. In the 11751 * latter case the address is added persistently if @persist is %true. 11752 * 11753 * Note that in general it is not possible to modify the value of a given 11754 * filter so the generic way to modify an address filter is to free the one 11755 * being used by the old address value and allocate a new filter for the 11756 * new address value. 11757 * 11758 * Returns a negative error number or the index of the filter with the new 11759 * MAC value. Note that this index may differ from @idx. 11760 */ 11761 int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid, 11762 int idx, const u8 *addr, bool persist, uint16_t *smt_idx) 11763 { 11764 int ret, mode; 11765 struct fw_vi_mac_cmd c; 11766 struct fw_vi_mac_exact *p = c.u.exact; 11767 unsigned int max_mac_addr = adap->chip_params->mps_tcam_size; 11768 11769 if (idx < 0) /* new allocation */ 11770 idx = persist ? FW_VI_MAC_ADD_PERSIST_MAC : FW_VI_MAC_ADD_MAC; 11771 mode = smt_idx ? FW_VI_MAC_SMT_AND_MPSTCAM : FW_VI_MAC_MPS_TCAM_ENTRY; 11772 11773 memset(&c, 0, sizeof(c)); 11774 c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_VI_MAC_CMD) | 11775 F_FW_CMD_REQUEST | F_FW_CMD_WRITE | 11776 V_FW_VI_MAC_CMD_VIID(viid)); 11777 c.freemacs_to_len16 = cpu_to_be32(V_FW_CMD_LEN16(1)); 11778 p->valid_to_idx = cpu_to_be16(F_FW_VI_MAC_CMD_VALID | 11779 V_FW_VI_MAC_CMD_SMAC_RESULT(mode) | 11780 V_FW_VI_MAC_CMD_IDX(idx)); 11781 memcpy(p->macaddr, addr, sizeof(p->macaddr)); 11782 11783 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); 11784 if (ret == 0) { 11785 ret = G_FW_VI_MAC_CMD_IDX(be16_to_cpu(p->valid_to_idx)); 11786 if (ret >= max_mac_addr) 11787 ret = -ENOMEM; 11788 if (smt_idx) { 11789 if (adap->params.viid_smt_extn_support) 11790 *smt_idx = G_FW_VI_MAC_CMD_SMTID(be32_to_cpu(c.op_to_viid)); 11791 else { 11792 if (chip_id(adap) <= CHELSIO_T5) 11793 *smt_idx = (viid & M_FW_VIID_VIN) << 1; 11794 else 11795 *smt_idx = viid & M_FW_VIID_VIN; 11796 } 11797 } 11798 } 11799 return ret; 11800 } 11801 11802 /** 11803 * t4_set_addr_hash - program the MAC inexact-match hash filter 11804 * @adap: the adapter 11805 * @mbox: mailbox to use for the FW command 11806 * @viid: the VI id 11807 * @ucast: whether the hash filter should also match unicast addresses 11808 * @vec: the value to be written to the hash filter 11809 * @sleep_ok: call is allowed to sleep 11810 * 11811 * Sets the 64-bit inexact-match hash filter for a virtual interface. 11812 */ 11813 int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid, 11814 bool ucast, u64 vec, bool sleep_ok) 11815 { 11816 struct fw_vi_mac_cmd c; 11817 u32 val; 11818 11819 memset(&c, 0, sizeof(c)); 11820 c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_VI_MAC_CMD) | 11821 F_FW_CMD_REQUEST | F_FW_CMD_WRITE | 11822 V_FW_VI_ENABLE_CMD_VIID(viid)); 11823 val = V_FW_VI_MAC_CMD_ENTRY_TYPE(FW_VI_MAC_TYPE_HASHVEC) | 11824 V_FW_VI_MAC_CMD_HASHUNIEN(ucast) | V_FW_CMD_LEN16(1); 11825 c.freemacs_to_len16 = cpu_to_be32(val); 11826 c.u.hash.hashvec = cpu_to_be64(vec); 11827 return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok); 11828 } 11829 11830 /** 11831 * t4_enable_vi_params - enable/disable a virtual interface 11832 * @adap: the adapter 11833 * @mbox: mailbox to use for the FW command 11834 * @viid: the VI id 11835 * @rx_en: 1=enable Rx, 0=disable Rx 11836 * @tx_en: 1=enable Tx, 0=disable Tx 11837 * @dcb_en: 1=enable delivery of Data Center Bridging messages. 11838 * 11839 * Enables/disables a virtual interface. Note that setting DCB Enable 11840 * only makes sense when enabling a Virtual Interface ... 11841 */ 11842 int t4_enable_vi_params(struct adapter *adap, unsigned int mbox, 11843 unsigned int viid, bool rx_en, bool tx_en, bool dcb_en) 11844 { 11845 struct fw_vi_enable_cmd c; 11846 11847 memset(&c, 0, sizeof(c)); 11848 c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_VI_ENABLE_CMD) | 11849 F_FW_CMD_REQUEST | F_FW_CMD_EXEC | 11850 V_FW_VI_ENABLE_CMD_VIID(viid)); 11851 c.ien_to_len16 = cpu_to_be32(V_FW_VI_ENABLE_CMD_IEN(rx_en) | 11852 V_FW_VI_ENABLE_CMD_EEN(tx_en) | 11853 V_FW_VI_ENABLE_CMD_DCB_INFO(dcb_en) | 11854 FW_LEN16(c)); 11855 return t4_wr_mbox_ns(adap, mbox, &c, sizeof(c), NULL); 11856 } 11857 11858 /** 11859 * t4_enable_vi - enable/disable a virtual interface 11860 * @adap: the adapter 11861 * @mbox: mailbox to use for the FW command 11862 * @viid: the VI id 11863 * @rx_en: 1=enable Rx, 0=disable Rx 11864 * @tx_en: 1=enable Tx, 0=disable Tx 11865 * 11866 * Enables/disables a virtual interface. Note that setting DCB Enable 11867 * only makes sense when enabling a Virtual Interface ... 11868 */ 11869 int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid, 11870 bool rx_en, bool tx_en) 11871 { 11872 return t4_enable_vi_params(adap, mbox, viid, rx_en, tx_en, 0); 11873 } 11874 11875 /** 11876 * t4_identify_port - identify a VI's port by blinking its LED 11877 * @adap: the adapter 11878 * @mbox: mailbox to use for the FW command 11879 * @viid: the VI id 11880 * @nblinks: how many times to blink LED at 2.5 Hz 11881 * 11882 * Identifies a VI's port by blinking its LED. 11883 */ 11884 int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, 11885 unsigned int nblinks) 11886 { 11887 struct fw_vi_enable_cmd c; 11888 11889 memset(&c, 0, sizeof(c)); 11890 c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_VI_ENABLE_CMD) | 11891 F_FW_CMD_REQUEST | F_FW_CMD_EXEC | 11892 V_FW_VI_ENABLE_CMD_VIID(viid)); 11893 c.ien_to_len16 = cpu_to_be32(F_FW_VI_ENABLE_CMD_LED | FW_LEN16(c)); 11894 c.blinkdur = cpu_to_be16(nblinks); 11895 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 11896 } 11897 11898 /** 11899 * t4_iq_stop - stop an ingress queue and its FLs 11900 * @adap: the adapter 11901 * @mbox: mailbox to use for the FW command 11902 * @pf: the PF owning the queues 11903 * @vf: the VF owning the queues 11904 * @iqtype: the ingress queue type (FW_IQ_TYPE_FL_INT_CAP, etc.) 11905 * @iqid: ingress queue id 11906 * @fl0id: FL0 queue id or 0xffff if no attached FL0 11907 * @fl1id: FL1 queue id or 0xffff if no attached FL1 11908 * 11909 * Stops an ingress queue and its associated FLs, if any. This causes 11910 * any current or future data/messages destined for these queues to be 11911 * tossed. 11912 */ 11913 int t4_iq_stop(struct adapter *adap, unsigned int mbox, unsigned int pf, 11914 unsigned int vf, unsigned int iqtype, unsigned int iqid, 11915 unsigned int fl0id, unsigned int fl1id) 11916 { 11917 struct fw_iq_cmd c; 11918 11919 memset(&c, 0, sizeof(c)); 11920 c.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_IQ_CMD) | F_FW_CMD_REQUEST | 11921 F_FW_CMD_EXEC | V_FW_IQ_CMD_PFN(pf) | 11922 V_FW_IQ_CMD_VFN(vf)); 11923 c.alloc_to_len16 = cpu_to_be32(F_FW_IQ_CMD_IQSTOP | FW_LEN16(c)); 11924 c.type_to_iqandstindex = cpu_to_be32(V_FW_IQ_CMD_TYPE(iqtype)); 11925 c.iqid = cpu_to_be16(iqid); 11926 c.fl0id = cpu_to_be16(fl0id); 11927 c.fl1id = cpu_to_be16(fl1id); 11928 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 11929 } 11930 11931 /** 11932 * t4_iq_free - free an ingress queue and its FLs 11933 * @adap: the adapter 11934 * @mbox: mailbox to use for the FW command 11935 * @pf: the PF owning the queues 11936 * @vf: the VF owning the queues 11937 * @iqtype: the ingress queue type (FW_IQ_TYPE_FL_INT_CAP, etc.) 11938 * @iqid: ingress queue id 11939 * @fl0id: FL0 queue id or 0xffff if no attached FL0 11940 * @fl1id: FL1 queue id or 0xffff if no attached FL1 11941 * 11942 * Frees an ingress queue and its associated FLs, if any. 11943 */ 11944 int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, 11945 unsigned int vf, unsigned int iqtype, unsigned int iqid, 11946 unsigned int fl0id, unsigned int fl1id) 11947 { 11948 struct fw_iq_cmd c; 11949 11950 memset(&c, 0, sizeof(c)); 11951 c.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_IQ_CMD) | F_FW_CMD_REQUEST | 11952 F_FW_CMD_EXEC | V_FW_IQ_CMD_PFN(pf) | 11953 V_FW_IQ_CMD_VFN(vf)); 11954 c.alloc_to_len16 = cpu_to_be32(F_FW_IQ_CMD_FREE | FW_LEN16(c)); 11955 c.type_to_iqandstindex = cpu_to_be32(V_FW_IQ_CMD_TYPE(iqtype)); 11956 c.iqid = cpu_to_be16(iqid); 11957 c.fl0id = cpu_to_be16(fl0id); 11958 c.fl1id = cpu_to_be16(fl1id); 11959 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 11960 } 11961 11962 /** 11963 * t4_eth_eq_stop - stop an Ethernet egress queue 11964 * @adap: the adapter 11965 * @mbox: mailbox to use for the FW command 11966 * @pf: the PF owning the queues 11967 * @vf: the VF owning the queues 11968 * @eqid: egress queue id 11969 * 11970 * Stops an Ethernet egress queue. The queue can be reinitialized or 11971 * freed but is not otherwise functional after this call. 11972 */ 11973 int t4_eth_eq_stop(struct adapter *adap, unsigned int mbox, unsigned int pf, 11974 unsigned int vf, unsigned int eqid) 11975 { 11976 struct fw_eq_eth_cmd c; 11977 11978 memset(&c, 0, sizeof(c)); 11979 c.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_EQ_ETH_CMD) | 11980 F_FW_CMD_REQUEST | F_FW_CMD_EXEC | 11981 V_FW_EQ_ETH_CMD_PFN(pf) | 11982 V_FW_EQ_ETH_CMD_VFN(vf)); 11983 c.alloc_to_len16 = cpu_to_be32(F_FW_EQ_ETH_CMD_EQSTOP | FW_LEN16(c)); 11984 c.eqid_pkd = cpu_to_be32(V_FW_EQ_ETH_CMD_EQID(eqid)); 11985 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 11986 } 11987 11988 /** 11989 * t4_eth_eq_free - free an Ethernet egress queue 11990 * @adap: the adapter 11991 * @mbox: mailbox to use for the FW command 11992 * @pf: the PF owning the queue 11993 * @vf: the VF owning the queue 11994 * @eqid: egress queue id 11995 * 11996 * Frees an Ethernet egress queue. 11997 */ 11998 int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, 11999 unsigned int vf, unsigned int eqid) 12000 { 12001 struct fw_eq_eth_cmd c; 12002 12003 memset(&c, 0, sizeof(c)); 12004 c.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_EQ_ETH_CMD) | 12005 F_FW_CMD_REQUEST | F_FW_CMD_EXEC | 12006 V_FW_EQ_ETH_CMD_PFN(pf) | 12007 V_FW_EQ_ETH_CMD_VFN(vf)); 12008 c.alloc_to_len16 = cpu_to_be32(F_FW_EQ_ETH_CMD_FREE | FW_LEN16(c)); 12009 c.eqid_pkd = cpu_to_be32(V_FW_EQ_ETH_CMD_EQID(eqid)); 12010 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 12011 } 12012 12013 /** 12014 * t4_ctrl_eq_free - free a control egress queue 12015 * @adap: the adapter 12016 * @mbox: mailbox to use for the FW command 12017 * @pf: the PF owning the queue 12018 * @vf: the VF owning the queue 12019 * @eqid: egress queue id 12020 * 12021 * Frees a control egress queue. 12022 */ 12023 int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, 12024 unsigned int vf, unsigned int eqid) 12025 { 12026 struct fw_eq_ctrl_cmd c; 12027 12028 memset(&c, 0, sizeof(c)); 12029 c.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_EQ_CTRL_CMD) | 12030 F_FW_CMD_REQUEST | F_FW_CMD_EXEC | 12031 V_FW_EQ_CTRL_CMD_PFN(pf) | 12032 V_FW_EQ_CTRL_CMD_VFN(vf)); 12033 c.alloc_to_len16 = cpu_to_be32(F_FW_EQ_CTRL_CMD_FREE | FW_LEN16(c)); 12034 c.cmpliqid_eqid = cpu_to_be32(V_FW_EQ_CTRL_CMD_EQID(eqid)); 12035 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 12036 } 12037 12038 /** 12039 * t4_ofld_eq_free - free an offload egress queue 12040 * @adap: the adapter 12041 * @mbox: mailbox to use for the FW command 12042 * @pf: the PF owning the queue 12043 * @vf: the VF owning the queue 12044 * @eqid: egress queue id 12045 * 12046 * Frees a control egress queue. 12047 */ 12048 int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, 12049 unsigned int vf, unsigned int eqid) 12050 { 12051 struct fw_eq_ofld_cmd c; 12052 12053 memset(&c, 0, sizeof(c)); 12054 c.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_EQ_OFLD_CMD) | 12055 F_FW_CMD_REQUEST | F_FW_CMD_EXEC | 12056 V_FW_EQ_OFLD_CMD_PFN(pf) | 12057 V_FW_EQ_OFLD_CMD_VFN(vf)); 12058 c.alloc_to_len16 = cpu_to_be32(F_FW_EQ_OFLD_CMD_FREE | FW_LEN16(c)); 12059 c.eqid_pkd = cpu_to_be32(V_FW_EQ_OFLD_CMD_EQID(eqid)); 12060 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 12061 } 12062 12063 /** 12064 * t4_link_down_rc_str - return a string for a Link Down Reason Code 12065 * @link_down_rc: Link Down Reason Code 12066 * 12067 * Returns a string representation of the Link Down Reason Code. 12068 */ 12069 const char *t4_link_down_rc_str(unsigned char link_down_rc) 12070 { 12071 static const char *reason[] = { 12072 "Link Down", 12073 "Remote Fault", 12074 "Auto-negotiation Failure", 12075 "Reserved3", 12076 "Insufficient Airflow", 12077 "Unable To Determine Reason", 12078 "No RX Signal Detected", 12079 "Reserved7", 12080 }; 12081 12082 if (link_down_rc >= ARRAY_SIZE(reason)) 12083 return "Bad Reason Code"; 12084 12085 return reason[link_down_rc]; 12086 } 12087 12088 /* 12089 * Return the highest speed set in the port capabilities, in Mb/s. 12090 */ 12091 unsigned int fwcap_to_speed(uint32_t caps) 12092 { 12093 #define TEST_SPEED_RETURN(__caps_speed, __speed) \ 12094 do { \ 12095 if (caps & FW_PORT_CAP32_SPEED_##__caps_speed) \ 12096 return __speed; \ 12097 } while (0) 12098 12099 TEST_SPEED_RETURN(400G, 400000); 12100 TEST_SPEED_RETURN(200G, 200000); 12101 TEST_SPEED_RETURN(100G, 100000); 12102 TEST_SPEED_RETURN(50G, 50000); 12103 TEST_SPEED_RETURN(40G, 40000); 12104 TEST_SPEED_RETURN(25G, 25000); 12105 TEST_SPEED_RETURN(10G, 10000); 12106 TEST_SPEED_RETURN(1G, 1000); 12107 TEST_SPEED_RETURN(100M, 100); 12108 12109 #undef TEST_SPEED_RETURN 12110 12111 return 0; 12112 } 12113 12114 /* 12115 * Return the port capabilities bit for the given speed, which is in Mb/s. 12116 */ 12117 uint32_t speed_to_fwcap(unsigned int speed) 12118 { 12119 #define TEST_SPEED_RETURN(__caps_speed, __speed) \ 12120 do { \ 12121 if (speed == __speed) \ 12122 return FW_PORT_CAP32_SPEED_##__caps_speed; \ 12123 } while (0) 12124 12125 TEST_SPEED_RETURN(400G, 400000); 12126 TEST_SPEED_RETURN(200G, 200000); 12127 TEST_SPEED_RETURN(100G, 100000); 12128 TEST_SPEED_RETURN(50G, 50000); 12129 TEST_SPEED_RETURN(40G, 40000); 12130 TEST_SPEED_RETURN(25G, 25000); 12131 TEST_SPEED_RETURN(10G, 10000); 12132 TEST_SPEED_RETURN(1G, 1000); 12133 TEST_SPEED_RETURN(100M, 100); 12134 12135 #undef TEST_SPEED_RETURN 12136 12137 return 0; 12138 } 12139 12140 /* 12141 * Return the port capabilities bit for the highest speed in the capabilities. 12142 */ 12143 uint32_t fwcap_top_speed(uint32_t caps) 12144 { 12145 #define TEST_SPEED_RETURN(__caps_speed) \ 12146 do { \ 12147 if (caps & FW_PORT_CAP32_SPEED_##__caps_speed) \ 12148 return FW_PORT_CAP32_SPEED_##__caps_speed; \ 12149 } while (0) 12150 12151 TEST_SPEED_RETURN(400G); 12152 TEST_SPEED_RETURN(200G); 12153 TEST_SPEED_RETURN(100G); 12154 TEST_SPEED_RETURN(50G); 12155 TEST_SPEED_RETURN(40G); 12156 TEST_SPEED_RETURN(25G); 12157 TEST_SPEED_RETURN(10G); 12158 TEST_SPEED_RETURN(1G); 12159 TEST_SPEED_RETURN(100M); 12160 12161 #undef TEST_SPEED_RETURN 12162 12163 return 0; 12164 } 12165 12166 /** 12167 * lstatus_to_fwcap - translate old lstatus to 32-bit Port Capabilities 12168 * @lstatus: old FW_PORT_ACTION_GET_PORT_INFO lstatus value 12169 * 12170 * Translates old FW_PORT_ACTION_GET_PORT_INFO lstatus field into new 12171 * 32-bit Port Capabilities value. 12172 */ 12173 static uint32_t lstatus_to_fwcap(u32 lstatus) 12174 { 12175 uint32_t linkattr = 0; 12176 12177 /* 12178 * Unfortunately the format of the Link Status in the old 12179 * 16-bit Port Information message isn't the same as the 12180 * 16-bit Port Capabilities bitfield used everywhere else ... 12181 */ 12182 if (lstatus & F_FW_PORT_CMD_RXPAUSE) 12183 linkattr |= FW_PORT_CAP32_FC_RX; 12184 if (lstatus & F_FW_PORT_CMD_TXPAUSE) 12185 linkattr |= FW_PORT_CAP32_FC_TX; 12186 if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M)) 12187 linkattr |= FW_PORT_CAP32_SPEED_100M; 12188 if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G)) 12189 linkattr |= FW_PORT_CAP32_SPEED_1G; 12190 if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G)) 12191 linkattr |= FW_PORT_CAP32_SPEED_10G; 12192 if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_25G)) 12193 linkattr |= FW_PORT_CAP32_SPEED_25G; 12194 if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G)) 12195 linkattr |= FW_PORT_CAP32_SPEED_40G; 12196 if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100G)) 12197 linkattr |= FW_PORT_CAP32_SPEED_100G; 12198 12199 return linkattr; 12200 } 12201 12202 /* 12203 * Updates all fields owned by the common code in port_info and link_config 12204 * based on information provided by the firmware. Does not touch any 12205 * requested_* field. 12206 */ 12207 static void handle_port_info(struct port_info *pi, const struct fw_port_cmd *p, 12208 enum fw_port_action action, bool *mod_changed, bool *link_changed) 12209 { 12210 struct link_config old_lc, *lc = &pi->link_cfg; 12211 unsigned char fc; 12212 u32 stat, linkattr; 12213 int old_ptype, old_mtype; 12214 12215 old_ptype = pi->port_type; 12216 old_mtype = pi->mod_type; 12217 old_lc = *lc; 12218 if (action == FW_PORT_ACTION_GET_PORT_INFO) { 12219 stat = be32_to_cpu(p->u.info.lstatus_to_modtype); 12220 12221 pi->port_type = G_FW_PORT_CMD_PTYPE(stat); 12222 pi->mod_type = G_FW_PORT_CMD_MODTYPE(stat); 12223 pi->mdio_addr = stat & F_FW_PORT_CMD_MDIOCAP ? 12224 G_FW_PORT_CMD_MDIOADDR(stat) : -1; 12225 12226 lc->pcaps = fwcaps16_to_caps32(be16_to_cpu(p->u.info.pcap)); 12227 lc->acaps = fwcaps16_to_caps32(be16_to_cpu(p->u.info.acap)); 12228 lc->lpacaps = fwcaps16_to_caps32(be16_to_cpu(p->u.info.lpacap)); 12229 lc->link_ok = (stat & F_FW_PORT_CMD_LSTATUS) != 0; 12230 lc->link_down_rc = G_FW_PORT_CMD_LINKDNRC(stat); 12231 12232 linkattr = lstatus_to_fwcap(stat); 12233 } else if (action == FW_PORT_ACTION_GET_PORT_INFO32) { 12234 stat = be32_to_cpu(p->u.info32.lstatus32_to_cbllen32); 12235 12236 pi->port_type = G_FW_PORT_CMD_PORTTYPE32(stat); 12237 pi->mod_type = G_FW_PORT_CMD_MODTYPE32(stat); 12238 pi->mdio_addr = stat & F_FW_PORT_CMD_MDIOCAP32 ? 12239 G_FW_PORT_CMD_MDIOADDR32(stat) : -1; 12240 12241 lc->pcaps = be32_to_cpu(p->u.info32.pcaps32); 12242 lc->acaps = be32_to_cpu(p->u.info32.acaps32); 12243 lc->lpacaps = be32_to_cpu(p->u.info32.lpacaps32); 12244 lc->link_ok = (stat & F_FW_PORT_CMD_LSTATUS32) != 0; 12245 lc->link_down_rc = G_FW_PORT_CMD_LINKDNRC32(stat); 12246 12247 linkattr = be32_to_cpu(p->u.info32.linkattr32); 12248 } else { 12249 CH_ERR(pi->adapter, "bad port_info action 0x%x\n", action); 12250 return; 12251 } 12252 12253 lc->speed = fwcap_to_speed(linkattr); 12254 lc->fec = fwcap_to_fec(linkattr, true); 12255 12256 fc = 0; 12257 if (linkattr & FW_PORT_CAP32_FC_RX) 12258 fc |= PAUSE_RX; 12259 if (linkattr & FW_PORT_CAP32_FC_TX) 12260 fc |= PAUSE_TX; 12261 lc->fc = fc; 12262 12263 if (mod_changed != NULL) 12264 *mod_changed = false; 12265 if (link_changed != NULL) 12266 *link_changed = false; 12267 if (old_ptype != pi->port_type || old_mtype != pi->mod_type || 12268 old_lc.pcaps != lc->pcaps) { 12269 if (pi->mod_type != FW_PORT_MOD_TYPE_NONE) 12270 lc->fec_hint = fwcap_to_fec(lc->acaps, true); 12271 if (mod_changed != NULL) 12272 *mod_changed = true; 12273 } 12274 if (old_lc.link_ok != lc->link_ok || old_lc.speed != lc->speed || 12275 old_lc.fec != lc->fec || old_lc.fc != lc->fc) { 12276 if (link_changed != NULL) 12277 *link_changed = true; 12278 } 12279 } 12280 12281 /** 12282 * t4_update_port_info - retrieve and update port information if changed 12283 * @pi: the port_info 12284 * 12285 * We issue a Get Port Information Command to the Firmware and, if 12286 * successful, we check to see if anything is different from what we 12287 * last recorded and update things accordingly. 12288 */ 12289 int t4_update_port_info(struct port_info *pi) 12290 { 12291 struct adapter *sc = pi->adapter; 12292 struct fw_port_cmd cmd; 12293 enum fw_port_action action; 12294 int ret; 12295 12296 memset(&cmd, 0, sizeof(cmd)); 12297 cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | 12298 F_FW_CMD_REQUEST | F_FW_CMD_READ | 12299 V_FW_PORT_CMD_PORTID(pi->hw_port)); 12300 action = sc->params.port_caps32 ? FW_PORT_ACTION_GET_PORT_INFO32 : 12301 FW_PORT_ACTION_GET_PORT_INFO; 12302 cmd.action_to_len16 = cpu_to_be32(V_FW_PORT_CMD_ACTION(action) | 12303 FW_LEN16(cmd)); 12304 ret = t4_wr_mbox_ns(sc, sc->mbox, &cmd, sizeof(cmd), &cmd); 12305 if (ret) 12306 return ret; 12307 12308 handle_port_info(pi, &cmd, action, NULL, NULL); 12309 return 0; 12310 } 12311 12312 /** 12313 * t4_handle_fw_rpl - process a FW reply message 12314 * @adap: the adapter 12315 * @rpl: start of the FW message 12316 * 12317 * Processes a FW message, such as link state change messages. 12318 */ 12319 int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) 12320 { 12321 u8 opcode = *(const u8 *)rpl; 12322 const struct fw_port_cmd *p = (const void *)rpl; 12323 enum fw_port_action action = 12324 G_FW_PORT_CMD_ACTION(be32_to_cpu(p->action_to_len16)); 12325 bool mod_changed, link_changed; 12326 12327 if (opcode == FW_PORT_CMD && 12328 (action == FW_PORT_ACTION_GET_PORT_INFO || 12329 action == FW_PORT_ACTION_GET_PORT_INFO32)) { 12330 /* link/module state change message */ 12331 int hw_port = G_FW_PORT_CMD_PORTID(be32_to_cpu(p->op_to_portid)); 12332 int port_id = adap->port_map[hw_port]; 12333 struct port_info *pi; 12334 12335 MPASS(port_id >= 0 && port_id < adap->params.nports); 12336 pi = adap->port[port_id]; 12337 PORT_LOCK(pi); 12338 handle_port_info(pi, p, action, &mod_changed, &link_changed); 12339 PORT_UNLOCK(pi); 12340 if (mod_changed) 12341 t4_os_portmod_changed(pi); 12342 if (link_changed) { 12343 PORT_LOCK(pi); 12344 t4_os_link_changed(pi); 12345 PORT_UNLOCK(pi); 12346 } 12347 } else { 12348 CH_WARN_RATELIMIT(adap, "Unknown firmware reply %d\n", opcode); 12349 return -EINVAL; 12350 } 12351 return 0; 12352 } 12353 12354 /** 12355 * get_pci_mode - determine a card's PCI mode 12356 * @adapter: the adapter 12357 * @p: where to store the PCI settings 12358 * 12359 * Determines a card's PCI mode and associated parameters, such as speed 12360 * and width. 12361 */ 12362 static void get_pci_mode(struct adapter *adapter, 12363 struct pci_params *p) 12364 { 12365 u16 val; 12366 u32 pcie_cap; 12367 12368 pcie_cap = t4_os_find_pci_capability(adapter, PCI_CAP_ID_EXP); 12369 if (pcie_cap) { 12370 t4_os_pci_read_cfg2(adapter, pcie_cap + PCI_EXP_LNKSTA, &val); 12371 p->speed = val & PCI_EXP_LNKSTA_CLS; 12372 p->width = (val & PCI_EXP_LNKSTA_NLW) >> 4; 12373 } 12374 } 12375 12376 struct flash_desc { 12377 u32 vendor_and_model_id; 12378 u32 size_mb; 12379 }; 12380 12381 int t4_get_flash_params(struct adapter *adapter) 12382 { 12383 /* 12384 * Table for non-standard supported Flash parts. Note, all Flash 12385 * parts must have 64KB sectors. 12386 */ 12387 static struct flash_desc supported_flash[] = { 12388 { 0x00150201, 4 << 20 }, /* Spansion 4MB S25FL032P */ 12389 }; 12390 12391 int ret; 12392 u32 flashid = 0; 12393 unsigned int part, manufacturer; 12394 unsigned int density, size = 0; 12395 12396 12397 /* 12398 * Issue a Read ID Command to the Flash part. We decode supported 12399 * Flash parts and their sizes from this. There's a newer Query 12400 * Command which can retrieve detailed geometry information but many 12401 * Flash parts don't support it. 12402 */ 12403 ret = sf1_write(adapter, 1, 1, 0, SF_RD_ID); 12404 if (!ret) 12405 ret = sf1_read(adapter, 3, 0, 1, &flashid); 12406 t4_write_reg(adapter, A_SF_OP, 0); /* unlock SF */ 12407 if (ret < 0) 12408 return ret; 12409 12410 /* 12411 * Check to see if it's one of our non-standard supported Flash parts. 12412 */ 12413 for (part = 0; part < ARRAY_SIZE(supported_flash); part++) 12414 if (supported_flash[part].vendor_and_model_id == flashid) { 12415 adapter->params.sf_size = 12416 supported_flash[part].size_mb; 12417 adapter->params.sf_nsec = 12418 adapter->params.sf_size / SF_SEC_SIZE; 12419 goto found; 12420 } 12421 12422 /* 12423 * Decode Flash part size. The code below looks repetative with 12424 * common encodings, but that's not guaranteed in the JEDEC 12425 * specification for the Read JADEC ID command. The only thing that 12426 * we're guaranteed by the JADEC specification is where the 12427 * Manufacturer ID is in the returned result. After that each 12428 * Manufacturer ~could~ encode things completely differently. 12429 * Note, all Flash parts must have 64KB sectors. 12430 */ 12431 manufacturer = flashid & 0xff; 12432 switch (manufacturer) { 12433 case 0x20: /* Micron/Numonix */ 12434 /* 12435 * This Density -> Size decoding table is taken from Micron 12436 * Data Sheets. 12437 */ 12438 density = (flashid >> 16) & 0xff; 12439 switch (density) { 12440 case 0x14: size = 1 << 20; break; /* 1MB */ 12441 case 0x15: size = 1 << 21; break; /* 2MB */ 12442 case 0x16: size = 1 << 22; break; /* 4MB */ 12443 case 0x17: size = 1 << 23; break; /* 8MB */ 12444 case 0x18: size = 1 << 24; break; /* 16MB */ 12445 case 0x19: size = 1 << 25; break; /* 32MB */ 12446 case 0x20: size = 1 << 26; break; /* 64MB */ 12447 case 0x21: size = 1 << 27; break; /* 128MB */ 12448 case 0x22: size = 1 << 28; break; /* 256MB */ 12449 } 12450 break; 12451 12452 case 0x9d: /* ISSI -- Integrated Silicon Solution, Inc. */ 12453 /* 12454 * This Density -> Size decoding table is taken from ISSI 12455 * Data Sheets. 12456 */ 12457 density = (flashid >> 16) & 0xff; 12458 switch (density) { 12459 case 0x16: size = 1 << 25; break; /* 32MB */ 12460 case 0x17: size = 1 << 26; break; /* 64MB */ 12461 } 12462 break; 12463 12464 case 0xc2: /* Macronix */ 12465 /* 12466 * This Density -> Size decoding table is taken from Macronix 12467 * Data Sheets. 12468 */ 12469 density = (flashid >> 16) & 0xff; 12470 switch (density) { 12471 case 0x17: size = 1 << 23; break; /* 8MB */ 12472 case 0x18: size = 1 << 24; break; /* 16MB */ 12473 } 12474 break; 12475 12476 case 0xef: /* Winbond */ 12477 /* 12478 * This Density -> Size decoding table is taken from Winbond 12479 * Data Sheets. 12480 */ 12481 density = (flashid >> 16) & 0xff; 12482 switch (density) { 12483 case 0x17: size = 1 << 23; break; /* 8MB */ 12484 case 0x18: size = 1 << 24; break; /* 16MB */ 12485 } 12486 break; 12487 } 12488 12489 /* If we didn't recognize the FLASH part, that's no real issue: the 12490 * Hardware/Software contract says that Hardware will _*ALWAYS*_ use a 12491 * FLASH part which has 64KB sectors and is at least 4MB or 16MB in 12492 * size, depending on the board. 12493 */ 12494 if (size == 0) { 12495 size = chip_id(adapter) >= CHELSIO_T7 ? 16 : 4; 12496 CH_WARN(adapter, "Unknown Flash Part %#x, assuming %uMB\n", 12497 flashid, size); 12498 size <<= 20; 12499 } 12500 12501 /* 12502 * Store decoded Flash size and fall through into vetting code. 12503 */ 12504 adapter->params.sf_size = size; 12505 adapter->params.sf_nsec = size / SF_SEC_SIZE; 12506 12507 found: 12508 /* 12509 * We should ~probably~ reject adapters with FLASHes which are too 12510 * small but we have some legacy FPGAs with small FLASHes that we'd 12511 * still like to use. So instead we emit a scary message ... 12512 */ 12513 if (adapter->params.sf_size < FLASH_MIN_SIZE) 12514 CH_WARN(adapter, "WARNING: Flash Part ID %#x, size %#x < %#x\n", 12515 flashid, adapter->params.sf_size, FLASH_MIN_SIZE); 12516 12517 return 0; 12518 } 12519 12520 static void set_pcie_completion_timeout(struct adapter *adapter, 12521 u8 range) 12522 { 12523 u16 val; 12524 u32 pcie_cap; 12525 12526 pcie_cap = t4_os_find_pci_capability(adapter, PCI_CAP_ID_EXP); 12527 if (pcie_cap) { 12528 t4_os_pci_read_cfg2(adapter, pcie_cap + PCI_EXP_DEVCTL2, &val); 12529 val &= 0xfff0; 12530 val |= range ; 12531 t4_os_pci_write_cfg2(adapter, pcie_cap + PCI_EXP_DEVCTL2, val); 12532 } 12533 } 12534 12535 const struct chip_params *t4_get_chip_params(int chipid) 12536 { 12537 static const struct chip_params chip_params[] = { 12538 { 12539 /* T4 */ 12540 .nchan = NCHAN, 12541 .pm_stats_cnt = PM_NSTATS, 12542 .cng_ch_bits_log = 2, 12543 .nsched_cls = 15, 12544 .cim_num_ibq = CIM_NUM_IBQ, 12545 .cim_num_obq = CIM_NUM_OBQ, 12546 .filter_opt_len = FILTER_OPT_LEN, 12547 .filter_num_opt = S_FT_LAST + 1, 12548 .mps_rplc_size = 128, 12549 .vfcount = 128, 12550 .sge_fl_db = F_DBPRIO, 12551 .sge_ctxt_size = SGE_CTXT_SIZE, 12552 .mps_tcam_size = NUM_MPS_CLS_SRAM_L_INSTANCES, 12553 .rss_nentries = RSS_NENTRIES, 12554 .cim_la_size = CIMLA_SIZE, 12555 }, 12556 { 12557 /* T5 */ 12558 .nchan = NCHAN, 12559 .pm_stats_cnt = PM_NSTATS, 12560 .cng_ch_bits_log = 2, 12561 .nsched_cls = 16, 12562 .cim_num_ibq = CIM_NUM_IBQ, 12563 .cim_num_obq = CIM_NUM_OBQ_T5, 12564 .filter_opt_len = T5_FILTER_OPT_LEN, 12565 .filter_num_opt = S_FT_LAST + 1, 12566 .mps_rplc_size = 128, 12567 .vfcount = 128, 12568 .sge_fl_db = F_DBPRIO | F_DBTYPE, 12569 .sge_ctxt_size = SGE_CTXT_SIZE, 12570 .mps_tcam_size = NUM_MPS_T5_CLS_SRAM_L_INSTANCES, 12571 .rss_nentries = RSS_NENTRIES, 12572 .cim_la_size = CIMLA_SIZE, 12573 }, 12574 { 12575 /* T6 */ 12576 .nchan = T6_NCHAN, 12577 .pm_stats_cnt = T6_PM_NSTATS, 12578 .cng_ch_bits_log = 3, 12579 .nsched_cls = 16, 12580 .cim_num_ibq = CIM_NUM_IBQ, 12581 .cim_num_obq = CIM_NUM_OBQ_T5, 12582 .filter_opt_len = T5_FILTER_OPT_LEN, 12583 .filter_num_opt = S_FT_LAST + 1, 12584 .mps_rplc_size = 256, 12585 .vfcount = 256, 12586 .sge_fl_db = 0, 12587 .sge_ctxt_size = SGE_CTXT_SIZE, 12588 .mps_tcam_size = NUM_MPS_T5_CLS_SRAM_L_INSTANCES, 12589 .rss_nentries = T6_RSS_NENTRIES, 12590 .cim_la_size = CIMLA_SIZE_T6, 12591 }, 12592 { 12593 /* T7 */ 12594 .nchan = NCHAN, 12595 .pm_stats_cnt = T6_PM_NSTATS, 12596 .cng_ch_bits_log = 2, 12597 .nsched_cls = 16, 12598 .cim_num_ibq = CIM_NUM_IBQ_T7, 12599 .cim_num_obq = CIM_NUM_OBQ_T7, 12600 .filter_opt_len = T7_FILTER_OPT_LEN, 12601 .filter_num_opt = S_T7_FT_LAST + 1, 12602 .mps_rplc_size = 256, 12603 .vfcount = 256, 12604 .sge_fl_db = 0, 12605 .sge_ctxt_size = SGE_CTXT_SIZE_T7, 12606 .mps_tcam_size = NUM_MPS_T5_CLS_SRAM_L_INSTANCES * 3, 12607 .rss_nentries = T7_RSS_NENTRIES, 12608 .cim_la_size = CIMLA_SIZE_T6, 12609 }, 12610 }; 12611 12612 chipid -= CHELSIO_T4; 12613 if (chipid < 0 || chipid >= ARRAY_SIZE(chip_params)) 12614 return NULL; 12615 12616 return &chip_params[chipid]; 12617 } 12618 12619 /** 12620 * t4_prep_adapter - prepare SW and HW for operation 12621 * @adapter: the adapter 12622 * @buf: temporary space of at least VPD_LEN size provided by the caller. 12623 * 12624 * Initialize adapter SW state for the various HW modules, set initial 12625 * values for some adapter tunables, take PHYs out of reset, and 12626 * initialize the MDIO interface. 12627 */ 12628 int t4_prep_adapter(struct adapter *adapter, u32 *buf) 12629 { 12630 int ret; 12631 uint16_t device_id; 12632 uint32_t pl_rev; 12633 12634 get_pci_mode(adapter, &adapter->params.pci); 12635 12636 pl_rev = t4_read_reg(adapter, A_PL_REV); 12637 adapter->params.chipid = G_CHIPID(pl_rev); 12638 adapter->params.rev = G_REV(pl_rev); 12639 if (adapter->params.chipid == 0) { 12640 /* T4 did not have chipid in PL_REV (T5 onwards do) */ 12641 adapter->params.chipid = CHELSIO_T4; 12642 12643 /* T4A1 chip is not supported */ 12644 if (adapter->params.rev == 1) { 12645 CH_ALERT(adapter, "T4 rev 1 chip is not supported.\n"); 12646 return -EINVAL; 12647 } 12648 } 12649 12650 adapter->chip_params = t4_get_chip_params(chip_id(adapter)); 12651 if (adapter->chip_params == NULL) 12652 return -EINVAL; 12653 12654 adapter->params.pci.vpd_cap_addr = 12655 t4_os_find_pci_capability(adapter, PCI_CAP_ID_VPD); 12656 12657 ret = t4_get_flash_params(adapter); 12658 if (ret < 0) 12659 return ret; 12660 12661 /* Cards with real ASICs have the chipid in the PCIe device id */ 12662 t4_os_pci_read_cfg2(adapter, PCI_DEVICE_ID, &device_id); 12663 if (device_id >> 12 == chip_id(adapter)) 12664 adapter->params.cim_la_size = adapter->chip_params->cim_la_size; 12665 else { 12666 /* FPGA */ 12667 adapter->params.fpga = 1; 12668 adapter->params.cim_la_size = 2 * adapter->chip_params->cim_la_size; 12669 } 12670 12671 ret = get_vpd_params(adapter, &adapter->params.vpd, device_id, buf); 12672 if (ret < 0) 12673 return ret; 12674 12675 init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd); 12676 12677 /* 12678 * Default port and clock for debugging in case we can't reach FW. 12679 */ 12680 adapter->params.nports = 1; 12681 adapter->params.portvec = 1; 12682 adapter->params.vpd.cclk = 50000; 12683 12684 /* Set pci completion timeout value to 4 seconds. */ 12685 set_pcie_completion_timeout(adapter, 0xd); 12686 return 0; 12687 } 12688 12689 /** 12690 * t4_shutdown_adapter - shut down adapter, host & wire 12691 * @adapter: the adapter 12692 * 12693 * Perform an emergency shutdown of the adapter and stop it from 12694 * continuing any further communication on the ports or DMA to the 12695 * host. This is typically used when the adapter and/or firmware 12696 * have crashed and we want to prevent any further accidental 12697 * communication with the rest of the world. This will also force 12698 * the port Link Status to go down -- if register writes work -- 12699 * which should help our peers figure out that we're down. 12700 */ 12701 int t4_shutdown_adapter(struct adapter *adapter) 12702 { 12703 int port; 12704 const bool bt = adapter->bt_map != 0; 12705 12706 t4_intr_disable(adapter); 12707 if (bt) 12708 t4_write_reg(adapter, A_DBG_GPIO_EN, 0xffff0000); 12709 for_each_port(adapter, port) { 12710 u32 a_port_cfg = is_t4(adapter) ? 12711 t4_port_reg(adapter, port, A_XGMAC_PORT_CFG) : 12712 t4_port_reg(adapter, port, A_MAC_PORT_CFG); 12713 12714 t4_write_reg(adapter, a_port_cfg, 12715 t4_read_reg(adapter, a_port_cfg) 12716 & ~V_SIGNAL_DET(1)); 12717 if (!bt) { 12718 u32 hss_cfg0 = is_t4(adapter) ? 12719 t4_port_reg(adapter, port, A_XGMAC_PORT_HSS_CFG0) : 12720 t4_port_reg(adapter, port, A_MAC_PORT_HSS_CFG0); 12721 t4_set_reg_field(adapter, hss_cfg0, F_HSSPDWNPLLB | 12722 F_HSSPDWNPLLA | F_HSSPLLBYPB | F_HSSPLLBYPA, 12723 F_HSSPDWNPLLB | F_HSSPDWNPLLA | F_HSSPLLBYPB | 12724 F_HSSPLLBYPA); 12725 } 12726 } 12727 t4_set_reg_field(adapter, A_SGE_CONTROL, F_GLOBALENABLE, 0); 12728 12729 return 0; 12730 } 12731 12732 /** 12733 * t4_bar2_sge_qregs - return BAR2 SGE Queue register information 12734 * @adapter: the adapter 12735 * @qid: the Queue ID 12736 * @qtype: the Ingress or Egress type for @qid 12737 * @user: true if this request is for a user mode queue 12738 * @pbar2_qoffset: BAR2 Queue Offset 12739 * @pbar2_qid: BAR2 Queue ID or 0 for Queue ID inferred SGE Queues 12740 * 12741 * Returns the BAR2 SGE Queue Registers information associated with the 12742 * indicated Absolute Queue ID. These are passed back in return value 12743 * pointers. @qtype should be T4_BAR2_QTYPE_EGRESS for Egress Queue 12744 * and T4_BAR2_QTYPE_INGRESS for Ingress Queues. 12745 * 12746 * This may return an error which indicates that BAR2 SGE Queue 12747 * registers aren't available. If an error is not returned, then the 12748 * following values are returned: 12749 * 12750 * *@pbar2_qoffset: the BAR2 Offset of the @qid Registers 12751 * *@pbar2_qid: the BAR2 SGE Queue ID or 0 of @qid 12752 * 12753 * If the returned BAR2 Queue ID is 0, then BAR2 SGE registers which 12754 * require the "Inferred Queue ID" ability may be used. E.g. the 12755 * Write Combining Doorbell Buffer. If the BAR2 Queue ID is not 0, 12756 * then these "Inferred Queue ID" register may not be used. 12757 */ 12758 int t4_bar2_sge_qregs(struct adapter *adapter, 12759 unsigned int qid, 12760 enum t4_bar2_qtype qtype, 12761 int user, 12762 u64 *pbar2_qoffset, 12763 unsigned int *pbar2_qid) 12764 { 12765 unsigned int page_shift, page_size, qpp_shift, qpp_mask; 12766 u64 bar2_page_offset, bar2_qoffset; 12767 unsigned int bar2_qid, bar2_qid_offset, bar2_qinferred; 12768 12769 /* T4 doesn't support BAR2 SGE Queue registers for kernel 12770 * mode queues. 12771 */ 12772 if (!user && is_t4(adapter)) 12773 return -EINVAL; 12774 12775 /* Get our SGE Page Size parameters. 12776 */ 12777 page_shift = adapter->params.sge.page_shift; 12778 page_size = 1 << page_shift; 12779 12780 /* Get the right Queues per Page parameters for our Queue. 12781 */ 12782 qpp_shift = (qtype == T4_BAR2_QTYPE_EGRESS 12783 ? adapter->params.sge.eq_s_qpp 12784 : adapter->params.sge.iq_s_qpp); 12785 qpp_mask = (1 << qpp_shift) - 1; 12786 12787 /* Calculate the basics of the BAR2 SGE Queue register area: 12788 * o The BAR2 page the Queue registers will be in. 12789 * o The BAR2 Queue ID. 12790 * o The BAR2 Queue ID Offset into the BAR2 page. 12791 */ 12792 bar2_page_offset = ((u64)(qid >> qpp_shift) << page_shift); 12793 bar2_qid = qid & qpp_mask; 12794 bar2_qid_offset = bar2_qid * SGE_UDB_SIZE; 12795 12796 /* If the BAR2 Queue ID Offset is less than the Page Size, then the 12797 * hardware will infer the Absolute Queue ID simply from the writes to 12798 * the BAR2 Queue ID Offset within the BAR2 Page (and we need to use a 12799 * BAR2 Queue ID of 0 for those writes). Otherwise, we'll simply 12800 * write to the first BAR2 SGE Queue Area within the BAR2 Page with 12801 * the BAR2 Queue ID and the hardware will infer the Absolute Queue ID 12802 * from the BAR2 Page and BAR2 Queue ID. 12803 * 12804 * One important censequence of this is that some BAR2 SGE registers 12805 * have a "Queue ID" field and we can write the BAR2 SGE Queue ID 12806 * there. But other registers synthesize the SGE Queue ID purely 12807 * from the writes to the registers -- the Write Combined Doorbell 12808 * Buffer is a good example. These BAR2 SGE Registers are only 12809 * available for those BAR2 SGE Register areas where the SGE Absolute 12810 * Queue ID can be inferred from simple writes. 12811 */ 12812 bar2_qoffset = bar2_page_offset; 12813 bar2_qinferred = (bar2_qid_offset < page_size); 12814 if (bar2_qinferred) { 12815 bar2_qoffset += bar2_qid_offset; 12816 bar2_qid = 0; 12817 } 12818 12819 *pbar2_qoffset = bar2_qoffset; 12820 *pbar2_qid = bar2_qid; 12821 return 0; 12822 } 12823 12824 /** 12825 * t4_init_devlog_ncores_params - initialize adap->params.devlog and ncores 12826 * @adap: the adapter 12827 * @fw_attach: whether we can talk to the firmware 12828 */ 12829 int t4_init_devlog_ncores_params(struct adapter *adap, int fw_attach) 12830 { 12831 struct devlog_params *dparams = &adap->params.devlog; 12832 u32 pf_dparams; 12833 unsigned int devlog_meminfo; 12834 struct fw_devlog_cmd devlog_cmd; 12835 int ret; 12836 12837 /* If we're dealing with newer firmware, the Device Log Paramerters 12838 * are stored in a designated register which allows us to access the 12839 * Device Log even if we can't talk to the firmware. 12840 */ 12841 pf_dparams = 12842 t4_read_reg(adap, PCIE_FW_REG(A_PCIE_FW_PF, PCIE_FW_PF_DEVLOG)); 12843 if (pf_dparams && pf_dparams != UINT32_MAX) { 12844 unsigned int nentries, nentries128, ncore_shift; 12845 12846 ncore_shift = (G_PCIE_FW_PF_DEVLOG_COUNT_MSB(pf_dparams) << 1) | 12847 G_PCIE_FW_PF_DEVLOG_COUNT_LSB(pf_dparams); 12848 adap->params.ncores = 1 << ncore_shift; 12849 12850 dparams->memtype = G_PCIE_FW_PF_DEVLOG_MEMTYPE(pf_dparams); 12851 dparams->start = G_PCIE_FW_PF_DEVLOG_ADDR16(pf_dparams) << 4; 12852 nentries128 = G_PCIE_FW_PF_DEVLOG_NENTRIES128(pf_dparams); 12853 nentries = (nentries128 + 1) * 128; 12854 dparams->size = nentries * sizeof(struct fw_devlog_e); 12855 12856 return 0; 12857 } 12858 12859 /* 12860 * For any failing returns ... 12861 */ 12862 adap->params.ncores = 1; 12863 memset(dparams, 0, sizeof *dparams); 12864 12865 /* 12866 * If we can't talk to the firmware, there's really nothing we can do 12867 * at this point. 12868 */ 12869 if (!fw_attach) 12870 return -ENXIO; 12871 12872 /* Otherwise, ask the firmware for it's Device Log Parameters. 12873 */ 12874 memset(&devlog_cmd, 0, sizeof devlog_cmd); 12875 devlog_cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_DEVLOG_CMD) | 12876 F_FW_CMD_REQUEST | F_FW_CMD_READ); 12877 devlog_cmd.retval_len16 = cpu_to_be32(FW_LEN16(devlog_cmd)); 12878 ret = t4_wr_mbox(adap, adap->mbox, &devlog_cmd, sizeof(devlog_cmd), 12879 &devlog_cmd); 12880 if (ret) 12881 return ret; 12882 12883 devlog_meminfo = 12884 be32_to_cpu(devlog_cmd.memtype_devlog_memaddr16_devlog); 12885 dparams->memtype = G_FW_DEVLOG_CMD_MEMTYPE_DEVLOG(devlog_meminfo); 12886 dparams->start = G_FW_DEVLOG_CMD_MEMADDR16_DEVLOG(devlog_meminfo) << 4; 12887 dparams->size = be32_to_cpu(devlog_cmd.memsize_devlog); 12888 12889 return 0; 12890 } 12891 12892 /** 12893 * t4_init_sge_params - initialize adap->params.sge 12894 * @adapter: the adapter 12895 * 12896 * Initialize various fields of the adapter's SGE Parameters structure. 12897 */ 12898 int t4_init_sge_params(struct adapter *adapter) 12899 { 12900 u32 r; 12901 struct sge_params *sp = &adapter->params.sge; 12902 unsigned i, tscale = 1; 12903 12904 r = t4_read_reg(adapter, A_SGE_INGRESS_RX_THRESHOLD); 12905 sp->counter_val[0] = G_THRESHOLD_0(r); 12906 sp->counter_val[1] = G_THRESHOLD_1(r); 12907 sp->counter_val[2] = G_THRESHOLD_2(r); 12908 sp->counter_val[3] = G_THRESHOLD_3(r); 12909 12910 if (chip_id(adapter) >= CHELSIO_T6) { 12911 r = t4_read_reg(adapter, A_SGE_ITP_CONTROL); 12912 tscale = G_TSCALE(r); 12913 if (tscale == 0) 12914 tscale = 1; 12915 else 12916 tscale += 2; 12917 } 12918 12919 r = t4_read_reg(adapter, A_SGE_TIMER_VALUE_0_AND_1); 12920 sp->timer_val[0] = core_ticks_to_us(adapter, G_TIMERVALUE0(r)) * tscale; 12921 sp->timer_val[1] = core_ticks_to_us(adapter, G_TIMERVALUE1(r)) * tscale; 12922 r = t4_read_reg(adapter, A_SGE_TIMER_VALUE_2_AND_3); 12923 sp->timer_val[2] = core_ticks_to_us(adapter, G_TIMERVALUE2(r)) * tscale; 12924 sp->timer_val[3] = core_ticks_to_us(adapter, G_TIMERVALUE3(r)) * tscale; 12925 r = t4_read_reg(adapter, A_SGE_TIMER_VALUE_4_AND_5); 12926 sp->timer_val[4] = core_ticks_to_us(adapter, G_TIMERVALUE4(r)) * tscale; 12927 sp->timer_val[5] = core_ticks_to_us(adapter, G_TIMERVALUE5(r)) * tscale; 12928 12929 r = t4_read_reg(adapter, A_SGE_CONM_CTRL); 12930 sp->fl_starve_threshold = G_EGRTHRESHOLD(r) * 2 + 1; 12931 if (is_t4(adapter)) 12932 sp->fl_starve_threshold2 = sp->fl_starve_threshold; 12933 else if (is_t5(adapter)) 12934 sp->fl_starve_threshold2 = G_EGRTHRESHOLDPACKING(r) * 2 + 1; 12935 else 12936 sp->fl_starve_threshold2 = G_T6_EGRTHRESHOLDPACKING(r) * 2 + 1; 12937 12938 /* egress queues: log2 of # of doorbells per BAR2 page */ 12939 r = t4_read_reg(adapter, A_SGE_EGRESS_QUEUES_PER_PAGE_PF); 12940 r >>= S_QUEUESPERPAGEPF0 + 12941 (S_QUEUESPERPAGEPF1 - S_QUEUESPERPAGEPF0) * adapter->pf; 12942 sp->eq_s_qpp = r & M_QUEUESPERPAGEPF0; 12943 12944 /* ingress queues: log2 of # of doorbells per BAR2 page */ 12945 r = t4_read_reg(adapter, A_SGE_INGRESS_QUEUES_PER_PAGE_PF); 12946 r >>= S_QUEUESPERPAGEPF0 + 12947 (S_QUEUESPERPAGEPF1 - S_QUEUESPERPAGEPF0) * adapter->pf; 12948 sp->iq_s_qpp = r & M_QUEUESPERPAGEPF0; 12949 12950 r = t4_read_reg(adapter, A_SGE_HOST_PAGE_SIZE); 12951 r >>= S_HOSTPAGESIZEPF0 + 12952 (S_HOSTPAGESIZEPF1 - S_HOSTPAGESIZEPF0) * adapter->pf; 12953 sp->page_shift = (r & M_HOSTPAGESIZEPF0) + 10; 12954 12955 r = t4_read_reg(adapter, A_SGE_CONTROL); 12956 sp->sge_control = r; 12957 sp->spg_len = r & F_EGRSTATUSPAGESIZE ? 128 : 64; 12958 sp->fl_pktshift = G_PKTSHIFT(r); 12959 if (chip_id(adapter) <= CHELSIO_T5) { 12960 sp->pad_boundary = 1 << (G_INGPADBOUNDARY(r) + 12961 X_INGPADBOUNDARY_SHIFT); 12962 } else { 12963 sp->pad_boundary = 1 << (G_INGPADBOUNDARY(r) + 12964 X_T6_INGPADBOUNDARY_SHIFT); 12965 } 12966 if (is_t4(adapter)) 12967 sp->pack_boundary = sp->pad_boundary; 12968 else { 12969 r = t4_read_reg(adapter, A_SGE_CONTROL2); 12970 if (G_INGPACKBOUNDARY(r) == 0) 12971 sp->pack_boundary = 16; 12972 else 12973 sp->pack_boundary = 1 << (G_INGPACKBOUNDARY(r) + 5); 12974 } 12975 for (i = 0; i < SGE_FLBUF_SIZES; i++) 12976 sp->sge_fl_buffer_size[i] = t4_read_reg(adapter, 12977 A_SGE_FL_BUFFER_SIZE0 + (4 * i)); 12978 12979 return 0; 12980 } 12981 12982 /* Convert the LE's hardware hash mask to a shorter filter mask. */ 12983 static inline uint16_t 12984 hashmask_to_filtermask(struct adapter *adap, uint64_t hashmask, uint16_t filter_mode) 12985 { 12986 int first, last, i; 12987 uint16_t filter_mask; 12988 uint64_t mask; /* field mask */ 12989 12990 12991 if (chip_id(adap) >= CHELSIO_T7) { 12992 first = S_T7_FT_FIRST; 12993 last = S_T7_FT_LAST; 12994 } else { 12995 first = S_FT_FIRST; 12996 last = S_FT_LAST; 12997 } 12998 12999 for (filter_mask = 0, i = first; i <= last; i++) { 13000 if ((filter_mode & (1 << i)) == 0) 13001 continue; 13002 mask = (1 << t4_filter_field_width(adap, i)) - 1; 13003 if ((hashmask & mask) == mask) 13004 filter_mask |= 1 << i; 13005 hashmask >>= t4_filter_field_width(adap, i); 13006 } 13007 13008 return (filter_mask); 13009 } 13010 13011 /* 13012 * Read and cache the adapter's compressed filter mode and ingress config. 13013 */ 13014 static void 13015 read_filter_mode_and_ingress_config(struct adapter *adap) 13016 { 13017 int rc; 13018 uint32_t v, param[2], val[2]; 13019 struct tp_params *tpp = &adap->params.tp; 13020 uint64_t hash_mask; 13021 13022 param[0] = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | 13023 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_FILTER) | 13024 V_FW_PARAMS_PARAM_Y(FW_PARAM_DEV_FILTER_MODE_MASK); 13025 param[1] = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | 13026 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_FILTER) | 13027 V_FW_PARAMS_PARAM_Y(FW_PARAM_DEV_FILTER_VNIC_MODE); 13028 rc = -t4_query_params(adap, adap->mbox, adap->pf, 0, 2, param, val); 13029 if (rc == 0) { 13030 tpp->filter_mode = G_FW_PARAMS_PARAM_FILTER_MODE(val[0]); 13031 tpp->filter_mask = G_FW_PARAMS_PARAM_FILTER_MASK(val[0]); 13032 tpp->vnic_mode = val[1]; 13033 } else { 13034 /* 13035 * Old firmware. Read filter mode/mask and ingress config 13036 * straight from the hardware. 13037 */ 13038 t4_tp_pio_read(adap, &v, 1, A_TP_VLAN_PRI_MAP, true); 13039 tpp->filter_mode = v & 0xffff; 13040 13041 hash_mask = 0; 13042 if (chip_id(adap) > CHELSIO_T4) { 13043 v = t4_read_reg(adap, LE_HASH_MASK_GEN_IPV4T5(3)); 13044 hash_mask = v; 13045 v = t4_read_reg(adap, LE_HASH_MASK_GEN_IPV4T5(4)); 13046 hash_mask |= (u64)v << 32; 13047 } 13048 if (chip_id(adap) >= CHELSIO_T7) { 13049 /* 13050 * This param came before T7 so T7+ firmwares should 13051 * always support this query. 13052 */ 13053 CH_WARN(adap, "query for filter mode/mask failed: %d\n", 13054 rc); 13055 } 13056 tpp->filter_mask = hashmask_to_filtermask(adap, hash_mask, 13057 tpp->filter_mode); 13058 13059 t4_tp_pio_read(adap, &v, 1, A_TP_INGRESS_CONFIG, true); 13060 if (v & F_VNIC) 13061 tpp->vnic_mode = FW_VNIC_MODE_PF_VF; 13062 else 13063 tpp->vnic_mode = FW_VNIC_MODE_OUTER_VLAN; 13064 } 13065 13066 /* 13067 * Now that we have TP_VLAN_PRI_MAP cached, we can calculate the field 13068 * shift positions of several elements of the Compressed Filter Tuple 13069 * for this adapter which we need frequently ... 13070 */ 13071 if (chip_id(adap) >= CHELSIO_T7) { 13072 tpp->ipsecidx_shift = t4_filter_field_shift(adap, F_IPSECIDX); 13073 tpp->fcoe_shift = t4_filter_field_shift(adap, F_T7_FCOE); 13074 tpp->port_shift = t4_filter_field_shift(adap, F_T7_PORT); 13075 tpp->vnic_shift = t4_filter_field_shift(adap, F_T7_VNIC_ID); 13076 tpp->vlan_shift = t4_filter_field_shift(adap, F_T7_VLAN); 13077 tpp->tos_shift = t4_filter_field_shift(adap, F_T7_TOS); 13078 tpp->protocol_shift = t4_filter_field_shift(adap, F_T7_PROTOCOL); 13079 tpp->ethertype_shift = t4_filter_field_shift(adap, F_T7_ETHERTYPE); 13080 tpp->macmatch_shift = t4_filter_field_shift(adap, F_T7_MACMATCH); 13081 tpp->matchtype_shift = t4_filter_field_shift(adap, F_T7_MPSHITTYPE); 13082 tpp->frag_shift = t4_filter_field_shift(adap, F_T7_FRAGMENTATION); 13083 tpp->roce_shift = t4_filter_field_shift(adap, F_ROCE); 13084 tpp->synonly_shift = t4_filter_field_shift(adap, F_SYNONLY); 13085 tpp->tcpflags_shift = t4_filter_field_shift(adap, F_TCPFLAGS); 13086 } else { 13087 tpp->ipsecidx_shift = -1; 13088 tpp->fcoe_shift = t4_filter_field_shift(adap, F_FCOE); 13089 tpp->port_shift = t4_filter_field_shift(adap, F_PORT); 13090 tpp->vnic_shift = t4_filter_field_shift(adap, F_VNIC_ID); 13091 tpp->vlan_shift = t4_filter_field_shift(adap, F_VLAN); 13092 tpp->tos_shift = t4_filter_field_shift(adap, F_TOS); 13093 tpp->protocol_shift = t4_filter_field_shift(adap, F_PROTOCOL); 13094 tpp->ethertype_shift = t4_filter_field_shift(adap, F_ETHERTYPE); 13095 tpp->macmatch_shift = t4_filter_field_shift(adap, F_MACMATCH); 13096 tpp->matchtype_shift = t4_filter_field_shift(adap, F_MPSHITTYPE); 13097 tpp->frag_shift = t4_filter_field_shift(adap, F_FRAGMENTATION); 13098 tpp->roce_shift = -1; 13099 tpp->synonly_shift = -1; 13100 tpp->tcpflags_shift = -1; 13101 } 13102 } 13103 13104 /** 13105 * t4_init_tp_params - initialize adap->params.tp 13106 * @adap: the adapter 13107 * 13108 * Initialize various fields of the adapter's TP Parameters structure. 13109 */ 13110 int t4_init_tp_params(struct adapter *adap) 13111 { 13112 u32 tx_len, rx_len, r, v; 13113 struct tp_params *tpp = &adap->params.tp; 13114 13115 v = t4_read_reg(adap, A_TP_TIMER_RESOLUTION); 13116 tpp->tre = G_TIMERRESOLUTION(v); 13117 tpp->dack_re = G_DELAYEDACKRESOLUTION(v); 13118 13119 read_filter_mode_and_ingress_config(adap); 13120 13121 tpp->rx_pkt_encap = false; 13122 tpp->lb_mode = 0; 13123 tpp->lb_nchan = 1; 13124 if (chip_id(adap) > CHELSIO_T5) { 13125 v = t4_read_reg(adap, A_TP_OUT_CONFIG); 13126 tpp->rx_pkt_encap = v & F_CRXPKTENC; 13127 if (chip_id(adap) >= CHELSIO_T7) { 13128 t4_tp_pio_read(adap, &v, 1, A_TP_CHANNEL_MAP, true); 13129 tpp->lb_mode = G_T7_LB_MODE(v); 13130 if (tpp->lb_mode == 1) 13131 tpp->lb_nchan = 4; 13132 else if (tpp->lb_mode == 2) 13133 tpp->lb_nchan = 2; 13134 } 13135 } 13136 13137 rx_len = t4_read_reg(adap, A_TP_PMM_RX_PAGE_SIZE); 13138 tx_len = t4_read_reg(adap, A_TP_PMM_TX_PAGE_SIZE); 13139 13140 r = t4_read_reg(adap, A_TP_PARA_REG2); 13141 rx_len = min(rx_len, G_MAXRXDATA(r)); 13142 tx_len = min(tx_len, G_MAXRXDATA(r)); 13143 13144 r = t4_read_reg(adap, A_TP_PARA_REG7); 13145 v = min(G_PMMAXXFERLEN0(r), G_PMMAXXFERLEN1(r)); 13146 rx_len = min(rx_len, v); 13147 tx_len = min(tx_len, v); 13148 13149 tpp->max_tx_pdu = tx_len; 13150 tpp->max_rx_pdu = rx_len; 13151 13152 return 0; 13153 } 13154 13155 /** 13156 * t4_filter_field_width - returns the width of a filter field 13157 * @adap: the adapter 13158 * @filter_field: the filter field whose width is being requested 13159 * 13160 * Return the shift position of a filter field within the Compressed 13161 * Filter Tuple. The filter field is specified via its selection bit 13162 * within TP_VLAN_PRI_MAL (filter mode). E.g. F_VLAN. 13163 */ 13164 int t4_filter_field_width(const struct adapter *adap, int filter_field) 13165 { 13166 const int nopt = adap->chip_params->filter_num_opt; 13167 static const uint8_t width_t7[] = { 13168 W_FT_IPSECIDX, 13169 W_FT_FCOE, 13170 W_FT_PORT, 13171 W_FT_VNIC_ID, 13172 W_FT_VLAN, 13173 W_FT_TOS, 13174 W_FT_PROTOCOL, 13175 W_FT_ETHERTYPE, 13176 W_FT_MACMATCH, 13177 W_FT_MPSHITTYPE, 13178 W_FT_FRAGMENTATION, 13179 W_FT_ROCE, 13180 W_FT_SYNONLY, 13181 W_FT_TCPFLAGS 13182 }; 13183 static const uint8_t width_t4[] = { 13184 W_FT_FCOE, 13185 W_FT_PORT, 13186 W_FT_VNIC_ID, 13187 W_FT_VLAN, 13188 W_FT_TOS, 13189 W_FT_PROTOCOL, 13190 W_FT_ETHERTYPE, 13191 W_FT_MACMATCH, 13192 W_FT_MPSHITTYPE, 13193 W_FT_FRAGMENTATION 13194 }; 13195 const uint8_t *width = chip_id(adap) >= CHELSIO_T7 ? width_t7 : width_t4; 13196 13197 if (filter_field < 0 || filter_field >= nopt) 13198 return (0); 13199 return (width[filter_field]); 13200 } 13201 13202 /** 13203 * t4_filter_field_shift - calculate filter field shift 13204 * @adap: the adapter 13205 * @filter_sel: the desired field (from TP_VLAN_PRI_MAP bits) 13206 * 13207 * Return the shift position of a filter field within the Compressed 13208 * Filter Tuple. The filter field is specified via its selection bit 13209 * within TP_VLAN_PRI_MAL (filter mode). E.g. F_VLAN. 13210 */ 13211 int t4_filter_field_shift(const struct adapter *adap, int filter_sel) 13212 { 13213 const unsigned int filter_mode = adap->params.tp.filter_mode; 13214 unsigned int sel; 13215 int field_shift; 13216 13217 if ((filter_mode & filter_sel) == 0) 13218 return -1; 13219 13220 if (chip_id(adap) >= CHELSIO_T7) { 13221 for (sel = 1, field_shift = 0; sel < filter_sel; sel <<= 1) { 13222 switch (filter_mode & sel) { 13223 case F_IPSECIDX: 13224 field_shift += W_FT_IPSECIDX; 13225 break; 13226 case F_T7_FCOE: 13227 field_shift += W_FT_FCOE; 13228 break; 13229 case F_T7_PORT: 13230 field_shift += W_FT_PORT; 13231 break; 13232 case F_T7_VNIC_ID: 13233 field_shift += W_FT_VNIC_ID; 13234 break; 13235 case F_T7_VLAN: 13236 field_shift += W_FT_VLAN; 13237 break; 13238 case F_T7_TOS: 13239 field_shift += W_FT_TOS; 13240 break; 13241 case F_T7_PROTOCOL: 13242 field_shift += W_FT_PROTOCOL; 13243 break; 13244 case F_T7_ETHERTYPE: 13245 field_shift += W_FT_ETHERTYPE; 13246 break; 13247 case F_T7_MACMATCH: 13248 field_shift += W_FT_MACMATCH; 13249 break; 13250 case F_T7_MPSHITTYPE: 13251 field_shift += W_FT_MPSHITTYPE; 13252 break; 13253 case F_T7_FRAGMENTATION: 13254 field_shift += W_FT_FRAGMENTATION; 13255 break; 13256 case F_ROCE: 13257 field_shift += W_FT_ROCE; 13258 break; 13259 case F_SYNONLY: 13260 field_shift += W_FT_SYNONLY; 13261 break; 13262 case F_TCPFLAGS: 13263 field_shift += W_FT_TCPFLAGS; 13264 break; 13265 } 13266 } 13267 return field_shift; 13268 } 13269 13270 for (sel = 1, field_shift = 0; sel < filter_sel; sel <<= 1) { 13271 switch (filter_mode & sel) { 13272 case F_FCOE: 13273 field_shift += W_FT_FCOE; 13274 break; 13275 case F_PORT: 13276 field_shift += W_FT_PORT; 13277 break; 13278 case F_VNIC_ID: 13279 field_shift += W_FT_VNIC_ID; 13280 break; 13281 case F_VLAN: 13282 field_shift += W_FT_VLAN; 13283 break; 13284 case F_TOS: 13285 field_shift += W_FT_TOS; 13286 break; 13287 case F_PROTOCOL: 13288 field_shift += W_FT_PROTOCOL; 13289 break; 13290 case F_ETHERTYPE: 13291 field_shift += W_FT_ETHERTYPE; 13292 break; 13293 case F_MACMATCH: 13294 field_shift += W_FT_MACMATCH; 13295 break; 13296 case F_MPSHITTYPE: 13297 field_shift += W_FT_MPSHITTYPE; 13298 break; 13299 case F_FRAGMENTATION: 13300 field_shift += W_FT_FRAGMENTATION; 13301 break; 13302 } 13303 } 13304 return field_shift; 13305 } 13306 13307 int t4_port_init(struct adapter *adap, int mbox, int pf, int vf, int port_id) 13308 { 13309 u8 addr[6]; 13310 int ret, i, j; 13311 struct port_info *p = adap2pinfo(adap, port_id); 13312 u32 param, val; 13313 struct vi_info *vi = &p->vi[0]; 13314 13315 for (i = 0, j = -1; i <= p->port_id; i++) { 13316 do { 13317 j++; 13318 } while ((adap->params.portvec & (1 << j)) == 0); 13319 } 13320 13321 p->hw_port = j; 13322 p->tx_chan = t4_get_tx_c_chan(adap, j); 13323 p->rx_chan = t4_get_rx_c_chan(adap, j); 13324 p->mps_bg_map = t4_get_mps_bg_map(adap, j); 13325 p->rx_e_chan_map = t4_get_rx_e_chan_map(adap, j); 13326 13327 if (!(adap->flags & IS_VF) || 13328 adap->params.vfres.r_caps & FW_CMD_CAP_PORT) { 13329 t4_update_port_info(p); 13330 } 13331 13332 ret = t4_alloc_vi(adap, mbox, j, pf, vf, 1, addr, &vi->rss_size, 13333 &vi->vfvld, &vi->vin); 13334 if (ret < 0) 13335 return ret; 13336 13337 vi->viid = ret; 13338 t4_os_set_hw_addr(p, addr); 13339 13340 param = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | 13341 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_RSSINFO) | 13342 V_FW_PARAMS_PARAM_YZ(vi->viid); 13343 ret = t4_query_params(adap, mbox, pf, vf, 1, ¶m, &val); 13344 if (ret) 13345 vi->rss_base = 0xffff; 13346 else { 13347 /* MPASS((val >> 16) == rss_size); */ 13348 vi->rss_base = val & 0xffff; 13349 } 13350 13351 return 0; 13352 } 13353 13354 static void t4_read_cimq_cfg_ibq_core(struct adapter *adap, u8 coreid, u32 qid, 13355 u16 *base, u16 *size, u16 *thres) 13356 { 13357 unsigned int v, m; 13358 13359 if (chip_id(adap) > CHELSIO_T6) { 13360 v = F_T7_IBQSELECT | V_T7_QUENUMSELECT(qid) | 13361 V_CORESELECT(coreid); 13362 /* value is in 512-byte units */ 13363 m = 512; 13364 } else { 13365 v = F_IBQSELECT | V_QUENUMSELECT(qid); 13366 /* value is in 256-byte units */ 13367 m = 256; 13368 } 13369 13370 t4_write_reg(adap, A_CIM_QUEUE_CONFIG_REF, v); 13371 v = t4_read_reg(adap, A_CIM_QUEUE_CONFIG_CTRL); 13372 if (base) 13373 *base = G_CIMQBASE(v) * m; 13374 if (size) 13375 *size = G_CIMQSIZE(v) * m; 13376 if (thres) 13377 *thres = G_QUEFULLTHRSH(v) * 8; /* 8-byte unit */ 13378 } 13379 13380 static void t4_read_cimq_cfg_obq_core(struct adapter *adap, u8 coreid, u32 qid, 13381 u16 *base, u16 *size) 13382 { 13383 unsigned int v, m; 13384 13385 if (chip_id(adap) > CHELSIO_T6) { 13386 v = F_T7_OBQSELECT | V_T7_QUENUMSELECT(qid) | 13387 V_CORESELECT(coreid); 13388 /* value is in 512-byte units */ 13389 m = 512; 13390 } else { 13391 v = F_OBQSELECT | V_QUENUMSELECT(qid); 13392 /* value is in 256-byte units */ 13393 m = 256; 13394 } 13395 13396 t4_write_reg(adap, A_CIM_QUEUE_CONFIG_REF, v); 13397 v = t4_read_reg(adap, A_CIM_QUEUE_CONFIG_CTRL); 13398 if (base) 13399 *base = G_CIMQBASE(v) * m; 13400 if (size) 13401 *size = G_CIMQSIZE(v) * m; 13402 } 13403 13404 /** 13405 * t4_read_cimq_cfg_core - read CIM queue configuration on specific core 13406 * @adap: the adapter 13407 * @coreid: the uP coreid 13408 * @base: holds the queue base addresses in bytes 13409 * @size: holds the queue sizes in bytes 13410 * @thres: holds the queue full thresholds in bytes 13411 * 13412 * Returns the current configuration of the CIM queues, starting with 13413 * the IBQs, then the OBQs, on a specific @coreid. 13414 */ 13415 void t4_read_cimq_cfg_core(struct adapter *adap, u8 coreid, u16 *base, 13416 u16 *size, u16 *thres) 13417 { 13418 unsigned int cim_num_ibq = adap->chip_params->cim_num_ibq; 13419 unsigned int cim_num_obq = adap->chip_params->cim_num_obq; 13420 unsigned int i; 13421 13422 for (i = 0; i < cim_num_ibq; i++, base++, size++, thres++) 13423 t4_read_cimq_cfg_ibq_core(adap, coreid, i, base, size, thres); 13424 13425 for (i = 0; i < cim_num_obq; i++, base++, size++) 13426 t4_read_cimq_cfg_obq_core(adap, coreid, i, base, size); 13427 } 13428 13429 static int t4_read_cim_ibq_data_core(struct adapter *adap, u8 coreid, u32 addr, 13430 u32 *data) 13431 { 13432 int ret, attempts; 13433 unsigned int v; 13434 13435 /* It might take 3-10ms before the IBQ debug read access is allowed. 13436 * Wait for 1 Sec with a delay of 1 usec. 13437 */ 13438 attempts = 1000000; 13439 13440 if (chip_id(adap) > CHELSIO_T6) 13441 v = V_T7_IBQDBGADDR(addr) | V_IBQDBGCORE(coreid); 13442 else 13443 v = V_IBQDBGADDR(addr); 13444 13445 t4_write_reg(adap, A_CIM_IBQ_DBG_CFG, v | F_IBQDBGEN); 13446 ret = t4_wait_op_done(adap, A_CIM_IBQ_DBG_CFG, F_IBQDBGBUSY, 0, 13447 attempts, 1); 13448 if (ret) 13449 return ret; 13450 13451 *data = t4_read_reg(adap, A_CIM_IBQ_DBG_DATA); 13452 return 0; 13453 } 13454 13455 /** 13456 * t4_read_cim_ibq_core - read the contents of a CIM inbound queue on 13457 * specific core 13458 * @adap: the adapter 13459 * @coreid: the uP coreid 13460 * @qid: the queue index 13461 * @data: where to store the queue contents 13462 * @n: capacity of @data in 32-bit words 13463 * 13464 * Reads the contents of the selected CIM queue starting at address 0 up 13465 * to the capacity of @data on a specific @coreid. @n must be a multiple 13466 * of 4. Returns < 0 on error and the number of 32-bit words actually 13467 * read on success. 13468 */ 13469 int t4_read_cim_ibq_core(struct adapter *adap, u8 coreid, u32 qid, u32 *data, 13470 size_t n) 13471 { 13472 unsigned int cim_num_ibq = adap->chip_params->cim_num_ibq; 13473 u16 i, addr, nwords; 13474 int ret; 13475 13476 if (qid > (cim_num_ibq - 1) || (n & 3)) 13477 return -EINVAL; 13478 13479 t4_read_cimq_cfg_ibq_core(adap, coreid, qid, &addr, &nwords, NULL); 13480 addr >>= sizeof(u16); 13481 nwords >>= sizeof(u16); 13482 if (n > nwords) 13483 n = nwords; 13484 13485 for (i = 0; i < n; i++, addr++, data++) { 13486 ret = t4_read_cim_ibq_data_core(adap, coreid, addr, data); 13487 if (ret < 0) 13488 return ret; 13489 } 13490 13491 t4_write_reg(adap, A_CIM_IBQ_DBG_CFG, 0); 13492 return i; 13493 } 13494 13495 static int t4_read_cim_obq_data_core(struct adapter *adap, u8 coreid, u32 addr, 13496 u32 *data) 13497 { 13498 unsigned int v; 13499 int ret; 13500 13501 if (chip_id(adap) > CHELSIO_T6) 13502 v = V_T7_OBQDBGADDR(addr) | V_OBQDBGCORE(coreid); 13503 else 13504 v = V_OBQDBGADDR(addr); 13505 13506 t4_write_reg(adap, A_CIM_OBQ_DBG_CFG, v | F_OBQDBGEN); 13507 ret = t4_wait_op_done(adap, A_CIM_OBQ_DBG_CFG, F_OBQDBGBUSY, 0, 2, 1); 13508 if (ret) 13509 return ret; 13510 13511 *data = t4_read_reg(adap, A_CIM_OBQ_DBG_DATA); 13512 return 0; 13513 } 13514 13515 /** 13516 * t4_read_cim_obq_core - read the contents of a CIM outbound queue on 13517 * specific core 13518 * @adap: the adapter 13519 * @coreid: the uP coreid 13520 * @qid: the queue index 13521 * @data: where to store the queue contents 13522 * @n: capacity of @data in 32-bit words 13523 * 13524 * Reads the contents of the selected CIM queue starting at address 0 up 13525 * to the capacity of @data on specific @coreid. @n must be a multiple 13526 * of 4. Returns < 0 on error and the number of 32-bit words actually 13527 * read on success. 13528 */ 13529 int t4_read_cim_obq_core(struct adapter *adap, u8 coreid, u32 qid, u32 *data, 13530 size_t n) 13531 { 13532 unsigned int cim_num_obq = adap->chip_params->cim_num_obq; 13533 u16 i, addr, nwords; 13534 int ret; 13535 13536 if ((qid > (cim_num_obq - 1)) || (n & 3)) 13537 return -EINVAL; 13538 13539 t4_read_cimq_cfg_obq_core(adap, coreid, qid, &addr, &nwords); 13540 addr >>= sizeof(u16); 13541 nwords >>= sizeof(u16); 13542 if (n > nwords) 13543 n = nwords; 13544 13545 for (i = 0; i < n; i++, addr++, data++) { 13546 ret = t4_read_cim_obq_data_core(adap, coreid, addr, data); 13547 if (ret < 0) 13548 return ret; 13549 } 13550 13551 t4_write_reg(adap, A_CIM_OBQ_DBG_CFG, 0); 13552 return i; 13553 } 13554 13555 /** 13556 * t4_cim_read_core - read a block from CIM internal address space 13557 * of a control register group on specific core. 13558 * @adap: the adapter 13559 * @group: the control register group to select for read 13560 * @coreid: the uP coreid 13561 * @addr: the start address within the CIM address space 13562 * @n: number of words to read 13563 * @valp: where to store the result 13564 * 13565 * Reads a block of 4-byte words from the CIM intenal address space 13566 * of a control register @group on a specific @coreid. 13567 */ 13568 int t4_cim_read_core(struct adapter *adap, u8 group, u8 coreid, 13569 unsigned int addr, unsigned int n, 13570 unsigned int *valp) 13571 { 13572 unsigned int hostbusy, v = 0; 13573 int ret = 0; 13574 13575 if (chip_id(adap) > CHELSIO_T6) { 13576 hostbusy = F_T7_HOSTBUSY; 13577 v = V_HOSTGRPSEL(group) | V_HOSTCORESEL(coreid); 13578 } else { 13579 hostbusy = F_HOSTBUSY; 13580 } 13581 13582 if (t4_read_reg(adap, A_CIM_HOST_ACC_CTRL) & hostbusy) 13583 return -EBUSY; 13584 13585 for ( ; !ret && n--; addr += 4) { 13586 t4_write_reg(adap, A_CIM_HOST_ACC_CTRL, addr | v); 13587 ret = t4_wait_op_done(adap, A_CIM_HOST_ACC_CTRL, hostbusy, 13588 0, 5, 2); 13589 if (!ret) 13590 *valp++ = t4_read_reg(adap, A_CIM_HOST_ACC_DATA); 13591 } 13592 13593 return ret; 13594 } 13595 13596 /** 13597 * t4_cim_write_core - write a block into CIM internal address space 13598 * of a control register group on specific core. 13599 * @adap: the adapter 13600 * @group: the control register group to select for write 13601 * @coreid: the uP coreid 13602 * @addr: the start address within the CIM address space 13603 * @n: number of words to write 13604 * @valp: set of values to write 13605 * 13606 * Writes a block of 4-byte words into the CIM intenal address space 13607 * of a control register @group on a specific @coreid. 13608 */ 13609 int t4_cim_write_core(struct adapter *adap, u8 group, u8 coreid, 13610 unsigned int addr, unsigned int n, 13611 const unsigned int *valp) 13612 { 13613 unsigned int hostbusy, v; 13614 int ret = 0; 13615 13616 if (chip_id(adap) > CHELSIO_T6) { 13617 hostbusy = F_T7_HOSTBUSY; 13618 v = F_T7_HOSTWRITE | V_HOSTGRPSEL(group) | 13619 V_HOSTCORESEL(coreid); 13620 } else { 13621 hostbusy = F_HOSTBUSY; 13622 v = F_HOSTWRITE; 13623 } 13624 13625 if (t4_read_reg(adap, A_CIM_HOST_ACC_CTRL) & hostbusy) 13626 return -EBUSY; 13627 13628 for ( ; !ret && n--; addr += 4) { 13629 t4_write_reg(adap, A_CIM_HOST_ACC_DATA, *valp++); 13630 t4_write_reg(adap, A_CIM_HOST_ACC_CTRL, addr | v); 13631 ret = t4_wait_op_done(adap, A_CIM_HOST_ACC_CTRL, hostbusy, 13632 0, 5, 2); 13633 } 13634 13635 return ret; 13636 } 13637 13638 /** 13639 * t4_cim_read_la_core - read CIM LA capture buffer on specific core 13640 * @adap: the adapter 13641 * @coreid: uP coreid 13642 * @la_buf: where to store the LA data 13643 * @wrptr: the HW write pointer within the capture buffer 13644 * 13645 * Reads the contents of the CIM LA buffer on a specific @coreid 13646 * with the most recent entry at the end of the returned data 13647 * and with the entry at @wrptr first. We try to leave the LA 13648 * in the running state we find it in. 13649 */ 13650 int t4_cim_read_la_core(struct adapter *adap, u8 coreid, u32 *la_buf, 13651 u32 *wrptr) 13652 { 13653 unsigned int cfg, val, idx; 13654 int i, ret; 13655 13656 ret = t4_cim_read_core(adap, 1, coreid, A_UP_UP_DBG_LA_CFG, 1, &cfg); 13657 if (ret) 13658 return ret; 13659 13660 if (cfg & F_UPDBGLAEN) { /* LA is running, freeze it */ 13661 val = 0; 13662 ret = t4_cim_write_core(adap, 1, coreid, A_UP_UP_DBG_LA_CFG, 1, 13663 &val); 13664 if (ret) 13665 return ret; 13666 } 13667 13668 ret = t4_cim_read_core(adap, 1, coreid, A_UP_UP_DBG_LA_CFG, 1, &val); 13669 if (ret) 13670 goto restart; 13671 13672 idx = G_UPDBGLAWRPTR(val); 13673 if (wrptr) 13674 *wrptr = idx; 13675 13676 for (i = 0; i < adap->params.cim_la_size; i++) { 13677 val = V_UPDBGLARDPTR(idx) | F_UPDBGLARDEN; 13678 ret = t4_cim_write_core(adap, 1, coreid, A_UP_UP_DBG_LA_CFG, 1, 13679 &val); 13680 if (ret) 13681 break; 13682 ret = t4_cim_read_core(adap, 1, coreid, A_UP_UP_DBG_LA_CFG, 1, 13683 &val); 13684 if (ret) 13685 break; 13686 if (val & F_UPDBGLARDEN) { 13687 ret = -ETIMEDOUT; 13688 break; 13689 } 13690 ret = t4_cim_read_core(adap, 1, coreid, A_UP_UP_DBG_LA_DATA, 1, 13691 &la_buf[i]); 13692 if (ret) 13693 break; 13694 13695 /* Bits 0-3 of UpDbgLaRdPtr can be between 0000 to 1001 to 13696 * identify the 32-bit portion of the full 312-bit data 13697 */ 13698 if ((chip_id(adap) > CHELSIO_T5) && (idx & 0xf) >= 9) 13699 idx = (idx & 0xff0) + 0x10; 13700 else 13701 idx++; 13702 /* address can't exceed 0xfff */ 13703 idx &= M_UPDBGLARDPTR; 13704 } 13705 restart: 13706 if (cfg & F_UPDBGLAEN) { 13707 int r; 13708 13709 val = cfg & ~F_UPDBGLARDEN; 13710 r = t4_cim_write_core(adap, 1, coreid, A_UP_UP_DBG_LA_CFG, 1, 13711 &val); 13712 if (!ret) 13713 ret = r; 13714 } 13715 13716 return ret; 13717 } 13718 13719 /** 13720 * t4_tp_read_la - read TP LA capture buffer 13721 * @adap: the adapter 13722 * @la_buf: where to store the LA data 13723 * @wrptr: the HW write pointer within the capture buffer 13724 * 13725 * Reads the contents of the TP LA buffer with the most recent entry at 13726 * the end of the returned data and with the entry at @wrptr first. 13727 * We leave the LA in the running state we find it in. 13728 */ 13729 void t4_tp_read_la(struct adapter *adap, u64 *la_buf, unsigned int *wrptr) 13730 { 13731 bool last_incomplete; 13732 unsigned int i, cfg, val, idx; 13733 13734 cfg = t4_read_reg(adap, A_TP_DBG_LA_CONFIG) & 0xffff; 13735 if (cfg & F_DBGLAENABLE) /* freeze LA */ 13736 t4_write_reg(adap, A_TP_DBG_LA_CONFIG, 13737 adap->params.tp.la_mask | (cfg ^ F_DBGLAENABLE)); 13738 13739 val = t4_read_reg(adap, A_TP_DBG_LA_CONFIG); 13740 idx = G_DBGLAWPTR(val); 13741 last_incomplete = G_DBGLAMODE(val) >= 2 && (val & F_DBGLAWHLF) == 0; 13742 if (last_incomplete) 13743 idx = (idx + 1) & M_DBGLARPTR; 13744 if (wrptr) 13745 *wrptr = idx; 13746 13747 val &= 0xffff; 13748 val &= ~V_DBGLARPTR(M_DBGLARPTR); 13749 val |= adap->params.tp.la_mask; 13750 13751 for (i = 0; i < TPLA_SIZE; i++) { 13752 t4_write_reg(adap, A_TP_DBG_LA_CONFIG, V_DBGLARPTR(idx) | val); 13753 la_buf[i] = t4_read_reg64(adap, A_TP_DBG_LA_DATAL); 13754 idx = (idx + 1) & M_DBGLARPTR; 13755 } 13756 13757 /* Wipe out last entry if it isn't valid */ 13758 if (last_incomplete) 13759 la_buf[TPLA_SIZE - 1] = ~0ULL; 13760 13761 if (cfg & F_DBGLAENABLE) /* restore running state */ 13762 t4_write_reg(adap, A_TP_DBG_LA_CONFIG, 13763 cfg | adap->params.tp.la_mask); 13764 } 13765 13766 /* 13767 * SGE Hung Ingress DMA Warning Threshold time and Warning Repeat Rate (in 13768 * seconds). If we find one of the SGE Ingress DMA State Machines in the same 13769 * state for more than the Warning Threshold then we'll issue a warning about 13770 * a potential hang. We'll repeat the warning as the SGE Ingress DMA Channel 13771 * appears to be hung every Warning Repeat second till the situation clears. 13772 * If the situation clears, we'll note that as well. 13773 */ 13774 #define SGE_IDMA_WARN_THRESH 1 13775 #define SGE_IDMA_WARN_REPEAT 300 13776 13777 /** 13778 * t4_idma_monitor_init - initialize SGE Ingress DMA Monitor 13779 * @adapter: the adapter 13780 * @idma: the adapter IDMA Monitor state 13781 * 13782 * Initialize the state of an SGE Ingress DMA Monitor. 13783 */ 13784 void t4_idma_monitor_init(struct adapter *adapter, 13785 struct sge_idma_monitor_state *idma) 13786 { 13787 /* Initialize the state variables for detecting an SGE Ingress DMA 13788 * hang. The SGE has internal counters which count up on each clock 13789 * tick whenever the SGE finds its Ingress DMA State Engines in the 13790 * same state they were on the previous clock tick. The clock used is 13791 * the Core Clock so we have a limit on the maximum "time" they can 13792 * record; typically a very small number of seconds. For instance, 13793 * with a 600MHz Core Clock, we can only count up to a bit more than 13794 * 7s. So we'll synthesize a larger counter in order to not run the 13795 * risk of having the "timers" overflow and give us the flexibility to 13796 * maintain a Hung SGE State Machine of our own which operates across 13797 * a longer time frame. 13798 */ 13799 idma->idma_1s_thresh = core_ticks_per_usec(adapter) * 1000000; /* 1s */ 13800 idma->idma_stalled[0] = idma->idma_stalled[1] = 0; 13801 } 13802 13803 /** 13804 * t4_idma_monitor - monitor SGE Ingress DMA state 13805 * @adapter: the adapter 13806 * @idma: the adapter IDMA Monitor state 13807 * @hz: number of ticks/second 13808 * @ticks: number of ticks since the last IDMA Monitor call 13809 */ 13810 void t4_idma_monitor(struct adapter *adapter, 13811 struct sge_idma_monitor_state *idma, 13812 int hz, int ticks) 13813 { 13814 int i, idma_same_state_cnt[2]; 13815 13816 /* Read the SGE Debug Ingress DMA Same State Count registers. These 13817 * are counters inside the SGE which count up on each clock when the 13818 * SGE finds its Ingress DMA State Engines in the same states they 13819 * were in the previous clock. The counters will peg out at 13820 * 0xffffffff without wrapping around so once they pass the 1s 13821 * threshold they'll stay above that till the IDMA state changes. 13822 */ 13823 t4_write_reg(adapter, A_SGE_DEBUG_INDEX, 13); 13824 idma_same_state_cnt[0] = t4_read_reg(adapter, A_SGE_DEBUG_DATA_HIGH); 13825 idma_same_state_cnt[1] = t4_read_reg(adapter, A_SGE_DEBUG_DATA_LOW); 13826 13827 for (i = 0; i < 2; i++) { 13828 u32 debug0, debug11; 13829 13830 /* If the Ingress DMA Same State Counter ("timer") is less 13831 * than 1s, then we can reset our synthesized Stall Timer and 13832 * continue. If we have previously emitted warnings about a 13833 * potential stalled Ingress Queue, issue a note indicating 13834 * that the Ingress Queue has resumed forward progress. 13835 */ 13836 if (idma_same_state_cnt[i] < idma->idma_1s_thresh) { 13837 if (idma->idma_stalled[i] >= SGE_IDMA_WARN_THRESH*hz) 13838 CH_WARN(adapter, "SGE idma%d, queue %u, " 13839 "resumed after %d seconds\n", 13840 i, idma->idma_qid[i], 13841 idma->idma_stalled[i]/hz); 13842 idma->idma_stalled[i] = 0; 13843 continue; 13844 } 13845 13846 /* Synthesize an SGE Ingress DMA Same State Timer in the Hz 13847 * domain. The first time we get here it'll be because we 13848 * passed the 1s Threshold; each additional time it'll be 13849 * because the RX Timer Callback is being fired on its regular 13850 * schedule. 13851 * 13852 * If the stall is below our Potential Hung Ingress Queue 13853 * Warning Threshold, continue. 13854 */ 13855 if (idma->idma_stalled[i] == 0) { 13856 idma->idma_stalled[i] = hz; 13857 idma->idma_warn[i] = 0; 13858 } else { 13859 idma->idma_stalled[i] += ticks; 13860 idma->idma_warn[i] -= ticks; 13861 } 13862 13863 if (idma->idma_stalled[i] < SGE_IDMA_WARN_THRESH*hz) 13864 continue; 13865 13866 /* We'll issue a warning every SGE_IDMA_WARN_REPEAT seconds. 13867 */ 13868 if (idma->idma_warn[i] > 0) 13869 continue; 13870 idma->idma_warn[i] = SGE_IDMA_WARN_REPEAT*hz; 13871 13872 /* Read and save the SGE IDMA State and Queue ID information. 13873 * We do this every time in case it changes across time ... 13874 * can't be too careful ... 13875 */ 13876 t4_write_reg(adapter, A_SGE_DEBUG_INDEX, 0); 13877 debug0 = t4_read_reg(adapter, A_SGE_DEBUG_DATA_LOW); 13878 idma->idma_state[i] = (debug0 >> (i * 9)) & 0x3f; 13879 13880 t4_write_reg(adapter, A_SGE_DEBUG_INDEX, 11); 13881 debug11 = t4_read_reg(adapter, A_SGE_DEBUG_DATA_LOW); 13882 idma->idma_qid[i] = (debug11 >> (i * 16)) & 0xffff; 13883 13884 CH_WARN(adapter, "SGE idma%u, queue %u, potentially stuck in " 13885 " state %u for %d seconds (debug0=%#x, debug11=%#x)\n", 13886 i, idma->idma_qid[i], idma->idma_state[i], 13887 idma->idma_stalled[i]/hz, 13888 debug0, debug11); 13889 t4_sge_decode_idma_state(adapter, idma->idma_state[i]); 13890 } 13891 } 13892 13893 /** 13894 * t4_set_vf_mac - Set MAC address for the specified VF 13895 * @adapter: The adapter 13896 * @pf: the PF used to instantiate the VFs 13897 * @vf: one of the VFs instantiated by the specified PF 13898 * @naddr: the number of MAC addresses 13899 * @addr: the MAC address(es) to be set to the specified VF 13900 */ 13901 int t4_set_vf_mac(struct adapter *adapter, unsigned int pf, unsigned int vf, 13902 unsigned int naddr, u8 *addr) 13903 { 13904 struct fw_acl_mac_cmd cmd; 13905 13906 memset(&cmd, 0, sizeof(cmd)); 13907 cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_ACL_MAC_CMD) | 13908 F_FW_CMD_REQUEST | 13909 F_FW_CMD_WRITE | 13910 V_FW_ACL_MAC_CMD_PFN(pf) | 13911 V_FW_ACL_MAC_CMD_VFN(vf)); 13912 13913 /* Note: Do not enable the ACL */ 13914 cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd)); 13915 cmd.nmac = naddr; 13916 13917 switch (pf) { 13918 case 3: 13919 memcpy(cmd.macaddr3, addr, sizeof(cmd.macaddr3)); 13920 break; 13921 case 2: 13922 memcpy(cmd.macaddr2, addr, sizeof(cmd.macaddr2)); 13923 break; 13924 case 1: 13925 memcpy(cmd.macaddr1, addr, sizeof(cmd.macaddr1)); 13926 break; 13927 case 0: 13928 memcpy(cmd.macaddr0, addr, sizeof(cmd.macaddr0)); 13929 break; 13930 } 13931 13932 return t4_wr_mbox(adapter, adapter->mbox, &cmd, sizeof(cmd), &cmd); 13933 } 13934 13935 /** 13936 * t4_read_pace_tbl - read the pace table 13937 * @adap: the adapter 13938 * @pace_vals: holds the returned values 13939 * 13940 * Returns the values of TP's pace table in microseconds. 13941 */ 13942 void t4_read_pace_tbl(struct adapter *adap, unsigned int pace_vals[NTX_SCHED]) 13943 { 13944 unsigned int i, v; 13945 13946 for (i = 0; i < NTX_SCHED; i++) { 13947 t4_write_reg(adap, A_TP_PACE_TABLE, 0xffff0000 + i); 13948 v = t4_read_reg(adap, A_TP_PACE_TABLE); 13949 pace_vals[i] = dack_ticks_to_usec(adap, v); 13950 } 13951 } 13952 13953 /** 13954 * t4_get_tx_sched - get the configuration of a Tx HW traffic scheduler 13955 * @adap: the adapter 13956 * @sched: the scheduler index 13957 * @kbps: the byte rate in Kbps 13958 * @ipg: the interpacket delay in tenths of nanoseconds 13959 * 13960 * Return the current configuration of a HW Tx scheduler. 13961 */ 13962 void t4_get_tx_sched(struct adapter *adap, unsigned int sched, unsigned int *kbps, 13963 unsigned int *ipg, bool sleep_ok) 13964 { 13965 unsigned int v, addr, bpt, cpt; 13966 13967 if (kbps) { 13968 addr = A_TP_TX_MOD_Q1_Q0_RATE_LIMIT - sched / 2; 13969 t4_tp_tm_pio_read(adap, &v, 1, addr, sleep_ok); 13970 if (sched & 1) 13971 v >>= 16; 13972 bpt = (v >> 8) & 0xff; 13973 cpt = v & 0xff; 13974 if (!cpt) 13975 *kbps = 0; /* scheduler disabled */ 13976 else { 13977 v = (adap->params.vpd.cclk * 1000) / cpt; /* ticks/s */ 13978 *kbps = (v * bpt) / 125; 13979 } 13980 } 13981 if (ipg) { 13982 addr = A_TP_TX_MOD_Q1_Q0_TIMER_SEPARATOR - sched / 2; 13983 t4_tp_tm_pio_read(adap, &v, 1, addr, sleep_ok); 13984 if (sched & 1) 13985 v >>= 16; 13986 v &= 0xffff; 13987 *ipg = (10000 * v) / core_ticks_per_usec(adap); 13988 } 13989 } 13990 13991 /** 13992 * t4_load_cfg - download config file 13993 * @adap: the adapter 13994 * @cfg_data: the cfg text file to write 13995 * @size: text file size 13996 * 13997 * Write the supplied config text file to the card's serial flash. 13998 */ 13999 int t4_load_cfg(struct adapter *adap, const u8 *cfg_data, unsigned int size) 14000 { 14001 int ret, i, n, cfg_addr; 14002 unsigned int addr, len; 14003 unsigned int flash_cfg_start_sec; 14004 14005 cfg_addr = t4_flash_cfg_addr(adap, &len); 14006 if (cfg_addr < 0) 14007 return cfg_addr; 14008 14009 if (size > len) { 14010 CH_ERR(adap, "cfg file too large, max is %u bytes\n", len); 14011 return -EFBIG; 14012 } 14013 14014 flash_cfg_start_sec = cfg_addr / SF_SEC_SIZE; 14015 i = DIV_ROUND_UP(len, SF_SEC_SIZE); 14016 ret = t4_flash_erase_sectors(adap, flash_cfg_start_sec, 14017 flash_cfg_start_sec + i - 1); 14018 /* 14019 * If size == 0 then we're simply erasing the FLASH sectors associated 14020 * with the on-adapter Firmware Configuration File. 14021 */ 14022 if (ret || size == 0) 14023 goto out; 14024 14025 /* this will write to the flash up to SF_PAGE_SIZE at a time */ 14026 addr = cfg_addr; 14027 for (i = 0; i < size; i += SF_PAGE_SIZE) { 14028 n = min(size - i, SF_PAGE_SIZE); 14029 ret = t4_write_flash(adap, addr, n, cfg_data, 1); 14030 if (ret) 14031 goto out; 14032 addr += SF_PAGE_SIZE; 14033 cfg_data += SF_PAGE_SIZE; 14034 } 14035 14036 out: 14037 if (ret) 14038 CH_ERR(adap, "config file %s failed %d\n", 14039 (size == 0 ? "clear" : "download"), ret); 14040 return ret; 14041 } 14042 14043 /** 14044 * t5_fw_init_extern_mem - initialize the external memory 14045 * @adap: the adapter 14046 * 14047 * Initializes the external memory on T5. 14048 */ 14049 int t5_fw_init_extern_mem(struct adapter *adap) 14050 { 14051 u32 params[1], val[1]; 14052 int ret; 14053 14054 if (!is_t5(adap)) 14055 return 0; 14056 14057 val[0] = 0xff; /* Initialize all MCs */ 14058 params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | 14059 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_MCINIT)); 14060 ret = t4_set_params_timeout(adap, adap->mbox, adap->pf, 0, 1, params, val, 14061 FW_CMD_MAX_TIMEOUT); 14062 14063 return ret; 14064 } 14065 14066 /* BIOS boot headers */ 14067 typedef struct pci_expansion_rom_header { 14068 u8 signature[2]; /* ROM Signature. Should be 0xaa55 */ 14069 u8 reserved[22]; /* Reserved per processor Architecture data */ 14070 u8 pcir_offset[2]; /* Offset to PCI Data Structure */ 14071 } pci_exp_rom_header_t; /* PCI_EXPANSION_ROM_HEADER */ 14072 14073 /* Legacy PCI Expansion ROM Header */ 14074 typedef struct legacy_pci_expansion_rom_header { 14075 u8 signature[2]; /* ROM Signature. Should be 0xaa55 */ 14076 u8 size512; /* Current Image Size in units of 512 bytes */ 14077 u8 initentry_point[4]; 14078 u8 cksum; /* Checksum computed on the entire Image */ 14079 u8 reserved[16]; /* Reserved */ 14080 u8 pcir_offset[2]; /* Offset to PCI Data Struture */ 14081 } legacy_pci_exp_rom_header_t; /* LEGACY_PCI_EXPANSION_ROM_HEADER */ 14082 14083 /* EFI PCI Expansion ROM Header */ 14084 typedef struct efi_pci_expansion_rom_header { 14085 u8 signature[2]; // ROM signature. The value 0xaa55 14086 u8 initialization_size[2]; /* Units 512. Includes this header */ 14087 u8 efi_signature[4]; /* Signature from EFI image header. 0x0EF1 */ 14088 u8 efi_subsystem[2]; /* Subsystem value for EFI image header */ 14089 u8 efi_machine_type[2]; /* Machine type from EFI image header */ 14090 u8 compression_type[2]; /* Compression type. */ 14091 /* 14092 * Compression type definition 14093 * 0x0: uncompressed 14094 * 0x1: Compressed 14095 * 0x2-0xFFFF: Reserved 14096 */ 14097 u8 reserved[8]; /* Reserved */ 14098 u8 efi_image_header_offset[2]; /* Offset to EFI Image */ 14099 u8 pcir_offset[2]; /* Offset to PCI Data Structure */ 14100 } efi_pci_exp_rom_header_t; /* EFI PCI Expansion ROM Header */ 14101 14102 /* PCI Data Structure Format */ 14103 typedef struct pcir_data_structure { /* PCI Data Structure */ 14104 u8 signature[4]; /* Signature. The string "PCIR" */ 14105 u8 vendor_id[2]; /* Vendor Identification */ 14106 u8 device_id[2]; /* Device Identification */ 14107 u8 vital_product[2]; /* Pointer to Vital Product Data */ 14108 u8 length[2]; /* PCIR Data Structure Length */ 14109 u8 revision; /* PCIR Data Structure Revision */ 14110 u8 class_code[3]; /* Class Code */ 14111 u8 image_length[2]; /* Image Length. Multiple of 512B */ 14112 u8 code_revision[2]; /* Revision Level of Code/Data */ 14113 u8 code_type; /* Code Type. */ 14114 /* 14115 * PCI Expansion ROM Code Types 14116 * 0x00: Intel IA-32, PC-AT compatible. Legacy 14117 * 0x01: Open Firmware standard for PCI. FCODE 14118 * 0x02: Hewlett-Packard PA RISC. HP reserved 14119 * 0x03: EFI Image. EFI 14120 * 0x04-0xFF: Reserved. 14121 */ 14122 u8 indicator; /* Indicator. Identifies the last image in the ROM */ 14123 u8 reserved[2]; /* Reserved */ 14124 } pcir_data_t; /* PCI__DATA_STRUCTURE */ 14125 14126 /* BOOT constants */ 14127 enum { 14128 BOOT_FLASH_BOOT_ADDR = 0x0,/* start address of boot image in flash */ 14129 BOOT_SIGNATURE = 0xaa55, /* signature of BIOS boot ROM */ 14130 BOOT_SIZE_INC = 512, /* image size measured in 512B chunks */ 14131 BOOT_MIN_SIZE = sizeof(pci_exp_rom_header_t), /* basic header */ 14132 BOOT_MAX_SIZE = 1024*BOOT_SIZE_INC, /* 1 byte * length increment */ 14133 VENDOR_ID = 0x1425, /* Vendor ID */ 14134 PCIR_SIGNATURE = 0x52494350 /* PCIR signature */ 14135 }; 14136 14137 /* 14138 * modify_device_id - Modifies the device ID of the Boot BIOS image 14139 * @adatper: the device ID to write. 14140 * @boot_data: the boot image to modify. 14141 * 14142 * Write the supplied device ID to the boot BIOS image. 14143 */ 14144 static void modify_device_id(int device_id, u8 *boot_data) 14145 { 14146 legacy_pci_exp_rom_header_t *header; 14147 pcir_data_t *pcir_header; 14148 u32 cur_header = 0; 14149 14150 /* 14151 * Loop through all chained images and change the device ID's 14152 */ 14153 while (1) { 14154 header = (legacy_pci_exp_rom_header_t *) &boot_data[cur_header]; 14155 pcir_header = (pcir_data_t *) &boot_data[cur_header + 14156 le16_to_cpu(*(u16*)header->pcir_offset)]; 14157 14158 /* 14159 * Only modify the Device ID if code type is Legacy or HP. 14160 * 0x00: Okay to modify 14161 * 0x01: FCODE. Do not be modify 14162 * 0x03: Okay to modify 14163 * 0x04-0xFF: Do not modify 14164 */ 14165 if (pcir_header->code_type == 0x00) { 14166 u8 csum = 0; 14167 int i; 14168 14169 /* 14170 * Modify Device ID to match current adatper 14171 */ 14172 *(u16*) pcir_header->device_id = device_id; 14173 14174 /* 14175 * Set checksum temporarily to 0. 14176 * We will recalculate it later. 14177 */ 14178 header->cksum = 0x0; 14179 14180 /* 14181 * Calculate and update checksum 14182 */ 14183 for (i = 0; i < (header->size512 * 512); i++) 14184 csum += (u8)boot_data[cur_header + i]; 14185 14186 /* 14187 * Invert summed value to create the checksum 14188 * Writing new checksum value directly to the boot data 14189 */ 14190 boot_data[cur_header + 7] = -csum; 14191 14192 } else if (pcir_header->code_type == 0x03) { 14193 14194 /* 14195 * Modify Device ID to match current adatper 14196 */ 14197 *(u16*) pcir_header->device_id = device_id; 14198 14199 } 14200 14201 14202 /* 14203 * Check indicator element to identify if this is the last 14204 * image in the ROM. 14205 */ 14206 if (pcir_header->indicator & 0x80) 14207 break; 14208 14209 /* 14210 * Move header pointer up to the next image in the ROM. 14211 */ 14212 cur_header += header->size512 * 512; 14213 } 14214 } 14215 14216 /* 14217 * t4_load_boot - download boot flash 14218 * @adapter: the adapter 14219 * @boot_data: the boot image to write 14220 * @boot_addr: offset in flash to write boot_data 14221 * @size: image size 14222 * 14223 * Write the supplied boot image to the card's serial flash. 14224 * The boot image has the following sections: a 28-byte header and the 14225 * boot image. 14226 */ 14227 int t4_load_boot(struct adapter *adap, u8 *boot_data, 14228 unsigned int boot_addr, unsigned int size) 14229 { 14230 pci_exp_rom_header_t *header; 14231 int pcir_offset ; 14232 pcir_data_t *pcir_header; 14233 int ret, addr; 14234 uint16_t device_id; 14235 unsigned int i, start, len; 14236 unsigned int boot_sector = boot_addr * 1024; 14237 14238 /* 14239 * Make sure the boot image does not exceed its available space. 14240 */ 14241 len = 0; 14242 start = t4_flash_loc_start(adap, FLASH_LOC_BOOT_AREA, &len); 14243 if (boot_sector + size > start + len) { 14244 CH_ERR(adap, "boot data is larger than available BOOT area\n"); 14245 return -EFBIG; 14246 } 14247 14248 /* 14249 * The boot sector is comprised of the Expansion-ROM boot, iSCSI boot, 14250 * and Boot configuration data sections. These 3 boot sections span 14251 * the entire FLASH_LOC_BOOT_AREA. 14252 */ 14253 i = DIV_ROUND_UP(size ? size : len, SF_SEC_SIZE); 14254 ret = t4_flash_erase_sectors(adap, boot_sector >> 16, 14255 (boot_sector >> 16) + i - 1); 14256 14257 /* 14258 * If size == 0 then we're simply erasing the FLASH sectors associated 14259 * with the on-adapter option ROM file 14260 */ 14261 if (ret || (size == 0)) 14262 goto out; 14263 14264 /* Get boot header */ 14265 header = (pci_exp_rom_header_t *)boot_data; 14266 pcir_offset = le16_to_cpu(*(u16 *)header->pcir_offset); 14267 /* PCIR Data Structure */ 14268 pcir_header = (pcir_data_t *) &boot_data[pcir_offset]; 14269 14270 /* 14271 * Perform some primitive sanity testing to avoid accidentally 14272 * writing garbage over the boot sectors. We ought to check for 14273 * more but it's not worth it for now ... 14274 */ 14275 if (size < BOOT_MIN_SIZE || size > BOOT_MAX_SIZE) { 14276 CH_ERR(adap, "boot image too small/large\n"); 14277 return -EFBIG; 14278 } 14279 14280 #ifndef CHELSIO_T4_DIAGS 14281 /* 14282 * Check BOOT ROM header signature 14283 */ 14284 if (le16_to_cpu(*(u16*)header->signature) != BOOT_SIGNATURE ) { 14285 CH_ERR(adap, "Boot image missing signature\n"); 14286 return -EINVAL; 14287 } 14288 14289 /* 14290 * Check PCI header signature 14291 */ 14292 if (le32_to_cpu(*(u32*)pcir_header->signature) != PCIR_SIGNATURE) { 14293 CH_ERR(adap, "PCI header missing signature\n"); 14294 return -EINVAL; 14295 } 14296 14297 /* 14298 * Check Vendor ID matches Chelsio ID 14299 */ 14300 if (le16_to_cpu(*(u16*)pcir_header->vendor_id) != VENDOR_ID) { 14301 CH_ERR(adap, "Vendor ID missing signature\n"); 14302 return -EINVAL; 14303 } 14304 #endif 14305 14306 /* 14307 * Retrieve adapter's device ID 14308 */ 14309 t4_os_pci_read_cfg2(adap, PCI_DEVICE_ID, &device_id); 14310 /* Want to deal with PF 0 so I strip off PF 4 indicator */ 14311 device_id = device_id & 0xf0ff; 14312 14313 /* 14314 * Check PCIE Device ID 14315 */ 14316 if (le16_to_cpu(*(u16*)pcir_header->device_id) != device_id) { 14317 /* 14318 * Change the device ID in the Boot BIOS image to match 14319 * the Device ID of the current adapter. 14320 */ 14321 modify_device_id(device_id, boot_data); 14322 } 14323 14324 /* 14325 * Skip over the first SF_PAGE_SIZE worth of data and write it after 14326 * we finish copying the rest of the boot image. This will ensure 14327 * that the BIOS boot header will only be written if the boot image 14328 * was written in full. 14329 */ 14330 addr = boot_sector; 14331 for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) { 14332 addr += SF_PAGE_SIZE; 14333 boot_data += SF_PAGE_SIZE; 14334 ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, boot_data, 0); 14335 if (ret) 14336 goto out; 14337 } 14338 14339 ret = t4_write_flash(adap, boot_sector, SF_PAGE_SIZE, 14340 (const u8 *)header, 0); 14341 14342 out: 14343 if (ret) 14344 CH_ERR(adap, "boot image download failed, error %d\n", ret); 14345 return ret; 14346 } 14347 14348 /* 14349 * t4_flash_bootcfg_addr - return the address of the flash optionrom configuration 14350 * @adapter: the adapter 14351 * 14352 * Return the address within the flash where the OptionROM Configuration 14353 * is stored, or an error if the device FLASH is too small to contain 14354 * a OptionROM Configuration. 14355 */ 14356 static int t4_flash_bootcfg_addr(struct adapter *adapter, unsigned int *lenp) 14357 { 14358 unsigned int len = 0; 14359 const int start = t4_flash_loc_start(adapter, FLASH_LOC_BOOTCFG, &len); 14360 14361 /* 14362 * If the device FLASH isn't large enough to hold a Firmware 14363 * Configuration File, return an error. 14364 */ 14365 if (adapter->params.sf_size < start + len) 14366 return -ENOSPC; 14367 if (lenp != NULL) 14368 *lenp = len; 14369 return (start); 14370 } 14371 14372 int t4_load_bootcfg(struct adapter *adap,const u8 *cfg_data, unsigned int size) 14373 { 14374 int ret, i, n, cfg_addr; 14375 unsigned int addr, len; 14376 unsigned int flash_cfg_start_sec; 14377 14378 cfg_addr = t4_flash_bootcfg_addr(adap, &len); 14379 if (cfg_addr < 0) 14380 return cfg_addr; 14381 14382 if (size > len) { 14383 CH_ERR(adap, "bootcfg file too large, max is %u bytes\n", len); 14384 return -EFBIG; 14385 } 14386 14387 flash_cfg_start_sec = cfg_addr / SF_SEC_SIZE; 14388 i = DIV_ROUND_UP(len, SF_SEC_SIZE); 14389 ret = t4_flash_erase_sectors(adap, flash_cfg_start_sec, 14390 flash_cfg_start_sec + i - 1); 14391 14392 /* 14393 * If size == 0 then we're simply erasing the FLASH sectors associated 14394 * with the on-adapter OptionROM Configuration File. 14395 */ 14396 if (ret || size == 0) 14397 goto out; 14398 14399 /* this will write to the flash up to SF_PAGE_SIZE at a time */ 14400 addr = cfg_addr; 14401 for (i = 0; i < size; i += SF_PAGE_SIZE) { 14402 n = min(size - i, SF_PAGE_SIZE); 14403 ret = t4_write_flash(adap, addr, n, cfg_data, 0); 14404 if (ret) 14405 goto out; 14406 addr += SF_PAGE_SIZE; 14407 cfg_data += SF_PAGE_SIZE; 14408 } 14409 14410 out: 14411 if (ret) 14412 CH_ERR(adap, "boot config data %s failed %d\n", 14413 (size == 0 ? "clear" : "download"), ret); 14414 return ret; 14415 } 14416 14417 /** 14418 * t4_set_filter_cfg - set up filter mode/mask and ingress config. 14419 * @adap: the adapter 14420 * @mode: a bitmap selecting which optional filter components to enable 14421 * @mask: a bitmap selecting which components to enable in filter mask 14422 * @vnic_mode: the ingress config/vnic mode setting 14423 * 14424 * Sets the filter mode and mask by selecting the optional components to 14425 * enable in filter tuples. Returns 0 on success and a negative error if 14426 * the requested mode needs more bits than are available for optional 14427 * components. The filter mask must be a subset of the filter mode. 14428 */ 14429 int t4_set_filter_cfg(struct adapter *adap, int mode, int mask, int vnic_mode) 14430 { 14431 int i, nbits, rc; 14432 uint32_t param, val; 14433 uint16_t fmode, fmask; 14434 const int maxbits = adap->chip_params->filter_opt_len; 14435 const int nopt = adap->chip_params->filter_num_opt; 14436 int width; 14437 14438 if (mode != -1 || mask != -1) { 14439 if (mode != -1) { 14440 fmode = mode; 14441 nbits = 0; 14442 for (i = 0; i < nopt; i++) { 14443 if (fmode & (1 << i)) 14444 nbits += t4_filter_field_width(adap, i); 14445 } 14446 if (nbits > maxbits) { 14447 CH_ERR(adap, "optional fields in the filter " 14448 "mode (0x%x) add up to %d bits " 14449 "(must be <= %db). Remove some fields and " 14450 "try again.\n", fmode, nbits, maxbits); 14451 return -E2BIG; 14452 } 14453 14454 /* 14455 * Hardware < T7 wants the bits to be maxed out. Keep 14456 * setting them until there's no room for more. 14457 */ 14458 if (chip_id(adap) < CHELSIO_T7) { 14459 for (i = 0; i < nopt; i++) { 14460 if (fmode & (1 << i)) 14461 continue; 14462 width = t4_filter_field_width(adap, i); 14463 if (nbits + width <= maxbits) { 14464 fmode |= 1 << i; 14465 nbits += width; 14466 if (nbits == maxbits) 14467 break; 14468 } 14469 } 14470 } 14471 14472 fmask = fmode & adap->params.tp.filter_mask; 14473 if (fmask != adap->params.tp.filter_mask) { 14474 CH_WARN(adap, 14475 "filter mask will be changed from 0x%x to " 14476 "0x%x to comply with the filter mode (0x%x).\n", 14477 adap->params.tp.filter_mask, fmask, fmode); 14478 } 14479 } else { 14480 fmode = adap->params.tp.filter_mode; 14481 fmask = mask; 14482 if ((fmode | fmask) != fmode) { 14483 CH_ERR(adap, 14484 "filter mask (0x%x) must be a subset of " 14485 "the filter mode (0x%x).\n", fmask, fmode); 14486 return -EINVAL; 14487 } 14488 } 14489 14490 param = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | 14491 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_FILTER) | 14492 V_FW_PARAMS_PARAM_Y(FW_PARAM_DEV_FILTER_MODE_MASK); 14493 val = V_FW_PARAMS_PARAM_FILTER_MODE(fmode) | 14494 V_FW_PARAMS_PARAM_FILTER_MASK(fmask); 14495 rc = t4_set_params(adap, adap->mbox, adap->pf, 0, 1, ¶m, 14496 &val); 14497 if (rc < 0) 14498 return rc; 14499 } 14500 14501 if (vnic_mode != -1) { 14502 param = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | 14503 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_FILTER) | 14504 V_FW_PARAMS_PARAM_Y(FW_PARAM_DEV_FILTER_VNIC_MODE); 14505 val = vnic_mode; 14506 rc = t4_set_params(adap, adap->mbox, adap->pf, 0, 1, ¶m, 14507 &val); 14508 if (rc < 0) 14509 return rc; 14510 } 14511 14512 /* Refresh. */ 14513 read_filter_mode_and_ingress_config(adap); 14514 14515 return 0; 14516 } 14517 14518 /** 14519 * t4_clr_port_stats - clear port statistics 14520 * @adap: the adapter 14521 * @idx: the port index 14522 * 14523 * Clear HW statistics for the given port. 14524 */ 14525 void t4_clr_port_stats(struct adapter *adap, int idx) 14526 { 14527 struct port_info *pi; 14528 int i, port_id, tx_chan; 14529 u32 bgmap, port_base_addr; 14530 14531 port_id = adap->port_map[idx]; 14532 MPASS(port_id >= 0 && port_id <= adap->params.nports); 14533 pi = adap->port[port_id]; 14534 14535 for (tx_chan = pi->tx_chan; 14536 tx_chan < pi->tx_chan + adap->params.tp.lb_nchan; tx_chan++) { 14537 port_base_addr = t4_port_reg(adap, tx_chan, 0); 14538 14539 for (i = A_MPS_PORT_STAT_TX_PORT_BYTES_L; 14540 i <= A_MPS_PORT_STAT_TX_PORT_PPP7_H; i += 8) 14541 t4_write_reg(adap, port_base_addr + i, 0); 14542 for (i = A_MPS_PORT_STAT_RX_PORT_BYTES_L; 14543 i <= A_MPS_PORT_STAT_RX_PORT_LESS_64B_H; i += 8) 14544 t4_write_reg(adap, port_base_addr + i, 0); 14545 } 14546 bgmap = pi->mps_bg_map; 14547 for (i = 0; i < 4; i++) 14548 if (bgmap & (1 << i)) { 14549 t4_write_reg(adap, 14550 A_MPS_STAT_RX_BG_0_MAC_DROP_FRAME_L + i * 8, 0); 14551 t4_write_reg(adap, 14552 A_MPS_STAT_RX_BG_0_MAC_TRUNC_FRAME_L + i * 8, 0); 14553 } 14554 } 14555 14556 /** 14557 * t4_i2c_io - read/write I2C data from adapter 14558 * @adap: the adapter 14559 * @port: Port number if per-port device; <0 if not 14560 * @devid: per-port device ID or absolute device ID 14561 * @offset: byte offset into device I2C space 14562 * @len: byte length of I2C space data 14563 * @buf: buffer in which to return I2C data for read 14564 * buffer which holds the I2C data for write 14565 * @write: if true, do a write; else do a read 14566 * Reads/Writes the I2C data from/to the indicated device and location. 14567 */ 14568 int t4_i2c_io(struct adapter *adap, unsigned int mbox, 14569 int port, unsigned int devid, 14570 unsigned int offset, unsigned int len, 14571 u8 *buf, bool write) 14572 { 14573 struct fw_ldst_cmd ldst_cmd, ldst_rpl; 14574 unsigned int i2c_max = sizeof(ldst_cmd.u.i2c.data); 14575 int ret = 0; 14576 14577 if (len > I2C_PAGE_SIZE) 14578 return -EINVAL; 14579 14580 /* Dont allow reads that spans multiple pages */ 14581 if (offset < I2C_PAGE_SIZE && offset + len > I2C_PAGE_SIZE) 14582 return -EINVAL; 14583 14584 memset(&ldst_cmd, 0, sizeof(ldst_cmd)); 14585 ldst_cmd.op_to_addrspace = 14586 cpu_to_be32(V_FW_CMD_OP(FW_LDST_CMD) | 14587 F_FW_CMD_REQUEST | 14588 (write ? F_FW_CMD_WRITE : F_FW_CMD_READ) | 14589 V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_I2C)); 14590 ldst_cmd.cycles_to_len16 = cpu_to_be32(FW_LEN16(ldst_cmd)); 14591 ldst_cmd.u.i2c.pid = (port < 0 ? 0xff : port); 14592 ldst_cmd.u.i2c.did = devid; 14593 14594 while (len > 0) { 14595 unsigned int i2c_len = (len < i2c_max) ? len : i2c_max; 14596 14597 ldst_cmd.u.i2c.boffset = offset; 14598 ldst_cmd.u.i2c.blen = i2c_len; 14599 14600 if (write) 14601 memcpy(ldst_cmd.u.i2c.data, buf, i2c_len); 14602 14603 ret = t4_wr_mbox(adap, mbox, &ldst_cmd, sizeof(ldst_cmd), 14604 write ? NULL : &ldst_rpl); 14605 if (ret) 14606 break; 14607 14608 if (!write) 14609 memcpy(buf, ldst_rpl.u.i2c.data, i2c_len); 14610 offset += i2c_len; 14611 buf += i2c_len; 14612 len -= i2c_len; 14613 } 14614 14615 return ret; 14616 } 14617 14618 int t4_i2c_rd(struct adapter *adap, unsigned int mbox, 14619 int port, unsigned int devid, 14620 unsigned int offset, unsigned int len, 14621 u8 *buf) 14622 { 14623 return t4_i2c_io(adap, mbox, port, devid, offset, len, buf, false); 14624 } 14625 14626 int t4_i2c_wr(struct adapter *adap, unsigned int mbox, 14627 int port, unsigned int devid, 14628 unsigned int offset, unsigned int len, 14629 u8 *buf) 14630 { 14631 return t4_i2c_io(adap, mbox, port, devid, offset, len, buf, true); 14632 } 14633 14634 /** 14635 * t4_sge_ctxt_rd - read an SGE context through FW 14636 * @adap: the adapter 14637 * @mbox: mailbox to use for the FW command 14638 * @cid: the context id 14639 * @ctype: the context type 14640 * @data: where to store the context data 14641 * 14642 * Issues a FW command through the given mailbox to read an SGE context. 14643 */ 14644 int t4_sge_ctxt_rd(struct adapter *adap, unsigned int mbox, unsigned int cid, 14645 enum ctxt_type ctype, u32 *data) 14646 { 14647 int ret; 14648 struct fw_ldst_cmd c; 14649 14650 if (ctype == CTXT_EGRESS) 14651 ret = FW_LDST_ADDRSPC_SGE_EGRC; 14652 else if (ctype == CTXT_INGRESS) 14653 ret = FW_LDST_ADDRSPC_SGE_INGC; 14654 else if (ctype == CTXT_FLM) 14655 ret = FW_LDST_ADDRSPC_SGE_FLMC; 14656 else 14657 ret = FW_LDST_ADDRSPC_SGE_CONMC; 14658 14659 memset(&c, 0, sizeof(c)); 14660 c.op_to_addrspace = cpu_to_be32(V_FW_CMD_OP(FW_LDST_CMD) | 14661 F_FW_CMD_REQUEST | F_FW_CMD_READ | 14662 V_FW_LDST_CMD_ADDRSPACE(ret)); 14663 c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c)); 14664 c.u.idctxt.physid = cpu_to_be32(cid); 14665 14666 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); 14667 if (ret == 0) { 14668 data[0] = be32_to_cpu(c.u.idctxt.ctxt_data0); 14669 data[1] = be32_to_cpu(c.u.idctxt.ctxt_data1); 14670 data[2] = be32_to_cpu(c.u.idctxt.ctxt_data2); 14671 data[3] = be32_to_cpu(c.u.idctxt.ctxt_data3); 14672 data[4] = be32_to_cpu(c.u.idctxt.ctxt_data4); 14673 data[5] = be32_to_cpu(c.u.idctxt.ctxt_data5); 14674 if (chip_id(adap) > CHELSIO_T6) 14675 data[6] = be32_to_cpu(c.u.idctxt.ctxt_data6); 14676 } 14677 return ret; 14678 } 14679 14680 /** 14681 * t4_sge_ctxt_rd_bd - read an SGE context bypassing FW 14682 * @adap: the adapter 14683 * @cid: the context id 14684 * @ctype: the context type 14685 * @data: where to store the context data 14686 * 14687 * Reads an SGE context directly, bypassing FW. This is only for 14688 * debugging when FW is unavailable. 14689 */ 14690 int t4_sge_ctxt_rd_bd(struct adapter *adap, unsigned int cid, enum ctxt_type ctype, 14691 u32 *data) 14692 { 14693 int i, ret; 14694 14695 t4_write_reg(adap, A_SGE_CTXT_CMD, V_CTXTQID(cid) | V_CTXTTYPE(ctype)); 14696 ret = t4_wait_op_done(adap, A_SGE_CTXT_CMD, F_BUSY, 0, 3, 1); 14697 if (!ret) { 14698 for (i = A_SGE_CTXT_DATA0; i <= A_SGE_CTXT_DATA5; i += 4) 14699 *data++ = t4_read_reg(adap, i); 14700 if (chip_id(adap) > CHELSIO_T6) 14701 *data++ = t4_read_reg(adap, i); 14702 } 14703 return ret; 14704 } 14705 14706 int t4_sched_config(struct adapter *adapter, int type, int minmaxen, 14707 int sleep_ok) 14708 { 14709 struct fw_sched_cmd cmd; 14710 14711 memset(&cmd, 0, sizeof(cmd)); 14712 cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_SCHED_CMD) | 14713 F_FW_CMD_REQUEST | 14714 F_FW_CMD_WRITE); 14715 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); 14716 14717 cmd.u.config.sc = FW_SCHED_SC_CONFIG; 14718 cmd.u.config.type = type; 14719 cmd.u.config.minmaxen = minmaxen; 14720 14721 return t4_wr_mbox_meat(adapter,adapter->mbox, &cmd, sizeof(cmd), 14722 NULL, sleep_ok); 14723 } 14724 14725 int t4_sched_params(struct adapter *adapter, int type, int level, int mode, 14726 int rateunit, int ratemode, int channel, int cl, 14727 int minrate, int maxrate, int weight, int pktsize, 14728 int burstsize, int sleep_ok) 14729 { 14730 struct fw_sched_cmd cmd; 14731 14732 memset(&cmd, 0, sizeof(cmd)); 14733 cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_SCHED_CMD) | 14734 F_FW_CMD_REQUEST | 14735 F_FW_CMD_WRITE); 14736 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); 14737 14738 cmd.u.params.sc = FW_SCHED_SC_PARAMS; 14739 cmd.u.params.type = type; 14740 cmd.u.params.level = level; 14741 cmd.u.params.mode = mode; 14742 cmd.u.params.ch = channel; 14743 cmd.u.params.cl = cl; 14744 cmd.u.params.unit = rateunit; 14745 cmd.u.params.rate = ratemode; 14746 cmd.u.params.min = cpu_to_be32(minrate); 14747 cmd.u.params.max = cpu_to_be32(maxrate); 14748 cmd.u.params.weight = cpu_to_be16(weight); 14749 cmd.u.params.pktsize = cpu_to_be16(pktsize); 14750 cmd.u.params.burstsize = cpu_to_be16(burstsize); 14751 14752 return t4_wr_mbox_meat(adapter,adapter->mbox, &cmd, sizeof(cmd), 14753 NULL, sleep_ok); 14754 } 14755 14756 int t4_sched_params_ch_rl(struct adapter *adapter, int channel, int ratemode, 14757 unsigned int maxrate, int sleep_ok) 14758 { 14759 struct fw_sched_cmd cmd; 14760 14761 memset(&cmd, 0, sizeof(cmd)); 14762 cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_SCHED_CMD) | 14763 F_FW_CMD_REQUEST | 14764 F_FW_CMD_WRITE); 14765 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); 14766 14767 cmd.u.params.sc = FW_SCHED_SC_PARAMS; 14768 cmd.u.params.type = FW_SCHED_TYPE_PKTSCHED; 14769 cmd.u.params.level = FW_SCHED_PARAMS_LEVEL_CH_RL; 14770 cmd.u.params.ch = channel; 14771 cmd.u.params.rate = ratemode; /* REL or ABS */ 14772 cmd.u.params.max = cpu_to_be32(maxrate);/* % or kbps */ 14773 14774 return t4_wr_mbox_meat(adapter,adapter->mbox, &cmd, sizeof(cmd), 14775 NULL, sleep_ok); 14776 } 14777 14778 int t4_sched_params_cl_wrr(struct adapter *adapter, int channel, int cl, 14779 int weight, int sleep_ok) 14780 { 14781 struct fw_sched_cmd cmd; 14782 14783 if (weight < 0 || weight > 100) 14784 return -EINVAL; 14785 14786 memset(&cmd, 0, sizeof(cmd)); 14787 cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_SCHED_CMD) | 14788 F_FW_CMD_REQUEST | 14789 F_FW_CMD_WRITE); 14790 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); 14791 14792 cmd.u.params.sc = FW_SCHED_SC_PARAMS; 14793 cmd.u.params.type = FW_SCHED_TYPE_PKTSCHED; 14794 cmd.u.params.level = FW_SCHED_PARAMS_LEVEL_CL_WRR; 14795 cmd.u.params.ch = channel; 14796 cmd.u.params.cl = cl; 14797 cmd.u.params.weight = cpu_to_be16(weight); 14798 14799 return t4_wr_mbox_meat(adapter,adapter->mbox, &cmd, sizeof(cmd), 14800 NULL, sleep_ok); 14801 } 14802 14803 int t4_sched_params_cl_rl_kbps(struct adapter *adapter, int channel, int cl, 14804 int mode, unsigned int maxrate, int pktsize, int sleep_ok) 14805 { 14806 struct fw_sched_cmd cmd; 14807 14808 memset(&cmd, 0, sizeof(cmd)); 14809 cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_SCHED_CMD) | 14810 F_FW_CMD_REQUEST | 14811 F_FW_CMD_WRITE); 14812 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); 14813 14814 cmd.u.params.sc = FW_SCHED_SC_PARAMS; 14815 cmd.u.params.type = FW_SCHED_TYPE_PKTSCHED; 14816 cmd.u.params.level = FW_SCHED_PARAMS_LEVEL_CL_RL; 14817 cmd.u.params.mode = mode; 14818 cmd.u.params.ch = channel; 14819 cmd.u.params.cl = cl; 14820 cmd.u.params.unit = FW_SCHED_PARAMS_UNIT_BITRATE; 14821 cmd.u.params.rate = FW_SCHED_PARAMS_RATE_ABS; 14822 cmd.u.params.max = cpu_to_be32(maxrate); 14823 cmd.u.params.pktsize = cpu_to_be16(pktsize); 14824 14825 return t4_wr_mbox_meat(adapter,adapter->mbox, &cmd, sizeof(cmd), 14826 NULL, sleep_ok); 14827 } 14828 14829 /* 14830 * t4_config_watchdog - configure (enable/disable) a watchdog timer 14831 * @adapter: the adapter 14832 * @mbox: mailbox to use for the FW command 14833 * @pf: the PF owning the queue 14834 * @vf: the VF owning the queue 14835 * @timeout: watchdog timeout in ms 14836 * @action: watchdog timer / action 14837 * 14838 * There are separate watchdog timers for each possible watchdog 14839 * action. Configure one of the watchdog timers by setting a non-zero 14840 * timeout. Disable a watchdog timer by using a timeout of zero. 14841 */ 14842 int t4_config_watchdog(struct adapter *adapter, unsigned int mbox, 14843 unsigned int pf, unsigned int vf, 14844 unsigned int timeout, unsigned int action) 14845 { 14846 struct fw_watchdog_cmd wdog; 14847 unsigned int ticks; 14848 14849 /* 14850 * The watchdog command expects a timeout in units of 10ms so we need 14851 * to convert it here (via rounding) and force a minimum of one 10ms 14852 * "tick" if the timeout is non-zero but the conversion results in 0 14853 * ticks. 14854 */ 14855 ticks = (timeout + 5)/10; 14856 if (timeout && !ticks) 14857 ticks = 1; 14858 14859 memset(&wdog, 0, sizeof wdog); 14860 wdog.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_WATCHDOG_CMD) | 14861 F_FW_CMD_REQUEST | 14862 F_FW_CMD_WRITE | 14863 V_FW_PARAMS_CMD_PFN(pf) | 14864 V_FW_PARAMS_CMD_VFN(vf)); 14865 wdog.retval_len16 = cpu_to_be32(FW_LEN16(wdog)); 14866 wdog.timeout = cpu_to_be32(ticks); 14867 wdog.action = cpu_to_be32(action); 14868 14869 return t4_wr_mbox(adapter, mbox, &wdog, sizeof wdog, NULL); 14870 } 14871 14872 int t4_get_devlog_level(struct adapter *adapter, unsigned int *level) 14873 { 14874 struct fw_devlog_cmd devlog_cmd; 14875 int ret; 14876 14877 memset(&devlog_cmd, 0, sizeof(devlog_cmd)); 14878 devlog_cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_DEVLOG_CMD) | 14879 F_FW_CMD_REQUEST | F_FW_CMD_READ); 14880 devlog_cmd.retval_len16 = cpu_to_be32(FW_LEN16(devlog_cmd)); 14881 ret = t4_wr_mbox(adapter, adapter->mbox, &devlog_cmd, 14882 sizeof(devlog_cmd), &devlog_cmd); 14883 if (ret) 14884 return ret; 14885 14886 *level = devlog_cmd.level; 14887 return 0; 14888 } 14889 14890 int t4_set_devlog_level(struct adapter *adapter, unsigned int level) 14891 { 14892 struct fw_devlog_cmd devlog_cmd; 14893 14894 memset(&devlog_cmd, 0, sizeof(devlog_cmd)); 14895 devlog_cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_DEVLOG_CMD) | 14896 F_FW_CMD_REQUEST | 14897 F_FW_CMD_WRITE); 14898 devlog_cmd.level = level; 14899 devlog_cmd.retval_len16 = cpu_to_be32(FW_LEN16(devlog_cmd)); 14900 return t4_wr_mbox(adapter, adapter->mbox, &devlog_cmd, 14901 sizeof(devlog_cmd), &devlog_cmd); 14902 } 14903 14904 int t4_configure_add_smac(struct adapter *adap) 14905 { 14906 unsigned int param, val; 14907 int ret = 0; 14908 14909 adap->params.smac_add_support = 0; 14910 param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | 14911 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_ADD_SMAC)); 14912 /* Query FW to check if FW supports adding source mac address 14913 * to TCAM feature or not. 14914 * If FW returns 1, driver can use this feature and driver need to send 14915 * FW_PARAMS_PARAM_DEV_ADD_SMAC write command with value 1 to 14916 * enable adding smac to TCAM. 14917 */ 14918 ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1, ¶m, &val); 14919 if (ret) 14920 return ret; 14921 14922 if (val == 1) { 14923 ret = t4_set_params(adap, adap->mbox, adap->pf, 0, 1, 14924 ¶m, &val); 14925 if (!ret) 14926 /* Firmware allows adding explicit TCAM entries. 14927 * Save this internally. 14928 */ 14929 adap->params.smac_add_support = 1; 14930 } 14931 14932 return ret; 14933 } 14934 14935 int t4_configure_ringbb(struct adapter *adap) 14936 { 14937 unsigned int param, val; 14938 int ret = 0; 14939 14940 param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | 14941 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_RING_BACKBONE)); 14942 /* Query FW to check if FW supports ring switch feature or not. 14943 * If FW returns 1, driver can use this feature and driver need to send 14944 * FW_PARAMS_PARAM_DEV_RING_BACKBONE write command with value 1 to 14945 * enable the ring backbone configuration. 14946 */ 14947 ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1, ¶m, &val); 14948 if (ret < 0) { 14949 CH_ERR(adap, "Querying FW using Ring backbone params command failed, err=%d\n", 14950 ret); 14951 goto out; 14952 } 14953 14954 if (val != 1) { 14955 CH_ERR(adap, "FW doesnot support ringbackbone features\n"); 14956 goto out; 14957 } 14958 14959 ret = t4_set_params(adap, adap->mbox, adap->pf, 0, 1, ¶m, &val); 14960 if (ret < 0) { 14961 CH_ERR(adap, "Could not set Ringbackbone, err= %d\n", 14962 ret); 14963 goto out; 14964 } 14965 14966 out: 14967 return ret; 14968 } 14969 14970 /* 14971 * t4_set_vlan_acl - Set a VLAN id for the specified VF 14972 * @adapter: the adapter 14973 * @mbox: mailbox to use for the FW command 14974 * @vf: one of the VFs instantiated by the specified PF 14975 * @vlan: The vlanid to be set 14976 * 14977 */ 14978 int t4_set_vlan_acl(struct adapter *adap, unsigned int pf, unsigned int vf, 14979 u16 vlan) 14980 { 14981 struct fw_acl_vlan_cmd vlan_cmd; 14982 unsigned int enable; 14983 14984 enable = (vlan ? F_FW_ACL_VLAN_CMD_EN : 0); 14985 memset(&vlan_cmd, 0, sizeof(vlan_cmd)); 14986 vlan_cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_ACL_VLAN_CMD) | 14987 F_FW_CMD_REQUEST | 14988 F_FW_CMD_WRITE | 14989 F_FW_CMD_EXEC | 14990 V_FW_ACL_VLAN_CMD_PFN(pf) | 14991 V_FW_ACL_VLAN_CMD_VFN(vf)); 14992 vlan_cmd.en_to_len16 = cpu_to_be32(enable | FW_LEN16(vlan_cmd) | 14993 V_FW_ACL_VLAN_CMD_PMASK(1 << pf)); 14994 /* Drop all packets that donot match vlan id */ 14995 vlan_cmd.dropnovlan_fm = (enable 14996 ? (F_FW_ACL_VLAN_CMD_DROPNOVLAN | 14997 F_FW_ACL_VLAN_CMD_FM) 14998 : 0); 14999 if (enable != 0) { 15000 vlan_cmd.nvlan = 1; 15001 vlan_cmd.vlanid[0] = cpu_to_be16(vlan); 15002 } 15003 15004 return t4_wr_mbox(adap, adap->mbox, &vlan_cmd, sizeof(vlan_cmd), NULL); 15005 } 15006 15007 /** 15008 * t4_del_mac - Removes the exact-match filter for a MAC address 15009 * @adap: the adapter 15010 * @mbox: mailbox to use for the FW command 15011 * @viid: the VI id 15012 * @addr: the MAC address value 15013 * @smac: if true, delete from only the smac region of MPS 15014 * 15015 * Modifies an exact-match filter and sets it to the new MAC address if 15016 * @idx >= 0, or adds the MAC address to a new filter if @idx < 0. In the 15017 * latter case the address is added persistently if @persist is %true. 15018 * 15019 * Returns a negative error number or the index of the filter with the new 15020 * MAC value. Note that this index may differ from @idx. 15021 */ 15022 int t4_del_mac(struct adapter *adap, unsigned int mbox, unsigned int viid, 15023 const u8 *addr, bool smac) 15024 { 15025 int ret; 15026 struct fw_vi_mac_cmd c; 15027 struct fw_vi_mac_exact *p = c.u.exact; 15028 unsigned int max_mac_addr = adap->chip_params->mps_tcam_size; 15029 15030 memset(&c, 0, sizeof(c)); 15031 c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_VI_MAC_CMD) | 15032 F_FW_CMD_REQUEST | F_FW_CMD_WRITE | 15033 V_FW_VI_MAC_CMD_VIID(viid)); 15034 c.freemacs_to_len16 = cpu_to_be32( 15035 V_FW_CMD_LEN16(1) | 15036 (smac ? F_FW_VI_MAC_CMD_IS_SMAC : 0)); 15037 15038 memcpy(p->macaddr, addr, sizeof(p->macaddr)); 15039 p->valid_to_idx = cpu_to_be16( 15040 F_FW_VI_MAC_CMD_VALID | 15041 V_FW_VI_MAC_CMD_IDX(FW_VI_MAC_MAC_BASED_FREE)); 15042 15043 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); 15044 if (ret == 0) { 15045 ret = G_FW_VI_MAC_CMD_IDX(be16_to_cpu(p->valid_to_idx)); 15046 if (ret < max_mac_addr) 15047 return -ENOMEM; 15048 } 15049 15050 return ret; 15051 } 15052 15053 /** 15054 * t4_add_mac - Adds an exact-match filter for a MAC address 15055 * @adap: the adapter 15056 * @mbox: mailbox to use for the FW command 15057 * @viid: the VI id 15058 * @idx: index of existing filter for old value of MAC address, or -1 15059 * @addr: the new MAC address value 15060 * @persist: whether a new MAC allocation should be persistent 15061 * @add_smt: if true also add the address to the HW SMT 15062 * @smac: if true, update only the smac region of MPS 15063 * 15064 * Modifies an exact-match filter and sets it to the new MAC address if 15065 * @idx >= 0, or adds the MAC address to a new filter if @idx < 0. In the 15066 * latter case the address is added persistently if @persist is %true. 15067 * 15068 * Returns a negative error number or the index of the filter with the new 15069 * MAC value. Note that this index may differ from @idx. 15070 */ 15071 int t4_add_mac(struct adapter *adap, unsigned int mbox, unsigned int viid, 15072 int idx, const u8 *addr, bool persist, u8 *smt_idx, bool smac) 15073 { 15074 int ret, mode; 15075 struct fw_vi_mac_cmd c; 15076 struct fw_vi_mac_exact *p = c.u.exact; 15077 unsigned int max_mac_addr = adap->chip_params->mps_tcam_size; 15078 15079 if (idx < 0) /* new allocation */ 15080 idx = persist ? FW_VI_MAC_ADD_PERSIST_MAC : FW_VI_MAC_ADD_MAC; 15081 mode = smt_idx ? FW_VI_MAC_SMT_AND_MPSTCAM : FW_VI_MAC_MPS_TCAM_ENTRY; 15082 15083 memset(&c, 0, sizeof(c)); 15084 c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_VI_MAC_CMD) | 15085 F_FW_CMD_REQUEST | F_FW_CMD_WRITE | 15086 V_FW_VI_MAC_CMD_VIID(viid)); 15087 c.freemacs_to_len16 = cpu_to_be32( 15088 V_FW_CMD_LEN16(1) | 15089 (smac ? F_FW_VI_MAC_CMD_IS_SMAC : 0)); 15090 p->valid_to_idx = cpu_to_be16(F_FW_VI_MAC_CMD_VALID | 15091 V_FW_VI_MAC_CMD_SMAC_RESULT(mode) | 15092 V_FW_VI_MAC_CMD_IDX(idx)); 15093 memcpy(p->macaddr, addr, sizeof(p->macaddr)); 15094 15095 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); 15096 if (ret == 0) { 15097 ret = G_FW_VI_MAC_CMD_IDX(be16_to_cpu(p->valid_to_idx)); 15098 if (ret >= max_mac_addr) 15099 return -ENOMEM; 15100 if (smt_idx) { 15101 /* Does fw supports returning smt_idx? */ 15102 if (adap->params.viid_smt_extn_support) 15103 *smt_idx = G_FW_VI_MAC_CMD_SMTID(be32_to_cpu(c.op_to_viid)); 15104 else { 15105 /* In T4/T5, SMT contains 256 SMAC entries 15106 * organized in 128 rows of 2 entries each. 15107 * In T6, SMT contains 256 SMAC entries in 15108 * 256 rows. 15109 */ 15110 if (chip_id(adap) <= CHELSIO_T5) 15111 *smt_idx = ((viid & M_FW_VIID_VIN) << 1); 15112 else 15113 *smt_idx = (viid & M_FW_VIID_VIN); 15114 } 15115 } 15116 } 15117 15118 return ret; 15119 } 15120