hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/net/ethernet/qlogic/qed/qed_int.c
....@@ -1,33 +1,7 @@
1
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
12 /* QLogic qed NIC Driver
23 * Copyright (c) 2015-2017 QLogic Corporation
3
- *
4
- * This software is available to you under a choice of one of two
5
- * licenses. You may choose to be licensed under the terms of the GNU
6
- * General Public License (GPL) Version 2, available from the file
7
- * COPYING in the main directory of this source tree, or the
8
- * OpenIB.org BSD license below:
9
- *
10
- * Redistribution and use in source and binary forms, with or
11
- * without modification, are permitted provided that the following
12
- * conditions are met:
13
- *
14
- * - Redistributions of source code must retain the above
15
- * copyright notice, this list of conditions and the following
16
- * disclaimer.
17
- *
18
- * - Redistributions in binary form must reproduce the above
19
- * copyright notice, this list of conditions and the following
20
- * disclaimer in the documentation and /or other materials
21
- * provided with the distribution.
22
- *
23
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
- * SOFTWARE.
4
+ * Copyright (c) 2019-2020 Marvell International Ltd.
315 */
326
337 #include <linux/types.h>
....@@ -96,6 +70,7 @@
9670 #define ATTENTION_BB(value) (value << ATTENTION_BB_SHIFT)
9771 #define ATTENTION_BB_DIFFERENT BIT(23)
9872
73
+#define ATTENTION_CLEAR_ENABLE BIT(28)
9974 unsigned int flags;
10075
10176 /* Callback to call if attention will be triggered */
....@@ -255,136 +230,319 @@
255230 #define PGLUE_ATTENTION_ICPL_VALID (1 << 23)
256231 #define PGLUE_ATTENTION_ZLR_VALID (1 << 25)
257232 #define PGLUE_ATTENTION_ILT_VALID (1 << 23)
258
-static int qed_pglub_rbc_attn_cb(struct qed_hwfn *p_hwfn)
233
+
234
+int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
235
+ bool hw_init)
259236 {
237
+ char msg[256];
260238 u32 tmp;
261239
262
- tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
263
- PGLUE_B_REG_TX_ERR_WR_DETAILS2);
240
+ tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_WR_DETAILS2);
264241 if (tmp & PGLUE_ATTENTION_VALID) {
265242 u32 addr_lo, addr_hi, details;
266243
267
- addr_lo = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
244
+ addr_lo = qed_rd(p_hwfn, p_ptt,
268245 PGLUE_B_REG_TX_ERR_WR_ADD_31_0);
269
- addr_hi = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
246
+ addr_hi = qed_rd(p_hwfn, p_ptt,
270247 PGLUE_B_REG_TX_ERR_WR_ADD_63_32);
271
- details = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
248
+ details = qed_rd(p_hwfn, p_ptt,
272249 PGLUE_B_REG_TX_ERR_WR_DETAILS);
273250
274
- DP_INFO(p_hwfn,
275
- "Illegal write by chip to [%08x:%08x] blocked.\n"
276
- "Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n"
277
- "Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]\n",
278
- addr_hi, addr_lo, details,
279
- (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID),
280
- (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID),
281
- GET_FIELD(details,
282
- PGLUE_ATTENTION_DETAILS_VF_VALID) ? 1 : 0,
283
- tmp,
284
- GET_FIELD(tmp,
285
- PGLUE_ATTENTION_DETAILS2_WAS_ERR) ? 1 : 0,
286
- GET_FIELD(tmp,
287
- PGLUE_ATTENTION_DETAILS2_BME) ? 1 : 0,
288
- GET_FIELD(tmp,
289
- PGLUE_ATTENTION_DETAILS2_FID_EN) ? 1 : 0);
251
+ snprintf(msg, sizeof(msg),
252
+ "Illegal write by chip to [%08x:%08x] blocked.\n"
253
+ "Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n"
254
+ "Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]",
255
+ addr_hi, addr_lo, details,
256
+ (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID),
257
+ (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID),
258
+ !!GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VF_VALID),
259
+ tmp,
260
+ !!GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_WAS_ERR),
261
+ !!GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_BME),
262
+ !!GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_FID_EN));
263
+
264
+ if (hw_init)
265
+ DP_VERBOSE(p_hwfn, NETIF_MSG_INTR, "%s\n", msg);
266
+ else
267
+ DP_NOTICE(p_hwfn, "%s\n", msg);
290268 }
291269
292
- tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
293
- PGLUE_B_REG_TX_ERR_RD_DETAILS2);
270
+ tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_RD_DETAILS2);
294271 if (tmp & PGLUE_ATTENTION_RD_VALID) {
295272 u32 addr_lo, addr_hi, details;
296273
297
- addr_lo = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
274
+ addr_lo = qed_rd(p_hwfn, p_ptt,
298275 PGLUE_B_REG_TX_ERR_RD_ADD_31_0);
299
- addr_hi = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
276
+ addr_hi = qed_rd(p_hwfn, p_ptt,
300277 PGLUE_B_REG_TX_ERR_RD_ADD_63_32);
301
- details = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
278
+ details = qed_rd(p_hwfn, p_ptt,
302279 PGLUE_B_REG_TX_ERR_RD_DETAILS);
303280
304
- DP_INFO(p_hwfn,
305
- "Illegal read by chip from [%08x:%08x] blocked.\n"
306
- " Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n"
307
- " Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]\n",
308
- addr_hi, addr_lo, details,
309
- (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID),
310
- (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID),
311
- GET_FIELD(details,
312
- PGLUE_ATTENTION_DETAILS_VF_VALID) ? 1 : 0,
313
- tmp,
314
- GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_WAS_ERR) ? 1
315
- : 0,
316
- GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_BME) ? 1 : 0,
317
- GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_FID_EN) ? 1
318
- : 0);
281
+ DP_NOTICE(p_hwfn,
282
+ "Illegal read by chip from [%08x:%08x] blocked.\n"
283
+ "Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n"
284
+ "Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]\n",
285
+ addr_hi, addr_lo, details,
286
+ (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID),
287
+ (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID),
288
+ GET_FIELD(details,
289
+ PGLUE_ATTENTION_DETAILS_VF_VALID) ? 1 : 0,
290
+ tmp,
291
+ GET_FIELD(tmp,
292
+ PGLUE_ATTENTION_DETAILS2_WAS_ERR) ? 1 : 0,
293
+ GET_FIELD(tmp,
294
+ PGLUE_ATTENTION_DETAILS2_BME) ? 1 : 0,
295
+ GET_FIELD(tmp,
296
+ PGLUE_ATTENTION_DETAILS2_FID_EN) ? 1 : 0);
319297 }
320298
321
- tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
322
- PGLUE_B_REG_TX_ERR_WR_DETAILS_ICPL);
323
- if (tmp & PGLUE_ATTENTION_ICPL_VALID)
324
- DP_INFO(p_hwfn, "ICPL error - %08x\n", tmp);
299
+ tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_WR_DETAILS_ICPL);
300
+ if (tmp & PGLUE_ATTENTION_ICPL_VALID) {
301
+ snprintf(msg, sizeof(msg), "ICPL error - %08x", tmp);
325302
326
- tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
327
- PGLUE_B_REG_MASTER_ZLR_ERR_DETAILS);
303
+ if (hw_init)
304
+ DP_VERBOSE(p_hwfn, NETIF_MSG_INTR, "%s\n", msg);
305
+ else
306
+ DP_NOTICE(p_hwfn, "%s\n", msg);
307
+ }
308
+
309
+ tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_MASTER_ZLR_ERR_DETAILS);
328310 if (tmp & PGLUE_ATTENTION_ZLR_VALID) {
329311 u32 addr_hi, addr_lo;
330312
331
- addr_lo = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
313
+ addr_lo = qed_rd(p_hwfn, p_ptt,
332314 PGLUE_B_REG_MASTER_ZLR_ERR_ADD_31_0);
333
- addr_hi = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
315
+ addr_hi = qed_rd(p_hwfn, p_ptt,
334316 PGLUE_B_REG_MASTER_ZLR_ERR_ADD_63_32);
335317
336
- DP_INFO(p_hwfn, "ZLR eror - %08x [Address %08x:%08x]\n",
337
- tmp, addr_hi, addr_lo);
318
+ DP_NOTICE(p_hwfn, "ZLR error - %08x [Address %08x:%08x]\n",
319
+ tmp, addr_hi, addr_lo);
338320 }
339321
340
- tmp = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
341
- PGLUE_B_REG_VF_ILT_ERR_DETAILS2);
322
+ tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_VF_ILT_ERR_DETAILS2);
342323 if (tmp & PGLUE_ATTENTION_ILT_VALID) {
343324 u32 addr_hi, addr_lo, details;
344325
345
- addr_lo = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
326
+ addr_lo = qed_rd(p_hwfn, p_ptt,
346327 PGLUE_B_REG_VF_ILT_ERR_ADD_31_0);
347
- addr_hi = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
328
+ addr_hi = qed_rd(p_hwfn, p_ptt,
348329 PGLUE_B_REG_VF_ILT_ERR_ADD_63_32);
349
- details = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
330
+ details = qed_rd(p_hwfn, p_ptt,
350331 PGLUE_B_REG_VF_ILT_ERR_DETAILS);
351332
352
- DP_INFO(p_hwfn,
353
- "ILT error - Details %08x Details2 %08x [Address %08x:%08x]\n",
354
- details, tmp, addr_hi, addr_lo);
333
+ DP_NOTICE(p_hwfn,
334
+ "ILT error - Details %08x Details2 %08x [Address %08x:%08x]\n",
335
+ details, tmp, addr_hi, addr_lo);
355336 }
356337
357338 /* Clear the indications */
358
- qed_wr(p_hwfn, p_hwfn->p_dpc_ptt,
359
- PGLUE_B_REG_LATCHED_ERRORS_CLR, (1 << 2));
339
+ qed_wr(p_hwfn, p_ptt, PGLUE_B_REG_LATCHED_ERRORS_CLR, BIT(2));
360340
361341 return 0;
362342 }
363343
364
-#define QED_DORQ_ATTENTION_REASON_MASK (0xfffff)
365
-#define QED_DORQ_ATTENTION_OPAQUE_MASK (0xffff)
366
-#define QED_DORQ_ATTENTION_SIZE_MASK (0x7f)
367
-#define QED_DORQ_ATTENTION_SIZE_SHIFT (16)
368
-static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
344
+static int qed_pglueb_rbc_attn_cb(struct qed_hwfn *p_hwfn)
369345 {
370
- u32 reason;
346
+ return qed_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_dpc_ptt, false);
347
+}
371348
372
- reason = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt, DORQ_REG_DB_DROP_REASON) &
373
- QED_DORQ_ATTENTION_REASON_MASK;
374
- if (reason) {
375
- u32 details = qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
376
- DORQ_REG_DB_DROP_DETAILS);
377
-
378
- DP_INFO(p_hwfn->cdev,
379
- "DORQ db_drop: address 0x%08x Opaque FID 0x%04x Size [bytes] 0x%08x Reason: 0x%08x\n",
380
- qed_rd(p_hwfn, p_hwfn->p_dpc_ptt,
381
- DORQ_REG_DB_DROP_DETAILS_ADDRESS),
382
- (u16)(details & QED_DORQ_ATTENTION_OPAQUE_MASK),
383
- GET_FIELD(details, QED_DORQ_ATTENTION_SIZE) * 4,
384
- reason);
385
- }
349
+static int qed_fw_assertion(struct qed_hwfn *p_hwfn)
350
+{
351
+ qed_hw_err_notify(p_hwfn, p_hwfn->p_dpc_ptt, QED_HW_ERR_FW_ASSERT,
352
+ "FW assertion!\n");
386353
387354 return -EINVAL;
355
+}
356
+
357
+static int qed_general_attention_35(struct qed_hwfn *p_hwfn)
358
+{
359
+ DP_INFO(p_hwfn, "General attention 35!\n");
360
+
361
+ return 0;
362
+}
363
+
364
+#define QED_DORQ_ATTENTION_REASON_MASK (0xfffff)
365
+#define QED_DORQ_ATTENTION_OPAQUE_MASK (0xffff)
366
+#define QED_DORQ_ATTENTION_OPAQUE_SHIFT (0x0)
367
+#define QED_DORQ_ATTENTION_SIZE_MASK (0x7f)
368
+#define QED_DORQ_ATTENTION_SIZE_SHIFT (16)
369
+
370
+#define QED_DB_REC_COUNT 1000
371
+#define QED_DB_REC_INTERVAL 100
372
+
373
+static int qed_db_rec_flush_queue(struct qed_hwfn *p_hwfn,
374
+ struct qed_ptt *p_ptt)
375
+{
376
+ u32 count = QED_DB_REC_COUNT;
377
+ u32 usage = 1;
378
+
379
+ /* Flush any pending (e)dpms as they may never arrive */
380
+ qed_wr(p_hwfn, p_ptt, DORQ_REG_DPM_FORCE_ABORT, 0x1);
381
+
382
+ /* wait for usage to zero or count to run out. This is necessary since
383
+ * EDPM doorbell transactions can take multiple 64b cycles, and as such
384
+ * can "split" over the pci. Possibly, the doorbell drop can happen with
385
+ * half an EDPM in the queue and other half dropped. Another EDPM
386
+ * doorbell to the same address (from doorbell recovery mechanism or
387
+ * from the doorbelling entity) could have first half dropped and second
388
+ * half interpreted as continuation of the first. To prevent such
389
+ * malformed doorbells from reaching the device, flush the queue before
390
+ * releasing the overflow sticky indication.
391
+ */
392
+ while (count-- && usage) {
393
+ usage = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_USAGE_CNT);
394
+ udelay(QED_DB_REC_INTERVAL);
395
+ }
396
+
397
+ /* should have been depleted by now */
398
+ if (usage) {
399
+ DP_NOTICE(p_hwfn->cdev,
400
+ "DB recovery: doorbell usage failed to zero after %d usec. usage was %x\n",
401
+ QED_DB_REC_INTERVAL * QED_DB_REC_COUNT, usage);
402
+ return -EBUSY;
403
+ }
404
+
405
+ return 0;
406
+}
407
+
408
+int qed_db_rec_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
409
+{
410
+ u32 attn_ovfl, cur_ovfl;
411
+ int rc;
412
+
413
+ attn_ovfl = test_and_clear_bit(QED_OVERFLOW_BIT,
414
+ &p_hwfn->db_recovery_info.overflow);
415
+ cur_ovfl = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY);
416
+ if (!cur_ovfl && !attn_ovfl)
417
+ return 0;
418
+
419
+ DP_NOTICE(p_hwfn, "PF Overflow sticky: attn %u current %u\n",
420
+ attn_ovfl, cur_ovfl);
421
+
422
+ if (cur_ovfl && !p_hwfn->db_bar_no_edpm) {
423
+ rc = qed_db_rec_flush_queue(p_hwfn, p_ptt);
424
+ if (rc)
425
+ return rc;
426
+ }
427
+
428
+ /* Release overflow sticky indication (stop silently dropping everything) */
429
+ qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0);
430
+
431
+ /* Repeat all last doorbells (doorbell drop recovery) */
432
+ qed_db_recovery_execute(p_hwfn);
433
+
434
+ return 0;
435
+}
436
+
437
+static void qed_dorq_attn_overflow(struct qed_hwfn *p_hwfn)
438
+{
439
+ struct qed_ptt *p_ptt = p_hwfn->p_dpc_ptt;
440
+ u32 overflow;
441
+ int rc;
442
+
443
+ overflow = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY);
444
+ if (!overflow)
445
+ goto out;
446
+
447
+ /* Run PF doorbell recovery in next periodic handler */
448
+ set_bit(QED_OVERFLOW_BIT, &p_hwfn->db_recovery_info.overflow);
449
+
450
+ if (!p_hwfn->db_bar_no_edpm) {
451
+ rc = qed_db_rec_flush_queue(p_hwfn, p_ptt);
452
+ if (rc)
453
+ goto out;
454
+ }
455
+
456
+ qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0);
457
+out:
458
+ /* Schedule the handler even if overflow was not detected */
459
+ qed_periodic_db_rec_start(p_hwfn);
460
+}
461
+
462
+static int qed_dorq_attn_int_sts(struct qed_hwfn *p_hwfn)
463
+{
464
+ u32 int_sts, first_drop_reason, details, address, all_drops_reason;
465
+ struct qed_ptt *p_ptt = p_hwfn->p_dpc_ptt;
466
+
467
+ /* int_sts may be zero since all PFs were interrupted for doorbell
468
+ * overflow but another one already handled it. Can abort here. If
469
+ * This PF also requires overflow recovery we will be interrupted again.
470
+ * The masked almost full indication may also be set. Ignoring.
471
+ */
472
+ int_sts = qed_rd(p_hwfn, p_ptt, DORQ_REG_INT_STS);
473
+ if (!(int_sts & ~DORQ_REG_INT_STS_DORQ_FIFO_AFULL))
474
+ return 0;
475
+
476
+ DP_NOTICE(p_hwfn->cdev, "DORQ attention. int_sts was %x\n", int_sts);
477
+
478
+ /* check if db_drop or overflow happened */
479
+ if (int_sts & (DORQ_REG_INT_STS_DB_DROP |
480
+ DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR)) {
481
+ /* Obtain data about db drop/overflow */
482
+ first_drop_reason = qed_rd(p_hwfn, p_ptt,
483
+ DORQ_REG_DB_DROP_REASON) &
484
+ QED_DORQ_ATTENTION_REASON_MASK;
485
+ details = qed_rd(p_hwfn, p_ptt, DORQ_REG_DB_DROP_DETAILS);
486
+ address = qed_rd(p_hwfn, p_ptt,
487
+ DORQ_REG_DB_DROP_DETAILS_ADDRESS);
488
+ all_drops_reason = qed_rd(p_hwfn, p_ptt,
489
+ DORQ_REG_DB_DROP_DETAILS_REASON);
490
+
491
+ /* Log info */
492
+ DP_NOTICE(p_hwfn->cdev,
493
+ "Doorbell drop occurred\n"
494
+ "Address\t\t0x%08x\t(second BAR address)\n"
495
+ "FID\t\t0x%04x\t\t(Opaque FID)\n"
496
+ "Size\t\t0x%04x\t\t(in bytes)\n"
497
+ "1st drop reason\t0x%08x\t(details on first drop since last handling)\n"
498
+ "Sticky reasons\t0x%08x\t(all drop reasons since last handling)\n",
499
+ address,
500
+ GET_FIELD(details, QED_DORQ_ATTENTION_OPAQUE),
501
+ GET_FIELD(details, QED_DORQ_ATTENTION_SIZE) * 4,
502
+ first_drop_reason, all_drops_reason);
503
+
504
+ /* Clear the doorbell drop details and prepare for next drop */
505
+ qed_wr(p_hwfn, p_ptt, DORQ_REG_DB_DROP_DETAILS_REL, 0);
506
+
507
+ /* Mark interrupt as handled (note: even if drop was due to a different
508
+ * reason than overflow we mark as handled)
509
+ */
510
+ qed_wr(p_hwfn,
511
+ p_ptt,
512
+ DORQ_REG_INT_STS_WR,
513
+ DORQ_REG_INT_STS_DB_DROP |
514
+ DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR);
515
+
516
+ /* If there are no indications other than drop indications, success */
517
+ if ((int_sts & ~(DORQ_REG_INT_STS_DB_DROP |
518
+ DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR |
519
+ DORQ_REG_INT_STS_DORQ_FIFO_AFULL)) == 0)
520
+ return 0;
521
+ }
522
+
523
+ /* Some other indication was present - non recoverable */
524
+ DP_INFO(p_hwfn, "DORQ fatal attention\n");
525
+
526
+ return -EINVAL;
527
+}
528
+
529
+static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
530
+{
531
+ p_hwfn->db_recovery_info.dorq_attn = true;
532
+ qed_dorq_attn_overflow(p_hwfn);
533
+
534
+ return qed_dorq_attn_int_sts(p_hwfn);
535
+}
536
+
537
+static void qed_dorq_attn_handler(struct qed_hwfn *p_hwfn)
538
+{
539
+ if (p_hwfn->db_recovery_info.dorq_attn)
540
+ goto out;
541
+
542
+ /* Call DORQ callback if the attention was missed */
543
+ qed_dorq_attn_cb(p_hwfn);
544
+out:
545
+ p_hwfn->db_recovery_info.dorq_attn = false;
388546 }
389547
390548 /* Instead of major changes to the data-structure, we have a some 'special'
....@@ -422,7 +580,7 @@
422580 {"PGLUE misc_flr", ATTENTION_SINGLE,
423581 NULL, MAX_BLOCK_ID},
424582 {"PGLUE B RBC", ATTENTION_PAR_INT,
425
- qed_pglub_rbc_attn_cb, BLOCK_PGLUE_B},
583
+ qed_pglueb_rbc_attn_cb, BLOCK_PGLUE_B},
426584 {"PGLUE misc_mctp", ATTENTION_SINGLE,
427585 NULL, MAX_BLOCK_ID},
428586 {"Flash event", ATTENTION_SINGLE, NULL, MAX_BLOCK_ID},
....@@ -445,13 +603,15 @@
445603
446604 {
447605 { /* After Invert 4 */
448
- {"General Attention 32", ATTENTION_SINGLE,
449
- NULL, MAX_BLOCK_ID},
606
+ {"General Attention 32", ATTENTION_SINGLE |
607
+ ATTENTION_CLEAR_ENABLE, qed_fw_assertion,
608
+ MAX_BLOCK_ID},
450609 {"General Attention %d",
451610 (2 << ATTENTION_LENGTH_SHIFT) |
452611 (33 << ATTENTION_OFFSET_SHIFT), NULL, MAX_BLOCK_ID},
453
- {"General Attention 35", ATTENTION_SINGLE,
454
- NULL, MAX_BLOCK_ID},
612
+ {"General Attention 35", ATTENTION_SINGLE |
613
+ ATTENTION_CLEAR_ENABLE, qed_general_attention_35,
614
+ MAX_BLOCK_ID},
455615 {"NWS Parity",
456616 ATTENTION_PAR | ATTENTION_BB_DIFFERENT |
457617 ATTENTION_BB(AEU_INVERT_REG_SPECIAL_CNIG_0),
....@@ -654,27 +814,22 @@
654814 {
655815 u16 rc = 0, index;
656816
657
- /* Make certain HW write took affect */
658
- mmiowb();
659
-
660817 index = le16_to_cpu(p_sb_desc->sb_attn->sb_index);
661818 if (p_sb_desc->index != index) {
662819 p_sb_desc->index = index;
663820 rc = QED_SB_ATT_IDX;
664821 }
665822
666
- /* Make certain we got a consistent view with HW */
667
- mmiowb();
668
-
669823 return rc;
670824 }
671825
672826 /**
673
- * @brief qed_int_assertion - handles asserted attention bits
827
+ * qed_int_assertion() - Handle asserted attention bits.
674828 *
675
- * @param p_hwfn
676
- * @param asserted_bits newly asserted bits
677
- * @return int
829
+ * @p_hwfn: HW device data.
830
+ * @asserted_bits: Newly asserted bits.
831
+ *
832
+ * Return: Zero value.
678833 */
679834 static int qed_int_assertion(struct qed_hwfn *p_hwfn, u16 asserted_bits)
680835 {
....@@ -734,16 +889,17 @@
734889 }
735890
736891 /**
737
- * @brief qed_int_deassertion_aeu_bit - handles the effects of a single
738
- * cause of the attention
892
+ * qed_int_deassertion_aeu_bit() - Handles the effects of a single
893
+ * cause of the attention.
739894 *
740
- * @param p_hwfn
741
- * @param p_aeu - descriptor of an AEU bit which caused the attention
742
- * @param aeu_en_reg - register offset of the AEU enable reg. which configured
743
- * this bit to this group.
744
- * @param bit_index - index of this bit in the aeu_en_reg
895
+ * @p_hwfn: HW device data.
896
+ * @p_aeu: Descriptor of an AEU bit which caused the attention.
897
+ * @aeu_en_reg: Register offset of the AEU enable reg. which configured
898
+ * this bit to this group.
899
+ * @p_bit_name: AEU bit description for logging purposes.
900
+ * @bitmask: Index of this bit in the aeu_en_reg.
745901 *
746
- * @return int
902
+ * Return: Zero on success, negative errno otherwise.
747903 */
748904 static int
749905 qed_int_deassertion_aeu_bit(struct qed_hwfn *p_hwfn,
....@@ -773,9 +929,12 @@
773929 qed_int_attn_print(p_hwfn, p_aeu->block_index,
774930 ATTN_TYPE_INTERRUPT, !b_fatal);
775931
776
-
777
- /* If the attention is benign, no need to prevent it */
778
- if (!rc)
932
+ /* Reach assertion if attention is fatal */
933
+ if (b_fatal)
934
+ qed_hw_err_notify(p_hwfn, p_hwfn->p_dpc_ptt, QED_HW_ERR_HW_ATTN,
935
+ "`%s': Fatal attention\n",
936
+ p_bit_name);
937
+ else /* If the attention is benign, no need to prevent it */
779938 goto out;
780939
781940 /* Prevent this Attention from being asserted in the future */
....@@ -789,12 +948,12 @@
789948 }
790949
791950 /**
792
- * @brief qed_int_deassertion_parity - handle a single parity AEU source
951
+ * qed_int_deassertion_parity() - Handle a single parity AEU source.
793952 *
794
- * @param p_hwfn
795
- * @param p_aeu - descriptor of an AEU bit which caused the parity
796
- * @param aeu_en_reg - address of the AEU enable register
797
- * @param bit_index
953
+ * @p_hwfn: HW device data.
954
+ * @p_aeu: Descriptor of an AEU bit which caused the parity.
955
+ * @aeu_en_reg: Address of the AEU enable register.
956
+ * @bit_index: Index (0-31) of an AEU bit.
798957 */
799958 static void qed_int_deassertion_parity(struct qed_hwfn *p_hwfn,
800959 struct aeu_invert_reg_bit *p_aeu,
....@@ -827,12 +986,13 @@
827986 }
828987
829988 /**
830
- * @brief - handles deassertion of previously asserted attentions.
989
+ * qed_int_deassertion() - Handle deassertion of previously asserted
990
+ * attentions.
831991 *
832
- * @param p_hwfn
833
- * @param deasserted_bits - newly deasserted bits
834
- * @return int
992
+ * @p_hwfn: HW device data.
993
+ * @deasserted_bits: newly deasserted bits.
835994 *
995
+ * Return: Zero value.
836996 */
837997 static int qed_int_deassertion(struct qed_hwfn *p_hwfn,
838998 u16 deasserted_bits)
....@@ -960,6 +1120,9 @@
9601120 }
9611121 }
9621122
1123
+ /* Handle missed DORQ attention */
1124
+ qed_dorq_attn_handler(p_hwfn);
1125
+
9631126 /* Clear IGU indication for the deasserted bits */
9641127 DIRECT_REG_WR((u8 __iomem *)p_hwfn->regview +
9651128 GTT_BAR0_MAP_REG_IGU_CMD +
....@@ -1037,27 +1200,25 @@
10371200 static void qed_sb_ack_attn(struct qed_hwfn *p_hwfn,
10381201 void __iomem *igu_addr, u32 ack_cons)
10391202 {
1040
- struct igu_prod_cons_update igu_ack = { 0 };
1203
+ u32 igu_ack;
10411204
1042
- igu_ack.sb_id_and_flags =
1043
- ((ack_cons << IGU_PROD_CONS_UPDATE_SB_INDEX_SHIFT) |
1044
- (1 << IGU_PROD_CONS_UPDATE_UPDATE_FLAG_SHIFT) |
1045
- (IGU_INT_NOP << IGU_PROD_CONS_UPDATE_ENABLE_INT_SHIFT) |
1046
- (IGU_SEG_ACCESS_ATTN <<
1047
- IGU_PROD_CONS_UPDATE_SEGMENT_ACCESS_SHIFT));
1205
+ igu_ack = ((ack_cons << IGU_PROD_CONS_UPDATE_SB_INDEX_SHIFT) |
1206
+ (1 << IGU_PROD_CONS_UPDATE_UPDATE_FLAG_SHIFT) |
1207
+ (IGU_INT_NOP << IGU_PROD_CONS_UPDATE_ENABLE_INT_SHIFT) |
1208
+ (IGU_SEG_ACCESS_ATTN <<
1209
+ IGU_PROD_CONS_UPDATE_SEGMENT_ACCESS_SHIFT));
10481210
1049
- DIRECT_REG_WR(igu_addr, igu_ack.sb_id_and_flags);
1211
+ DIRECT_REG_WR(igu_addr, igu_ack);
10501212
10511213 /* Both segments (interrupts & acks) are written to same place address;
10521214 * Need to guarantee all commands will be received (in-order) by HW.
10531215 */
1054
- mmiowb();
10551216 barrier();
10561217 }
10571218
1058
-void qed_int_sp_dpc(unsigned long hwfn_cookie)
1219
+void qed_int_sp_dpc(struct tasklet_struct *t)
10591220 {
1060
- struct qed_hwfn *p_hwfn = (struct qed_hwfn *)hwfn_cookie;
1221
+ struct qed_hwfn *p_hwfn = from_tasklet(p_hwfn, t, sp_dpc);
10611222 struct qed_pi_info *pi_info = NULL;
10621223 struct qed_sb_attn_info *sb_attn;
10631224 struct qed_sb_info *sb_info;
....@@ -1261,16 +1422,16 @@
12611422 u8 pf_id, u16 vf_number, u8 vf_valid)
12621423 {
12631424 struct qed_dev *cdev = p_hwfn->cdev;
1264
- u32 cau_state;
1425
+ u32 cau_state, params = 0, data = 0;
12651426 u8 timer_res;
12661427
12671428 memset(p_sb_entry, 0, sizeof(*p_sb_entry));
12681429
1269
- SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_PF_NUMBER, pf_id);
1270
- SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_VF_NUMBER, vf_number);
1271
- SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_VF_VALID, vf_valid);
1272
- SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_SB_TIMESET0, 0x7F);
1273
- SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_SB_TIMESET1, 0x7F);
1430
+ SET_FIELD(params, CAU_SB_ENTRY_PF_NUMBER, pf_id);
1431
+ SET_FIELD(params, CAU_SB_ENTRY_VF_NUMBER, vf_number);
1432
+ SET_FIELD(params, CAU_SB_ENTRY_VF_VALID, vf_valid);
1433
+ SET_FIELD(params, CAU_SB_ENTRY_SB_TIMESET0, 0x7F);
1434
+ SET_FIELD(params, CAU_SB_ENTRY_SB_TIMESET1, 0x7F);
12741435
12751436 cau_state = CAU_HC_DISABLE_STATE;
12761437
....@@ -1289,7 +1450,8 @@
12891450 timer_res = 1;
12901451 else
12911452 timer_res = 2;
1292
- SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_TIMER_RES0, timer_res);
1453
+
1454
+ SET_FIELD(params, CAU_SB_ENTRY_TIMER_RES0, timer_res);
12931455
12941456 if (cdev->tx_coalesce_usecs <= 0x7F)
12951457 timer_res = 0;
....@@ -1297,10 +1459,13 @@
12971459 timer_res = 1;
12981460 else
12991461 timer_res = 2;
1300
- SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_TIMER_RES1, timer_res);
13011462
1302
- SET_FIELD(p_sb_entry->data, CAU_SB_ENTRY_STATE0, cau_state);
1303
- SET_FIELD(p_sb_entry->data, CAU_SB_ENTRY_STATE1, cau_state);
1463
+ SET_FIELD(params, CAU_SB_ENTRY_TIMER_RES1, timer_res);
1464
+ p_sb_entry->params = cpu_to_le32(params);
1465
+
1466
+ SET_FIELD(data, CAU_SB_ENTRY_STATE0, cau_state);
1467
+ SET_FIELD(data, CAU_SB_ENTRY_STATE1, cau_state);
1468
+ p_sb_entry->data = cpu_to_le32(data);
13041469 }
13051470
13061471 static void qed_int_cau_conf_pi(struct qed_hwfn *p_hwfn,
....@@ -1310,31 +1475,27 @@
13101475 enum qed_coalescing_fsm coalescing_fsm,
13111476 u8 timeset)
13121477 {
1313
- struct cau_pi_entry pi_entry;
13141478 u32 sb_offset, pi_offset;
1479
+ u32 prod = 0;
13151480
13161481 if (IS_VF(p_hwfn->cdev))
13171482 return;
13181483
1319
- sb_offset = igu_sb_id * PIS_PER_SB_E4;
1320
- memset(&pi_entry, 0, sizeof(struct cau_pi_entry));
1321
-
1322
- SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_PI_TIMESET, timeset);
1484
+ SET_FIELD(prod, CAU_PI_ENTRY_PI_TIMESET, timeset);
13231485 if (coalescing_fsm == QED_COAL_RX_STATE_MACHINE)
1324
- SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_FSM_SEL, 0);
1486
+ SET_FIELD(prod, CAU_PI_ENTRY_FSM_SEL, 0);
13251487 else
1326
- SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_FSM_SEL, 1);
1488
+ SET_FIELD(prod, CAU_PI_ENTRY_FSM_SEL, 1);
13271489
1490
+ sb_offset = igu_sb_id * PIS_PER_SB_E4;
13281491 pi_offset = sb_offset + pi_index;
1329
- if (p_hwfn->hw_init_done) {
1492
+
1493
+ if (p_hwfn->hw_init_done)
13301494 qed_wr(p_hwfn, p_ptt,
1331
- CAU_REG_PI_MEMORY + pi_offset * sizeof(u32),
1332
- *((u32 *)&(pi_entry)));
1333
- } else {
1334
- STORE_RT_REG(p_hwfn,
1335
- CAU_REG_PI_MEMORY_RT_OFFSET + pi_offset,
1336
- *((u32 *)&(pi_entry)));
1337
- }
1495
+ CAU_REG_PI_MEMORY + pi_offset * sizeof(u32), prod);
1496
+ else
1497
+ STORE_RT_REG(p_hwfn, CAU_REG_PI_MEMORY_RT_OFFSET + pi_offset,
1498
+ prod);
13381499 }
13391500
13401501 void qed_int_cau_conf_sb(struct qed_hwfn *p_hwfn,
....@@ -1353,10 +1514,10 @@
13531514
13541515 qed_dmae_host2grc(p_hwfn, p_ptt, (u64)(uintptr_t)&phys_addr,
13551516 CAU_REG_SB_ADDR_MEMORY +
1356
- igu_sb_id * sizeof(u64), 2, 0);
1517
+ igu_sb_id * sizeof(u64), 2, NULL);
13571518 qed_dmae_host2grc(p_hwfn, p_ptt, (u64)(uintptr_t)&sb_entry,
13581519 CAU_REG_SB_VAR_MEMORY +
1359
- igu_sb_id * sizeof(u64), 2, 0);
1520
+ igu_sb_id * sizeof(u64), 2, NULL);
13601521 } else {
13611522 /* Initialize Status Block Address */
13621523 STORE_RT_REG_AGG(p_hwfn,
....@@ -1686,9 +1847,6 @@
16861847 qed_wr(p_hwfn, p_ptt, IGU_REG_TRAILING_EDGE_LATCH, 0xfff);
16871848 qed_wr(p_hwfn, p_ptt, IGU_REG_ATTENTION_ENABLE, 0xfff);
16881849
1689
- /* Flush the writes to IGU */
1690
- mmiowb();
1691
-
16921850 /* Unmask AEU signals toward IGU */
16931851 qed_wr(p_hwfn, p_ptt, MISC_REG_AEU_MASK_ATTN_IGU, 0xff);
16941852 }
....@@ -1751,9 +1909,6 @@
17511909 barrier();
17521910
17531911 qed_wr(p_hwfn, p_ptt, IGU_REG_COMMAND_REG_CTRL, cmd_ctrl);
1754
-
1755
- /* Flush the write to IGU */
1756
- mmiowb();
17571912
17581913 /* calculate where to read the status bit from */
17591914 sb_bit = 1 << (igu_sb_id % 32);
....@@ -2097,9 +2252,9 @@
20972252 }
20982253
20992254 /**
2100
- * @brief Initialize igu runtime registers
2255
+ * qed_int_igu_init_rt() - Initialize IGU runtime registers.
21012256 *
2102
- * @param p_hwfn
2257
+ * @p_hwfn: HW device data.
21032258 */
21042259 void qed_int_igu_init_rt(struct qed_hwfn *p_hwfn)
21052260 {
....@@ -2130,33 +2285,13 @@
21302285
21312286 static void qed_int_sp_dpc_setup(struct qed_hwfn *p_hwfn)
21322287 {
2133
- tasklet_init(p_hwfn->sp_dpc,
2134
- qed_int_sp_dpc, (unsigned long)p_hwfn);
2288
+ tasklet_setup(&p_hwfn->sp_dpc, qed_int_sp_dpc);
21352289 p_hwfn->b_sp_dpc_enabled = true;
2136
-}
2137
-
2138
-static int qed_int_sp_dpc_alloc(struct qed_hwfn *p_hwfn)
2139
-{
2140
- p_hwfn->sp_dpc = kmalloc(sizeof(*p_hwfn->sp_dpc), GFP_KERNEL);
2141
- if (!p_hwfn->sp_dpc)
2142
- return -ENOMEM;
2143
-
2144
- return 0;
2145
-}
2146
-
2147
-static void qed_int_sp_dpc_free(struct qed_hwfn *p_hwfn)
2148
-{
2149
- kfree(p_hwfn->sp_dpc);
2150
- p_hwfn->sp_dpc = NULL;
21512290 }
21522291
21532292 int qed_int_alloc(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
21542293 {
21552294 int rc = 0;
2156
-
2157
- rc = qed_int_sp_dpc_alloc(p_hwfn);
2158
- if (rc)
2159
- return rc;
21602295
21612296 rc = qed_int_sp_sb_alloc(p_hwfn, p_ptt);
21622297 if (rc)
....@@ -2171,7 +2306,6 @@
21712306 {
21722307 qed_int_sp_sb_free(p_hwfn);
21732308 qed_int_sb_attn_free(p_hwfn);
2174
- qed_int_sp_dpc_free(p_hwfn);
21752309 }
21762310
21772311 void qed_int_setup(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
....@@ -2200,10 +2334,16 @@
22002334 cdev->hwfns[i].b_int_requested = false;
22012335 }
22022336
2337
+void qed_int_attn_clr_enable(struct qed_dev *cdev, bool clr_enable)
2338
+{
2339
+ cdev->attn_clr_en = clr_enable;
2340
+}
2341
+
22032342 int qed_int_set_timer_res(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
22042343 u8 timer_res, u16 sb_id, bool tx)
22052344 {
22062345 struct cau_sb_entry sb_entry;
2346
+ u32 params;
22072347 int rc;
22082348
22092349 if (!p_hwfn->hw_init_done) {
....@@ -2213,21 +2353,25 @@
22132353
22142354 rc = qed_dmae_grc2host(p_hwfn, p_ptt, CAU_REG_SB_VAR_MEMORY +
22152355 sb_id * sizeof(u64),
2216
- (u64)(uintptr_t)&sb_entry, 2, 0);
2356
+ (u64)(uintptr_t)&sb_entry, 2, NULL);
22172357 if (rc) {
22182358 DP_ERR(p_hwfn, "dmae_grc2host failed %d\n", rc);
22192359 return rc;
22202360 }
22212361
2362
+ params = le32_to_cpu(sb_entry.params);
2363
+
22222364 if (tx)
2223
- SET_FIELD(sb_entry.params, CAU_SB_ENTRY_TIMER_RES1, timer_res);
2365
+ SET_FIELD(params, CAU_SB_ENTRY_TIMER_RES1, timer_res);
22242366 else
2225
- SET_FIELD(sb_entry.params, CAU_SB_ENTRY_TIMER_RES0, timer_res);
2367
+ SET_FIELD(params, CAU_SB_ENTRY_TIMER_RES0, timer_res);
2368
+
2369
+ sb_entry.params = cpu_to_le32(params);
22262370
22272371 rc = qed_dmae_host2grc(p_hwfn, p_ptt,
22282372 (u64)(uintptr_t)&sb_entry,
22292373 CAU_REG_SB_VAR_MEMORY +
2230
- sb_id * sizeof(u64), 2, 0);
2374
+ sb_id * sizeof(u64), 2, NULL);
22312375 if (rc) {
22322376 DP_ERR(p_hwfn, "dmae_host2grc failed %d\n", rc);
22332377 return rc;