aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/qlogic/qed/qed_int.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-04-17 12:57:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-04-17 12:57:45 -0400
commit2a3a028fc61d03e80ac57091330eb514280bd5be (patch)
treec0f98d752faa37fed4d11231f08d368dce120786 /drivers/net/ethernet/qlogic/qed/qed_int.c
parent444fe991353987c1c9bc5ab1f903d01f1b4ad415 (diff)
parente6986423d28362aafe64d3757bbbc493f2687f8f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Handle init flow failures properly in iwlwifi driver, from Shahar S Matityahu. 2) mac80211 TXQs need to be unscheduled on powersave start, from Felix Fietkau. 3) SKB memory accounting fix in A-MDSU aggregation, from Felix Fietkau. 4) Increase RCU lock hold time in mlx5 FPGA code, from Saeed Mahameed. 5) Avoid checksum complete with XDP in mlx5, also from Saeed. 6) Fix netdev feature clobbering in ibmvnic driver, from Thomas Falcon. 7) Partial sent TLS record leak fix from Jakub Kicinski. 8) Reject zero size iova range in vhost, from Jason Wang. 9) Allow pending work to complete before clcsock release from Karsten Graul. 10) Fix XDP handling max MTU in thunderx, from Matteo Croce. 11) A lot of protocols look at the sa_family field of a sockaddr before validating it's length is large enough, from Tetsuo Handa. 12) Don't write to free'd pointer in qede ptp error path, from Colin Ian King. 13) Have to recompile IP options in ipv4_link_failure because it can be invoked from ARP, from Stephen Suryaputra. 14) Doorbell handling fixes in qed from Denis Bolotin. 15) Revert net-sysfs kobject register leak fix, it causes new problems. From Wang Hai. 16) Spectre v1 fix in ATM code, from Gustavo A. R. Silva. 17) Fix put of BROPT_VLAN_STATS_PER_PORT in bridging code, from Nikolay Aleksandrov. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (111 commits) socket: fix compat SO_RCVTIMEO_NEW/SO_SNDTIMEO_NEW tcp: tcp_grow_window() needs to respect tcp_space() ocelot: Clean up stats update deferred work ocelot: Don't sleep in atomic context (irqs_disabled()) net: bridge: fix netlink export of vlan_stats_per_port option qed: fix spelling mistake "faspath" -> "fastpath" tipc: set sysctl_tipc_rmem and named_timeout right range tipc: fix link established but not in session net: Fix missing meta data in skb with vlan packet net: atm: Fix potential Spectre v1 vulnerabilities net/core: work around section mismatch warning for ptp_classifier net: bridge: fix per-port af_packet sockets bnx2x: fix spelling mistake "dicline" -> "decline" route: Avoid crash from dereferencing NULL rt->from MAINTAINERS: normalize Woojung Huh's email address bonding: fix event handling for stacked bonds Revert "net-sysfs: Fix memory leak in netdev_register_kobject" rtnetlink: fix rtnl_valid_stats_req() nlmsg_len check qed: Fix the DORQ's attentions handling qed: Fix missing DORQ attentions ...
Diffstat (limited to 'drivers/net/ethernet/qlogic/qed/qed_int.c')
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_int.c83
1 files changed, 63 insertions, 20 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c
index e23980e301b6..8848d5bed6e5 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.c
@@ -378,6 +378,9 @@ static int qed_db_rec_flush_queue(struct qed_hwfn *p_hwfn,
378 u32 count = QED_DB_REC_COUNT; 378 u32 count = QED_DB_REC_COUNT;
379 u32 usage = 1; 379 u32 usage = 1;
380 380
381 /* Flush any pending (e)dpms as they may never arrive */
382 qed_wr(p_hwfn, p_ptt, DORQ_REG_DPM_FORCE_ABORT, 0x1);
383
381 /* wait for usage to zero or count to run out. This is necessary since 384 /* wait for usage to zero or count to run out. This is necessary since
382 * EDPM doorbell transactions can take multiple 64b cycles, and as such 385 * EDPM doorbell transactions can take multiple 64b cycles, and as such
383 * can "split" over the pci. Possibly, the doorbell drop can happen with 386 * can "split" over the pci. Possibly, the doorbell drop can happen with
@@ -406,51 +409,74 @@ static int qed_db_rec_flush_queue(struct qed_hwfn *p_hwfn,
406 409
407int qed_db_rec_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) 410int qed_db_rec_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
408{ 411{
409 u32 overflow; 412 u32 attn_ovfl, cur_ovfl;
410 int rc; 413 int rc;
411 414
412 overflow = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY); 415 attn_ovfl = test_and_clear_bit(QED_OVERFLOW_BIT,
413 DP_NOTICE(p_hwfn, "PF Overflow sticky 0x%x\n", overflow); 416 &p_hwfn->db_recovery_info.overflow);
414 if (!overflow) { 417 cur_ovfl = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY);
415 qed_db_recovery_execute(p_hwfn, DB_REC_ONCE); 418 if (!cur_ovfl && !attn_ovfl)
416 return 0; 419 return 0;
417 }
418 420
419 if (qed_edpm_enabled(p_hwfn)) { 421 DP_NOTICE(p_hwfn, "PF Overflow sticky: attn %u current %u\n",
422 attn_ovfl, cur_ovfl);
423
424 if (cur_ovfl && !p_hwfn->db_bar_no_edpm) {
420 rc = qed_db_rec_flush_queue(p_hwfn, p_ptt); 425 rc = qed_db_rec_flush_queue(p_hwfn, p_ptt);
421 if (rc) 426 if (rc)
422 return rc; 427 return rc;
423 } 428 }
424 429
425 /* Flush any pending (e)dpm as they may never arrive */
426 qed_wr(p_hwfn, p_ptt, DORQ_REG_DPM_FORCE_ABORT, 0x1);
427
428 /* Release overflow sticky indication (stop silently dropping everything) */ 430 /* Release overflow sticky indication (stop silently dropping everything) */
429 qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0); 431 qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0);
430 432
431 /* Repeat all last doorbells (doorbell drop recovery) */ 433 /* Repeat all last doorbells (doorbell drop recovery) */
432 qed_db_recovery_execute(p_hwfn, DB_REC_REAL_DEAL); 434 qed_db_recovery_execute(p_hwfn);
433 435
434 return 0; 436 return 0;
435} 437}
436 438
437static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn) 439static void qed_dorq_attn_overflow(struct qed_hwfn *p_hwfn)
438{ 440{
439 u32 int_sts, first_drop_reason, details, address, all_drops_reason;
440 struct qed_ptt *p_ptt = p_hwfn->p_dpc_ptt; 441 struct qed_ptt *p_ptt = p_hwfn->p_dpc_ptt;
442 u32 overflow;
441 int rc; 443 int rc;
442 444
443 int_sts = qed_rd(p_hwfn, p_ptt, DORQ_REG_INT_STS); 445 overflow = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY);
444 DP_NOTICE(p_hwfn->cdev, "DORQ attention. int_sts was %x\n", int_sts); 446 if (!overflow)
447 goto out;
448
449 /* Run PF doorbell recovery in next periodic handler */
450 set_bit(QED_OVERFLOW_BIT, &p_hwfn->db_recovery_info.overflow);
451
452 if (!p_hwfn->db_bar_no_edpm) {
453 rc = qed_db_rec_flush_queue(p_hwfn, p_ptt);
454 if (rc)
455 goto out;
456 }
457
458 qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0);
459out:
460 /* Schedule the handler even if overflow was not detected */
461 qed_periodic_db_rec_start(p_hwfn);
462}
463
464static int qed_dorq_attn_int_sts(struct qed_hwfn *p_hwfn)
465{
466 u32 int_sts, first_drop_reason, details, address, all_drops_reason;
467 struct qed_ptt *p_ptt = p_hwfn->p_dpc_ptt;
445 468
446 /* int_sts may be zero since all PFs were interrupted for doorbell 469 /* int_sts may be zero since all PFs were interrupted for doorbell
447 * overflow but another one already handled it. Can abort here. If 470 * overflow but another one already handled it. Can abort here. If
448 * This PF also requires overflow recovery we will be interrupted again. 471 * This PF also requires overflow recovery we will be interrupted again.
449 * The masked almost full indication may also be set. Ignoring. 472 * The masked almost full indication may also be set. Ignoring.
450 */ 473 */
474 int_sts = qed_rd(p_hwfn, p_ptt, DORQ_REG_INT_STS);
451 if (!(int_sts & ~DORQ_REG_INT_STS_DORQ_FIFO_AFULL)) 475 if (!(int_sts & ~DORQ_REG_INT_STS_DORQ_FIFO_AFULL))
452 return 0; 476 return 0;
453 477
478 DP_NOTICE(p_hwfn->cdev, "DORQ attention. int_sts was %x\n", int_sts);
479
454 /* check if db_drop or overflow happened */ 480 /* check if db_drop or overflow happened */
455 if (int_sts & (DORQ_REG_INT_STS_DB_DROP | 481 if (int_sts & (DORQ_REG_INT_STS_DB_DROP |
456 DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR)) { 482 DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR)) {
@@ -477,11 +503,6 @@ static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
477 GET_FIELD(details, QED_DORQ_ATTENTION_SIZE) * 4, 503 GET_FIELD(details, QED_DORQ_ATTENTION_SIZE) * 4,
478 first_drop_reason, all_drops_reason); 504 first_drop_reason, all_drops_reason);
479 505
480 rc = qed_db_rec_handler(p_hwfn, p_ptt);
481 qed_periodic_db_rec_start(p_hwfn);
482 if (rc)
483 return rc;
484
485 /* Clear the doorbell drop details and prepare for next drop */ 506 /* Clear the doorbell drop details and prepare for next drop */
486 qed_wr(p_hwfn, p_ptt, DORQ_REG_DB_DROP_DETAILS_REL, 0); 507 qed_wr(p_hwfn, p_ptt, DORQ_REG_DB_DROP_DETAILS_REL, 0);
487 508
@@ -507,6 +528,25 @@ static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
507 return -EINVAL; 528 return -EINVAL;
508} 529}
509 530
531static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
532{
533 p_hwfn->db_recovery_info.dorq_attn = true;
534 qed_dorq_attn_overflow(p_hwfn);
535
536 return qed_dorq_attn_int_sts(p_hwfn);
537}
538
539static void qed_dorq_attn_handler(struct qed_hwfn *p_hwfn)
540{
541 if (p_hwfn->db_recovery_info.dorq_attn)
542 goto out;
543
544 /* Call DORQ callback if the attention was missed */
545 qed_dorq_attn_cb(p_hwfn);
546out:
547 p_hwfn->db_recovery_info.dorq_attn = false;
548}
549
510/* Instead of major changes to the data-structure, we have a some 'special' 550/* Instead of major changes to the data-structure, we have a some 'special'
511 * identifiers for sources that changed meaning between adapters. 551 * identifiers for sources that changed meaning between adapters.
512 */ 552 */
@@ -1080,6 +1120,9 @@ static int qed_int_deassertion(struct qed_hwfn *p_hwfn,
1080 } 1120 }
1081 } 1121 }
1082 1122
1123 /* Handle missed DORQ attention */
1124 qed_dorq_attn_handler(p_hwfn);
1125
1083 /* Clear IGU indication for the deasserted bits */ 1126 /* Clear IGU indication for the deasserted bits */
1084 DIRECT_REG_WR((u8 __iomem *)p_hwfn->regview + 1127 DIRECT_REG_WR((u8 __iomem *)p_hwfn->regview +
1085 GTT_BAR0_MAP_REG_IGU_CMD + 1128 GTT_BAR0_MAP_REG_IGU_CMD +