From patchwork Tue Sep 19 01:30:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Mody, Rasesh" X-Patchwork-Id: 28900 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 02A981B249; Tue, 19 Sep 2017 03:31:45 +0200 (CEST) Received: from NAM02-CY1-obe.outbound.protection.outlook.com (mail-cys01nam02on0055.outbound.protection.outlook.com [104.47.37.55]) by dpdk.org (Postfix) with ESMTP id 508631B1B0 for ; Tue, 19 Sep 2017 03:31:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-cavium-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=EkHb2nO2zUzUlc5vp12k2kGVol3trufkJpV/24/t5Tw=; b=Mt8ug+o6Xf4KshQWRdnuaENqx2V9d4+boASpSL6PVLHNdp/BzQaXrtYAnvg0S9H2j43WnTlvqqSHmfbJ2Tq2fqzNc3SIy3ymyD1n6tA89t1K+7pmmLH5uT0ht57jGmxMsrr4DW41d+uPR99Xz86OTy2lVExFIBWWEfTdkDYMX0c= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Rasesh.Mody@cavium.com; Received: from cavium.com (198.186.0.2) by SN4PR0701MB3838.namprd07.prod.outlook.com (2603:10b6:803:4f::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.56.11; Tue, 19 Sep 2017 01:31:23 +0000 From: Rasesh Mody To: dev@dpdk.org, ferruh.yigit@intel.com Cc: Rasesh Mody , Dept-EngDPDKDev@cavium.com Date: Mon, 18 Sep 2017 18:30:05 -0700 Message-Id: <1505784633-1171-26-git-send-email-rasesh.mody@cavium.com> X-Mailer: git-send-email 1.7.10.3 In-Reply-To: <1505784633-1171-1-git-send-email-rasesh.mody@cavium.com> References: <1505784633-1171-1-git-send-email-rasesh.mody@cavium.com> MIME-Version: 1.0 X-Originating-IP: [198.186.0.2] X-ClientProxiedBy: SN4PR0501CA0015.namprd05.prod.outlook.com (2603:10b6:803:40::28) To SN4PR0701MB3838.namprd07.prod.outlook.com (2603:10b6:803:4f::13) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 42be1aca-ed11-4ae7-7a54-08d4fefe235c X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(300000500095)(300135000095)(300000501095)(300135300095)(22001)(300000502095)(300135100095)(2017030254152)(300000503095)(300135400095)(2017052603199)(201703131423075)(201703031133081)(201702281549075)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095); SRVR:SN4PR0701MB3838; X-Microsoft-Exchange-Diagnostics: 1; SN4PR0701MB3838; 3:VCquIsN0uhJaOF5gxM7ue+klsbW1gCBFVnu8GajFsArOkeltyI+kXiT03cZPZjUa5ggxd46W8Xvt1M87/atcTfXZ1MMM2i8loGTVsBxSPqz80Mr3Rn4ZTshWsguGHIPtXRPqX+ITLaez81OckCUVrtD6vE5UXjQjaMydNdMtKluyI7eJRW4I3Xb6KaY3SEDHlQdENiRmULUuV1m7oCPepQrvTr5JkltBsOEb8QqsjdA7hu7ay7hiiPr70bBnjjeU; 25:jrtx4jFCWHWTrnEWs4Ad8uaS4+n+BDqMap4BQnvRGb2GVq+LMWP1Q4JWpmKH5SwyYin3+GLTkxS6b073MdsInhUbAQtc0/QnUmCjXbrSk+iW2+vXjVzBrrCgFYqnH0lJbkjWlHA3awS94feTBvdjj0TmLIACUE7v83ucH4BPlBWIWObm3rmTBqNqU4ugN1UQXmWnnDhdPwKooEGL8uCzzS1BdcWew5M8eqt5rs82smkc2E3gg7Zk0Ulolw6gcR/DilLExqDjve+ni2B+9keCOSWk5LFFbJ870Ub1rZXKTtNNNnnHIxiVrK6q+/11mJPuCVpjJX4AHWiecEL+d5djoQ==; 31:8gtw4b4W4zvfmfXFQO6pQEUVxAqQ97OwIJDXdHmCEvkZqXg7+rw2BNlWj/kn4nIqFf9i5zpoihrs6B9/1/I7mI1pfSitUPde1tA2kJaqI1URAbBFNB44i4lCj9rrbHmAmu5JrDgBJbQoZZUeNfnbJvDRLZxoJa9gGF79fgetfFchSs6vCwS9lmTAR1QOH16OQ8ztc3RS3PM10tL+f3/L6Y60PgHC/+0Pw1aRq02mnZI= X-MS-TrafficTypeDiagnostic: SN4PR0701MB3838: X-Microsoft-Exchange-Diagnostics: 1; SN4PR0701MB3838; 20:eqzI/eaQG7V4J3pjKzeXdNL/OMbxcml+Ev0dMNI80b/18+PPPCTXYrG+wvVlLRI5gncdK2E6JZGSMwk0xqT560CRyPsb1Fkknuj3aXMu0j/BXMTmQGrSkoyrJbLEC22c1Khqv7pwuoGwdfBAejuS79beQ2vkV3KpPyP6sRkNs86RsgOnNghKLkQKLL+5VJa1o8b7XafxjpXFXcb/aW7DS4U1T/1+69IbLg+xjXaZ/G4bTebaz/ZKqhzYsdGaA3cP0cqcEO3rimaulIhs2nIdgN5/wcz5ZaV7gdbNiVmF0wOpIKi8Gw5nJK+Bn3cRf2FcW/B0hkQYEq7IoScXoOE2xZ9mmJRMb7xu63yUVUM5BbGJH2dDp5gUDbu+VrW/IKFnp5mS2zshlBPLSmJHZFM9dY1gFRrgfZDXENXxS63uTEqECYCfW764g/26Tj3Yg0ruS0ZS/ak4pQBioszlYNv60Sb3CRF9YoU1VY8Y1OmjLMhWpRi3eb/ySz6c/zP1SiNq; 4:lhavIwoYpP90I8XX4kd9DYHdug20ActZK5YRk2Gc6xzpoeasYq5q3O0rHWh0YTvXyXbSGVOxE+mne5rTC/VUxj0tlYTuNZATuv+gat0BRuWbV/rOhgk1jk4aHUhIyJgTCwGsemwaBk/7s8J+OadddfRKKaMkc7yy/9PM7tnCN8XtKLUPwDi/D/gTUj2dCRN5BuwzFWAd310ihereUCrmj3tFx9mOVoCr9v+AT6/HDHcc/xkBWDvxnKK65ya2qCAz X-Exchange-Antispam-Report-Test: UriScan:; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(5005006)(8121501046)(100000703101)(100105400095)(10201501046)(93006095)(93001095)(3002001)(6041248)(20161123555025)(20161123562025)(20161123558100)(20161123560025)(20161123564025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:SN4PR0701MB3838; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:SN4PR0701MB3838; X-Forefront-PRVS: 04359FAD81 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6009001)(376002)(346002)(199003)(189002)(48376002)(33646002)(68736007)(316002)(21086003)(16526017)(16586007)(72206003)(36756003)(575784001)(478600001)(97736004)(86362001)(66066001)(25786009)(69596002)(47776003)(50986999)(81166006)(8936002)(50226002)(8676002)(5660300001)(7736002)(53936002)(305945005)(81156014)(55016002)(50466002)(76176999)(551934003)(6116002)(3846002)(2950100002)(101416001)(4326008)(4720700003)(2906002)(107886003)(6666003)(189998001)(106356001)(5003940100001)(105586002); DIR:OUT; SFP:1101; SCL:1; SRVR:SN4PR0701MB3838; H:cavium.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: cavium.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; SN4PR0701MB3838; 23:l1lThcXFqH5a1Wr7DM/1IvIgG/TvCd34mC0pn5L?= m8SvOxdbUKVTqukeMgOSQFM2QCl9HZ2KPH7ww0FgkKHijgEUrKEdtso7SbMiioT/RMLrYGTa6mfEyeNW+35R15+F/qR/P6WEI8xEiartDcyJJHTLDAGpnDw1S7dn1RLZq/a9jY+OyX0hQLpDHA7QsMCW67r8GzyUrLyYQVPvLdiCYScolKWcIA0pNRaGlSf4ksBLkNrTh2XzS8bmhqL6Le1Y7fUKzdEFCobgaEQ2T7dwoIRHkHd5BTTOR8Efaguv3o5BTtEjCCrPlO2DDSvRXI+c7H/CGpeshMyx90w+o8HV4CxnIyRItySWWWL+fJ/TM0Fr2lYeUTipmND9zeVw/4cF1hiXJKcMB0PcFndCNyKus+vQejBi2PfrzEV6+3UE0mlnTdUABcm/wdsfXBhPoL5od8OgMB5yso5qkRKLnJAUEPbfusX4glHK81N3Ak86jK9CSa73ySZfY/V/aHgmxgv48JkUJeM7fxJJuYAc0gTyI4fh6GaWQZ5Bga2y1ztWEpCElhOo7HDcrd2AbTePZ408tJUwdWtLu80VYYu4G6IBlv4hu2wTZBGoaznJT4sI7vFrQCpnT04ZxH1UlpMhs4Mx9XY8xGc8gK8OhWAzcUh1vJ+EF1jAM3p8PPSZuX52s0GcCz9BLNBeq/QS3ObcgvnACOJ4oOywUSNHGqYfFaS08stRbjLxzbsPAuZHL4El+ah/icojj36iDAfpHmhd0vqhsI9eF5PeRXRIEcV/fkCvcP073IUM3lcIp+G09EW3j6/JfWPVhmxh00LMzyiLWSSOceC9bR99fGBa4FWxbWIWHzOJFaNB91IU416NwRVOvCzjkWdc1mUAkf2oPJx5mm0DRuqn2ypJPYJulS9BLC1hArtkLmzM9t++g4UyWp8k4mmqgfCbSb6jOrm5UVt/ltnQ9OU+NAPADpAbCIE3hAWxGywqNQ16f1Attr5Tl8TSwA0ymXuLFMFWWQv6DgS/+Wi3IghPl7bStXiSj9gCLU7uSLBoRI0CMMija7xeg8tXD2ITU4UOsX61bG144ufi5rBrYUaO8f2sR3dQSUdaorJqWHaWc+9SDwKeU4/2qOeC1wIBDwPh2kQCxMCtZZk5ekD3abeCXOD83rp9uWitLF9zI7w== X-Microsoft-Exchange-Diagnostics: 1; SN4PR0701MB3838; 6:ozTGqOYbKppmvu/te1Vwb1OoZJDPcUptFyyYPreKepaI4fkLNLevg2an0x2J+I8Q7KwOJC81OBHFqqjJWTi/JRrWtfZzapTaunutLHbY/0mRnXJ5TfAV946xTrODbW3eIuRi6uX05I7wMFxdZ+2zJkNel+/IzTn94X+L5pBp6KDe0MGWTbC/7fR1Yk+zt95k2Hn0c/hChHA08Ul26fgO/6lZvJ5iQKvNntj1CHN4Xwp99vRzfxEkGqfAovY+Ul3HwqJH+DT8VQzNgXFjh2m5uJLl5ivF2AShTT/wUgVGtRvQCiGQXsuK/fXlOG5V6oo+R79hH7MrJ56ywHckbcETCw==; 5:IPoldQ5OtWclBnG+Aqs2Wh+SIZuSTcSgFaiiWhBgBGFp5ckJl2sLXREU6wOdd2d12mp+jolVNDFlTzE4HquYHm8p/QMmXikNsk1GhVCHSWZoI9AVEYAaL+z3Zu/zb/oZJ9btE91nDtOplizAow6h6A==; 24:rQYkOEWPcZ41iJ/d8F7zMei9pFPM5ushLedvuYzjMBl+9N+VmJE9Kfi3GIH57/YS46Rjv14R+Kw7v0Krr1ZpRrWpfDbJB68FjCoMJ1OYtxY=; 7:9axIx2umrzBt315Bqg8uFSst4kHTJnAM8VDtkr4C+uwyuq2jhcslsRyX9nEi85RCBv90/AHDjodJPz5kXOAr4IbNk2k+XfgANFFZQfZPDx6RCnknKlSsNnWK+SucVslkmN3ffLwX3VnwVgUDSPOUtgycwjFAkhnISVYP6ntaBnP+4rmLrCjuJJBuIQOyOwffsF5N85jhxTH36Gs9DuDsG1Pj1TvYXwCFZFwajoevFs8= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: cavium.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Sep 2017 01:31:23.1837 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 711e4ccf-2e9b-4bcf-a551-4094005b6194 X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN4PR0701MB3838 Subject: [dpdk-dev] [PATCH 25/53] net/qede/base: add support for doorbell overflow recovery X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add support for doorbell overflow recovery mechanism: The doorbell recovery mechanism consists of a list of entries which represent doorbelling entities (l2 queues, roce sq/rq/cqs, the slowpath spq, etc). Each entity needs to register with the mechanism and provide the parameters describing it's doorbell, including a location where last used doorbell data can be found. The doorbell execute function will traverse the list and doorbell all of the registered entries. Signed-off-by: Rasesh Mody --- drivers/net/qede/base/bcm_osal.h | 3 + drivers/net/qede/base/ecore.h | 24 ++- drivers/net/qede/base/ecore_dev.c | 322 ++++++++++++++++++++++++++++++++- drivers/net/qede/base/ecore_dev_api.h | 39 ++++ drivers/net/qede/base/ecore_int.c | 141 +++++++++++++-- drivers/net/qede/base/ecore_spq.c | 51 ++++-- drivers/net/qede/base/ecore_spq.h | 3 + drivers/net/qede/base/reg_addr.h | 10 + drivers/net/qede/qede_main.c | 1 + 9 files changed, 557 insertions(+), 37 deletions(-) diff --git a/drivers/net/qede/base/bcm_osal.h b/drivers/net/qede/base/bcm_osal.h index f4c7028..70b1a7f 100644 --- a/drivers/net/qede/base/bcm_osal.h +++ b/drivers/net/qede/base/bcm_osal.h @@ -148,6 +148,9 @@ void *osal_dma_alloc_coherent_aligned(struct ecore_dev *, dma_addr_t *, ((u8 *)(uintptr_t)(_p_hwfn->doorbells) + \ (_db_addr)), (u32)_val) +#define DIRECT_REG_WR64(hwfn, addr, value) nothing +#define DIRECT_REG_RD64(hwfn, addr) 0 + /* Mutexes */ typedef pthread_mutex_t osal_mutex_t; diff --git a/drivers/net/qede/base/ecore.h b/drivers/net/qede/base/ecore.h index 2d2f6f3..d921d9e 100644 --- a/drivers/net/qede/base/ecore.h +++ b/drivers/net/qede/base/ecore.h @@ -351,6 +351,12 @@ enum ecore_hw_err_type { }; #endif +enum ecore_db_rec_exec { + DB_REC_DRY_RUN, + DB_REC_REAL_DEAL, + DB_REC_ONCE, +}; + struct ecore_hw_info { /* PCI personality */ enum ecore_pci_personality personality; @@ -479,6 +485,12 @@ struct ecore_qm_info { u8 num_pf_rls; }; +struct ecore_db_recovery_info { + osal_list_t list; + osal_spinlock_t lock; + u32 db_recovery_counter; +}; + struct storm_stats { u32 address; u32 len; @@ -605,6 +617,9 @@ struct ecore_hwfn { /* L2-related */ struct ecore_l2_info *p_l2_info; + /* Mechanism for recovering from doorbell drop */ + struct ecore_db_recovery_info db_recovery_info; + /* @DPDK */ struct ecore_ptt *p_arfs_ptt; }; @@ -860,6 +875,13 @@ void ecore_set_fw_mac_addr(__le16 *fw_msb, __le16 *fw_mid, __le16 *fw_lsb, u16 ecore_get_cm_pq_idx_vf(struct ecore_hwfn *p_hwfn, u16 vf); u16 ecore_get_cm_pq_idx_rl(struct ecore_hwfn *p_hwfn, u8 qpid); +const char *ecore_hw_get_resc_name(enum ecore_resources res_id); + +/* doorbell recovery mechanism */ +void ecore_db_recovery_dp(struct ecore_hwfn *p_hwfn); +void ecore_db_recovery_execute(struct ecore_hwfn *p_hwfn, + enum ecore_db_rec_exec); + /* amount of resources used in qm init */ u8 ecore_init_qm_get_num_tcs(struct ecore_hwfn *p_hwfn); u16 ecore_init_qm_get_num_vfs(struct ecore_hwfn *p_hwfn); @@ -869,6 +891,4 @@ void ecore_set_fw_mac_addr(__le16 *fw_msb, __le16 *fw_mid, __le16 *fw_lsb, #define ECORE_LEADING_HWFN(dev) (&dev->hwfns[0]) -const char *ecore_hw_get_resc_name(enum ecore_resources res_id); - #endif /* __ECORE_H */ diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c index 2fe30d7..711a824 100644 --- a/drivers/net/qede/base/ecore_dev.c +++ b/drivers/net/qede/base/ecore_dev.c @@ -42,6 +42,318 @@ static osal_spinlock_t qm_lock; static bool qm_lock_init; +/******************** Doorbell Recovery *******************/ +/* The doorbell recovery mechanism consists of a list of entries which represent + * doorbelling entities (l2 queues, roce sq/rq/cqs, the slowpath spq, etc). Each + * entity needs to register with the mechanism and provide the parameters + * describing it's doorbell, including a location where last used doorbell data + * can be found. The doorbell execute function will traverse the list and + * doorbell all of the registered entries. + */ +struct ecore_db_recovery_entry { + osal_list_entry_t list_entry; + void OSAL_IOMEM *db_addr; + void *db_data; + enum ecore_db_rec_width db_width; + enum ecore_db_rec_space db_space; + u8 hwfn_idx; +}; + +/* display a single doorbell recovery entry */ +void ecore_db_recovery_dp_entry(struct ecore_hwfn *p_hwfn, + struct ecore_db_recovery_entry *db_entry, + const char *action) +{ + DP_VERBOSE(p_hwfn, ECORE_MSG_SPQ, "(%s: db_entry %p, addr %p, data %p, width %s, %s space, hwfn %d)\n", + action, db_entry, db_entry->db_addr, db_entry->db_data, + db_entry->db_width == DB_REC_WIDTH_32B ? "32b" : "64b", + db_entry->db_space == DB_REC_USER ? "user" : "kernel", + db_entry->hwfn_idx); +} + +/* doorbell address sanity (address within doorbell bar range) */ +bool ecore_db_rec_sanity(struct ecore_dev *p_dev, void OSAL_IOMEM *db_addr, + void *db_data) +{ + /* make sure doorbell address is within the doorbell bar */ + if (db_addr < p_dev->doorbells || (u8 *)db_addr > + (u8 *)p_dev->doorbells + p_dev->db_size) { + OSAL_WARN(true, + "Illegal doorbell address: %p. Legal range for doorbell addresses is [%p..%p]\n", + db_addr, p_dev->doorbells, + (u8 *)p_dev->doorbells + p_dev->db_size); + return false; + } + + /* make sure doorbell data pointer is not null */ + if (!db_data) { + OSAL_WARN(true, "Illegal doorbell data pointer: %p", db_data); + return false; + } + + return true; +} + +/* find hwfn according to the doorbell address */ +struct ecore_hwfn *ecore_db_rec_find_hwfn(struct ecore_dev *p_dev, + void OSAL_IOMEM *db_addr) +{ + struct ecore_hwfn *p_hwfn; + + /* In CMT doorbell bar is split down the middle between engine 0 and + * enigne 1 + */ + if (p_dev->num_hwfns > 1) + p_hwfn = db_addr < p_dev->hwfns[1].doorbells ? + &p_dev->hwfns[0] : &p_dev->hwfns[1]; + else + p_hwfn = ECORE_LEADING_HWFN(p_dev); + + return p_hwfn; +} + +/* add a new entry to the doorbell recovery mechanism */ +enum _ecore_status_t ecore_db_recovery_add(struct ecore_dev *p_dev, + void OSAL_IOMEM *db_addr, + void *db_data, + enum ecore_db_rec_width db_width, + enum ecore_db_rec_space db_space) +{ + struct ecore_db_recovery_entry *db_entry; + struct ecore_hwfn *p_hwfn; + + /* shortcircuit VFs, for now */ + if (IS_VF(p_dev)) { + DP_VERBOSE(p_dev, ECORE_MSG_IOV, "db recovery - skipping VF doorbell\n"); + return ECORE_SUCCESS; + } + + /* sanitize doorbell address */ + if (!ecore_db_rec_sanity(p_dev, db_addr, db_data)) + return ECORE_INVAL; + + /* obtain hwfn from doorbell address */ + p_hwfn = ecore_db_rec_find_hwfn(p_dev, db_addr); + + /* create entry */ + db_entry = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL, sizeof(*db_entry)); + if (!db_entry) { + DP_NOTICE(p_dev, false, "Failed to allocate a db recovery entry\n"); + return ECORE_NOMEM; + } + + /* populate entry */ + db_entry->db_addr = db_addr; + db_entry->db_data = db_data; + db_entry->db_width = db_width; + db_entry->db_space = db_space; + db_entry->hwfn_idx = p_hwfn->my_id; + + /* display */ + ecore_db_recovery_dp_entry(p_hwfn, db_entry, "Adding"); + + /* protect the list */ + OSAL_SPIN_LOCK(&p_hwfn->db_recovery_info.lock); + OSAL_LIST_PUSH_TAIL(&db_entry->list_entry, + &p_hwfn->db_recovery_info.list); + OSAL_SPIN_UNLOCK(&p_hwfn->db_recovery_info.lock); + + return ECORE_SUCCESS; +} + +/* remove an entry from the doorbell recovery mechanism */ +enum _ecore_status_t ecore_db_recovery_del(struct ecore_dev *p_dev, + void OSAL_IOMEM *db_addr, + void *db_data) +{ + struct ecore_db_recovery_entry *db_entry = OSAL_NULL; + enum _ecore_status_t rc = ECORE_INVAL; + struct ecore_hwfn *p_hwfn; + + /* shortcircuit VFs, for now */ + if (IS_VF(p_dev)) { + DP_VERBOSE(p_dev, ECORE_MSG_IOV, "db recovery - skipping VF doorbell\n"); + return ECORE_SUCCESS; + } + + /* sanitize doorbell address */ + if (!ecore_db_rec_sanity(p_dev, db_addr, db_data)) + return ECORE_INVAL; + + /* obtain hwfn from doorbell address */ + p_hwfn = ecore_db_rec_find_hwfn(p_dev, db_addr); + + /* protect the list */ + OSAL_SPIN_LOCK(&p_hwfn->db_recovery_info.lock); + OSAL_LIST_FOR_EACH_ENTRY(db_entry, + &p_hwfn->db_recovery_info.list, + list_entry, + struct ecore_db_recovery_entry) { + /* search according to db_data addr since db_addr is not unique + * (roce) + */ + if (db_entry->db_data == db_data) { + ecore_db_recovery_dp_entry(p_hwfn, db_entry, + "Deleting"); + OSAL_LIST_REMOVE_ENTRY(&db_entry->list_entry, + &p_hwfn->db_recovery_info.list); + rc = ECORE_SUCCESS; + break; + } + } + + OSAL_SPIN_UNLOCK(&p_hwfn->db_recovery_info.lock); + + if (rc == ECORE_INVAL) + /*OSAL_WARN(true,*/ + DP_NOTICE(p_hwfn, false, + "Failed to find element in list. Key (db_data addr) was %p. db_addr was %p\n", + db_data, db_addr); + else + OSAL_FREE(p_dev, db_entry); + + return rc; +} + +/* initialize the doorbell recovery mechanism */ +enum _ecore_status_t ecore_db_recovery_setup(struct ecore_hwfn *p_hwfn) +{ + DP_VERBOSE(p_hwfn, ECORE_MSG_SPQ, "Setting up db recovery\n"); + + /* make sure db_size was set in p_dev */ + if (!p_hwfn->p_dev->db_size) { + DP_ERR(p_hwfn->p_dev, "db_size not set\n"); + return ECORE_INVAL; + } + + OSAL_LIST_INIT(&p_hwfn->db_recovery_info.list); +#ifdef CONFIG_ECORE_LOCK_ALLOC + OSAL_SPIN_LOCK_ALLOC(p_hwfn, &p_hwfn->db_recovery_info.lock); +#endif + OSAL_SPIN_LOCK_INIT(&p_hwfn->db_recovery_info.lock); + p_hwfn->db_recovery_info.db_recovery_counter = 0; + + return ECORE_SUCCESS; +} + +/* destroy the doorbell recovery mechanism */ +void ecore_db_recovery_teardown(struct ecore_hwfn *p_hwfn) +{ + struct ecore_db_recovery_entry *db_entry = OSAL_NULL; + + DP_VERBOSE(p_hwfn, ECORE_MSG_SPQ, "Tearing down db recovery\n"); + if (!OSAL_LIST_IS_EMPTY(&p_hwfn->db_recovery_info.list)) { + DP_VERBOSE(p_hwfn, false, "Doorbell Recovery teardown found the doorbell recovery list was not empty (Expected in disorderly driver unload (e.g. recovery) otherwise this probably means some flow forgot to db_recovery_del). Prepare to purge doorbell recovery list...\n"); + while (!OSAL_LIST_IS_EMPTY(&p_hwfn->db_recovery_info.list)) { + db_entry = OSAL_LIST_FIRST_ENTRY( + &p_hwfn->db_recovery_info.list, + struct ecore_db_recovery_entry, + list_entry); + ecore_db_recovery_dp_entry(p_hwfn, db_entry, "Purging"); + OSAL_LIST_REMOVE_ENTRY(&db_entry->list_entry, + &p_hwfn->db_recovery_info.list); + OSAL_FREE(p_hwfn->p_dev, db_entry); + } + } +#ifdef CONFIG_ECORE_LOCK_ALLOC + OSAL_SPIN_LOCK_DEALLOC(&p_hwfn->db_recovery_info.lock); +#endif + p_hwfn->db_recovery_info.db_recovery_counter = 0; +} + +/* print the content of the doorbell recovery mechanism */ +void ecore_db_recovery_dp(struct ecore_hwfn *p_hwfn) +{ + struct ecore_db_recovery_entry *db_entry = OSAL_NULL; + + DP_NOTICE(p_hwfn, false, + "Dispalying doorbell recovery database. Counter was %d\n", + p_hwfn->db_recovery_info.db_recovery_counter); + + /* protect the list */ + OSAL_SPIN_LOCK(&p_hwfn->db_recovery_info.lock); + OSAL_LIST_FOR_EACH_ENTRY(db_entry, + &p_hwfn->db_recovery_info.list, + list_entry, + struct ecore_db_recovery_entry) { + ecore_db_recovery_dp_entry(p_hwfn, db_entry, "Printing"); + } + + OSAL_SPIN_UNLOCK(&p_hwfn->db_recovery_info.lock); +} + +/* ring the doorbell of a single doorbell recovery entry */ +void ecore_db_recovery_ring(struct ecore_hwfn *p_hwfn, + struct ecore_db_recovery_entry *db_entry, + enum ecore_db_rec_exec db_exec) +{ + /* Print according to width */ + if (db_entry->db_width == DB_REC_WIDTH_32B) + DP_VERBOSE(p_hwfn, ECORE_MSG_SPQ, "%s doorbell address %p data %x\n", + db_exec == DB_REC_DRY_RUN ? "would have rung" : "ringing", + db_entry->db_addr, *(u32 *)db_entry->db_data); + else + DP_VERBOSE(p_hwfn, ECORE_MSG_SPQ, "%s doorbell address %p data %lx\n", + db_exec == DB_REC_DRY_RUN ? "would have rung" : "ringing", + db_entry->db_addr, + *(unsigned long *)(db_entry->db_data)); + + /* Sanity */ + if (!ecore_db_rec_sanity(p_hwfn->p_dev, db_entry->db_addr, + db_entry->db_data)) + return; + + /* Flush the write combined buffer. Since there are multiple doorbelling + * entities using the same address, if we don't flush, a transaction + * could be lost. + */ + OSAL_WMB(p_hwfn->p_dev); + + /* Ring the doorbell */ + if (db_exec == DB_REC_REAL_DEAL || db_exec == DB_REC_ONCE) { + if (db_entry->db_width == DB_REC_WIDTH_32B) + DIRECT_REG_WR(p_hwfn, db_entry->db_addr, + *(u32 *)(db_entry->db_data)); + else + DIRECT_REG_WR64(p_hwfn, db_entry->db_addr, + *(u64 *)(db_entry->db_data)); + } + + /* Flush the write combined buffer. Next doorbell may come from a + * different entity to the same address... + */ + OSAL_WMB(p_hwfn->p_dev); +} + +/* traverse the doorbell recovery entry list and ring all the doorbells */ +void ecore_db_recovery_execute(struct ecore_hwfn *p_hwfn, + enum ecore_db_rec_exec db_exec) +{ + struct ecore_db_recovery_entry *db_entry = OSAL_NULL; + + if (db_exec != DB_REC_ONCE) { + DP_NOTICE(p_hwfn, false, "Executing doorbell recovery. Counter was %d\n", + p_hwfn->db_recovery_info.db_recovery_counter); + + /* track amount of times recovery was executed */ + p_hwfn->db_recovery_info.db_recovery_counter++; + } + + /* protect the list */ + OSAL_SPIN_LOCK(&p_hwfn->db_recovery_info.lock); + OSAL_LIST_FOR_EACH_ENTRY(db_entry, + &p_hwfn->db_recovery_info.list, + list_entry, + struct ecore_db_recovery_entry) { + ecore_db_recovery_ring(p_hwfn, db_entry, db_exec); + if (db_exec == DB_REC_ONCE) + break; + } + + OSAL_SPIN_UNLOCK(&p_hwfn->db_recovery_info.lock); +} +/******************** Doorbell Recovery end ****************/ + /* Configurable */ #define ECORE_MIN_DPIS (4) /* The minimal num of DPIs required to * load the driver. The number was @@ -172,6 +484,9 @@ void ecore_resc_free(struct ecore_dev *p_dev) ecore_dmae_info_free(p_hwfn); ecore_dcbx_info_free(p_hwfn, p_hwfn->p_dcbx_info); /* @@@TBD Flush work-queue ? */ + + /* destroy doorbell recovery mechanism */ + ecore_db_recovery_teardown(p_hwfn); } } @@ -863,12 +1178,17 @@ enum _ecore_status_t ecore_resc_alloc(struct ecore_dev *p_dev) struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i]; u32 n_eqes, num_cons; + /* initialize the doorbell recovery mechanism */ + rc = ecore_db_recovery_setup(p_hwfn); + if (rc) + goto alloc_err; + /* First allocate the context manager structure */ rc = ecore_cxt_mngr_alloc(p_hwfn); if (rc) goto alloc_err; - /* Set the HW cid/tid numbers (in the contest manager) + /* Set the HW cid/tid numbers (in the context manager) * Must be done prior to any further computations. */ rc = ecore_cxt_set_pf_params(p_hwfn); diff --git a/drivers/net/qede/base/ecore_dev_api.h b/drivers/net/qede/base/ecore_dev_api.h index b3c9f89..8b28af9 100644 --- a/drivers/net/qede/base/ecore_dev_api.h +++ b/drivers/net/qede/base/ecore_dev_api.h @@ -155,6 +155,45 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev, * */ void ecore_prepare_hibernate(struct ecore_dev *p_dev); + +enum ecore_db_rec_width { + DB_REC_WIDTH_32B, + DB_REC_WIDTH_64B, +}; + +enum ecore_db_rec_space { + DB_REC_KERNEL, + DB_REC_USER, +}; + +/** + * @brief db_recovery_add - add doorbell information to the doorbell + * recovery mechanism. + * + * @param p_dev + * @param db_addr - doorbell address + * @param db_data - address of where db_data is stored + * @param db_width - doorbell is 32b pr 64b + * @param db_space - doorbell recovery addresses are user or kernel space + */ +enum _ecore_status_t ecore_db_recovery_add(struct ecore_dev *p_dev, + void OSAL_IOMEM *db_addr, + void *db_data, + enum ecore_db_rec_width db_width, + enum ecore_db_rec_space db_space); + +/** + * @brief db_recovery_del - remove doorbell information from the doorbell + * recovery mechanism. db_data serves as key (db_addr is not unique). + * + * @param cdev + * @param db_addr - doorbell address + * @param db_data - address where db_data is stored. Serves as key for the + * entry to delete. + */ +enum _ecore_status_t ecore_db_recovery_del(struct ecore_dev *p_dev, + void OSAL_IOMEM *db_addr, + void *db_data); #endif /** diff --git a/drivers/net/qede/base/ecore_int.c b/drivers/net/qede/base/ecore_int.c index acf8759..d86f56e 100644 --- a/drivers/net/qede/base/ecore_int.c +++ b/drivers/net/qede/base/ecore_int.c @@ -414,31 +414,136 @@ static enum _ecore_status_t ecore_fw_assertion(struct ecore_hwfn *p_hwfn) return ECORE_SUCCESS; } -#define ECORE_DORQ_ATTENTION_REASON_MASK (0xfffff) -#define ECORE_DORQ_ATTENTION_OPAQUE_MASK (0xffff) -#define ECORE_DORQ_ATTENTION_SIZE_MASK (0x7f0000) -#define ECORE_DORQ_ATTENTION_SIZE_SHIFT (16) +#define ECORE_DORQ_ATTENTION_REASON_MASK (0xfffff) +#define ECORE_DORQ_ATTENTION_OPAQUE_MASK (0xffff) +#define ECORE_DORQ_ATTENTION_OPAQUE_SHIFT (0x0) +#define ECORE_DORQ_ATTENTION_SIZE_MASK (0x7f) +#define ECORE_DORQ_ATTENTION_SIZE_SHIFT (16) + +#define ECORE_DB_REC_COUNT 10 +#define ECORE_DB_REC_INTERVAL 100 + +/* assumes sticky overflow indication was set for this PF */ +static enum _ecore_status_t ecore_db_rec_attn(struct ecore_hwfn *p_hwfn, + struct ecore_ptt *p_ptt) +{ + u8 count = ECORE_DB_REC_COUNT; + u32 usage = 1; + + /* wait for usage to zero or count to run out. This is necessary since + * EDPM doorbell transactions can take multiple 64b cycles, and as such + * can "split" over the pci. Possibly, the doorbell drop can happen with + * half an EDPM in the queue and other half dropped. Another EDPM + * doorbell to the same address (from doorbell recovery mechanism or + * from the doorbelling entity) could have first half dropped and second + * half interperted as continuation of the first. To prevent such + * malformed doorbells from reaching the device, flush the queue before + * releaseing the overflow sticky indication. + */ + while (count-- && usage) { + usage = ecore_rd(p_hwfn, p_ptt, DORQ_REG_PF_USAGE_CNT); + OSAL_UDELAY(ECORE_DB_REC_INTERVAL); + } + + /* should have been depleted by now */ + if (usage) { + DP_NOTICE(p_hwfn->p_dev, false, + "DB recovery: doorbell usage failed to zero after %d usec. usage was %x\n", + ECORE_DB_REC_INTERVAL * ECORE_DB_REC_COUNT, usage); + return ECORE_TIMEOUT; + } + + /* flush any pedning (e)dpm as they may never arrive */ + ecore_wr(p_hwfn, p_ptt, DORQ_REG_DPM_FORCE_ABORT, 0x1); + + /* release overflow sticky indication (stop silently dropping + * everything) + */ + ecore_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0); + + /* repeat all last doorbells (doorbell drop recovery) */ + ecore_db_recovery_execute(p_hwfn, DB_REC_REAL_DEAL); + + return ECORE_SUCCESS; +} static enum _ecore_status_t ecore_dorq_attn_cb(struct ecore_hwfn *p_hwfn) { - u32 reason; + u32 int_sts, first_drop_reason, details, address, overflow, + all_drops_reason; + struct ecore_ptt *p_ptt = p_hwfn->p_dpc_ptt; + enum _ecore_status_t rc; - reason = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt, DORQ_REG_DB_DROP_REASON) & - ECORE_DORQ_ATTENTION_REASON_MASK; - if (reason) { - u32 details = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt, - DORQ_REG_DB_DROP_DETAILS); + int_sts = ecore_rd(p_hwfn, p_ptt, DORQ_REG_INT_STS); + DP_NOTICE(p_hwfn->p_dev, false, "DORQ attention. int_sts was %x\n", + int_sts); - DP_INFO(p_hwfn->p_dev, - "DORQ db_drop: address 0x%08x Opaque FID 0x%04x" - " Size [bytes] 0x%08x Reason: 0x%08x\n", - ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt, - DORQ_REG_DB_DROP_DETAILS_ADDRESS), - (u16)(details & ECORE_DORQ_ATTENTION_OPAQUE_MASK), - ((details & ECORE_DORQ_ATTENTION_SIZE_MASK) >> - ECORE_DORQ_ATTENTION_SIZE_SHIFT) * 4, reason); + /* int_sts may be zero since all PFs were interrupted for doorbell + * overflow but another one already handled it. Can abort here. If + * This PF also requires overflow recovery we will be interrupted again + */ + if (!int_sts) + return ECORE_SUCCESS; + + /* check if db_drop or overflow happened */ + if (int_sts & (DORQ_REG_INT_STS_DB_DROP | + DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR)) { + /* obtain data about db drop/overflow */ + first_drop_reason = ecore_rd(p_hwfn, p_ptt, + DORQ_REG_DB_DROP_REASON) & + ECORE_DORQ_ATTENTION_REASON_MASK; + details = ecore_rd(p_hwfn, p_ptt, + DORQ_REG_DB_DROP_DETAILS); + address = ecore_rd(p_hwfn, p_ptt, + DORQ_REG_DB_DROP_DETAILS_ADDRESS); + overflow = ecore_rd(p_hwfn, p_ptt, + DORQ_REG_PF_OVFL_STICKY); + all_drops_reason = ecore_rd(p_hwfn, p_ptt, + DORQ_REG_DB_DROP_DETAILS_REASON); + + /* log info */ + DP_NOTICE(p_hwfn->p_dev, false, + "Doorbell drop occurred\n" + "Address\t\t0x%08x\t(second BAR address)\n" + "FID\t\t0x%04x\t\t(Opaque FID)\n" + "Size\t\t0x%04x\t\t(in bytes)\n" + "1st drop reason\t0x%08x\t(details on first drop since last handling)\n" + "Sticky reasons\t0x%08x\t(all drop reasons since last handling)\n" + "Overflow\t0x%x\t\t(a per PF indication)\n", + address, + GET_FIELD(details, ECORE_DORQ_ATTENTION_OPAQUE), + GET_FIELD(details, ECORE_DORQ_ATTENTION_SIZE) * 4, + first_drop_reason, all_drops_reason, overflow); + + /* if this PF caused overflow, initiate recovery */ + if (overflow) { + rc = ecore_db_rec_attn(p_hwfn, p_ptt); + if (rc != ECORE_SUCCESS) + return rc; + } + + /* clear the doorbell drop details and prepare for next drop */ + ecore_wr(p_hwfn, p_ptt, DORQ_REG_DB_DROP_DETAILS_REL, 0); + + /* mark interrupt as handeld (note: even if drop was due to a + * different reason than overflow we mark as handled) + */ + ecore_wr(p_hwfn, p_ptt, DORQ_REG_INT_STS_WR, + DORQ_REG_INT_STS_DB_DROP | + DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR); + + /* if there are no indications otherthan drop indications, + * success + */ + if ((int_sts & ~(DORQ_REG_INT_STS_DB_DROP | + DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR | + DORQ_REG_INT_STS_DORQ_FIFO_AFULL)) == 0) + return ECORE_SUCCESS; } + /* some other indication was present - non recoverable */ + DP_INFO(p_hwfn, "DORQ fatal attention\n"); + return ECORE_INVAL; } diff --git a/drivers/net/qede/base/ecore_spq.c b/drivers/net/qede/base/ecore_spq.c index 29ba660..716799a 100644 --- a/drivers/net/qede/base/ecore_spq.c +++ b/drivers/net/qede/base/ecore_spq.c @@ -231,9 +231,9 @@ static enum _ecore_status_t ecore_spq_hw_post(struct ecore_hwfn *p_hwfn, struct ecore_spq_entry *p_ent) { struct ecore_chain *p_chain = &p_hwfn->p_spq->chain; + struct core_db_data *p_db_data = &p_spq->db_data; u16 echo = ecore_chain_get_prod_idx(p_chain); struct slow_path_element *elem; - struct core_db_data db; p_ent->elem.hdr.echo = OSAL_CPU_TO_LE16(echo); elem = ecore_chain_produce(p_chain); @@ -242,31 +242,24 @@ static enum _ecore_status_t ecore_spq_hw_post(struct ecore_hwfn *p_hwfn, return ECORE_INVAL; } - *elem = p_ent->elem; /* struct assignment */ + *elem = p_ent->elem; /* Struct assignment */ - /* send a doorbell on the slow hwfn session */ - OSAL_MEMSET(&db, 0, sizeof(db)); - SET_FIELD(db.params, CORE_DB_DATA_DEST, DB_DEST_XCM); - SET_FIELD(db.params, CORE_DB_DATA_AGG_CMD, DB_AGG_CMD_SET); - SET_FIELD(db.params, CORE_DB_DATA_AGG_VAL_SEL, - DQ_XCM_CORE_SPQ_PROD_CMD); - db.agg_flags = DQ_XCM_CORE_DQ_CF_CMD; - db.spq_prod = OSAL_CPU_TO_LE16(ecore_chain_get_prod_idx(p_chain)); + p_db_data->spq_prod = + OSAL_CPU_TO_LE16(ecore_chain_get_prod_idx(p_chain)); - /* make sure the SPQE is updated before the doorbell */ + /* Make sure the SPQE is updated before the doorbell */ OSAL_WMB(p_hwfn->p_dev); - DOORBELL(p_hwfn, DB_ADDR(p_spq->cid, DQ_DEMS_LEGACY), - *(u32 *)&db); + DOORBELL(p_hwfn, p_spq->db_addr_offset, *(u32 *)p_db_data); - /* make sure doorbell is rang */ + /* Make sure doorbell is rang */ OSAL_WMB(p_hwfn->p_dev); DP_VERBOSE(p_hwfn, ECORE_MSG_SPQ, "Doorbelled [0x%08x, CID 0x%08x] with Flags: %02x" " agg_params: %02x, prod: %04x\n", - DB_ADDR(p_spq->cid, DQ_DEMS_LEGACY), p_spq->cid, db.params, - db.agg_flags, ecore_chain_get_prod_idx(p_chain)); + p_spq->db_addr_offset, p_spq->cid, p_db_data->params, + p_db_data->agg_flags, ecore_chain_get_prod_idx(p_chain)); return ECORE_SUCCESS; } @@ -456,8 +449,11 @@ void ecore_spq_setup(struct ecore_hwfn *p_hwfn) { struct ecore_spq *p_spq = p_hwfn->p_spq; struct ecore_spq_entry *p_virt = OSAL_NULL; + struct core_db_data *p_db_data; + void OSAL_IOMEM *db_addr; dma_addr_t p_phys = 0; u32 i, capacity; + enum _ecore_status_t rc; OSAL_LIST_INIT(&p_spq->pending); OSAL_LIST_INIT(&p_spq->completion_pending); @@ -495,6 +491,24 @@ void ecore_spq_setup(struct ecore_hwfn *p_hwfn) /* reset the chain itself */ ecore_chain_reset(&p_spq->chain); + + /* Initialize the address/data of the SPQ doorbell */ + p_spq->db_addr_offset = DB_ADDR(p_spq->cid, DQ_DEMS_LEGACY); + p_db_data = &p_spq->db_data; + OSAL_MEM_ZERO(p_db_data, sizeof(*p_db_data)); + SET_FIELD(p_db_data->params, CORE_DB_DATA_DEST, DB_DEST_XCM); + SET_FIELD(p_db_data->params, CORE_DB_DATA_AGG_CMD, DB_AGG_CMD_MAX); + SET_FIELD(p_db_data->params, CORE_DB_DATA_AGG_VAL_SEL, + DQ_XCM_CORE_SPQ_PROD_CMD); + p_db_data->agg_flags = DQ_XCM_CORE_DQ_CF_CMD; + + /* Register the SPQ doorbell with the doorbell recovery mechanism */ + db_addr = (void *)((u8 *)p_hwfn->doorbells + p_spq->db_addr_offset); + rc = ecore_db_recovery_add(p_hwfn->p_dev, db_addr, &p_spq->db_data, + DB_REC_WIDTH_32B, DB_REC_KERNEL); + if (rc != ECORE_SUCCESS) + DP_INFO(p_hwfn, + "Failed to register the SPQ doorbell with the doorbell recovery mechanism\n"); } enum _ecore_status_t ecore_spq_alloc(struct ecore_hwfn *p_hwfn) @@ -552,11 +566,16 @@ enum _ecore_status_t ecore_spq_alloc(struct ecore_hwfn *p_hwfn) void ecore_spq_free(struct ecore_hwfn *p_hwfn) { struct ecore_spq *p_spq = p_hwfn->p_spq; + void OSAL_IOMEM *db_addr; u32 capacity; if (!p_spq) return; + /* Delete the SPQ doorbell from the doorbell recovery mechanism */ + db_addr = (void *)((u8 *)p_hwfn->doorbells + p_spq->db_addr_offset); + ecore_db_recovery_del(p_hwfn->p_dev, db_addr, &p_spq->db_data); + if (p_spq->p_virt) { capacity = ecore_chain_get_capacity(&p_spq->chain); OSAL_DMA_FREE_COHERENT(p_hwfn->p_dev, diff --git a/drivers/net/qede/base/ecore_spq.h b/drivers/net/qede/base/ecore_spq.h index e530f83..31d8a3e 100644 --- a/drivers/net/qede/base/ecore_spq.h +++ b/drivers/net/qede/base/ecore_spq.h @@ -124,6 +124,9 @@ struct ecore_spq { u32 comp_count; u32 cid; + + u32 db_addr_offset; + struct core_db_data db_data; }; struct ecore_port; diff --git a/drivers/net/qede/base/reg_addr.h b/drivers/net/qede/base/reg_addr.h index 116fe78..9048581 100644 --- a/drivers/net/qede/base/reg_addr.h +++ b/drivers/net/qede/base/reg_addr.h @@ -1208,3 +1208,13 @@ #define PSWRQ2_REG_WR_MBS0 0x240400UL #define PGLUE_B_REG_MASTER_WRITE_PAD_ENABLE 0x2aae30UL +#define DORQ_REG_PF_USAGE_CNT 0x1009c0UL +#define DORQ_REG_DPM_FORCE_ABORT 0x1009d8UL +#define DORQ_REG_PF_OVFL_STICKY 0x1009d0UL +#define DORQ_REG_INT_STS 0x100180UL + #define DORQ_REG_INT_STS_DB_DROP (0x1 << 1) + #define DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR (0x1 << 2) + #define DORQ_REG_INT_STS_DORQ_FIFO_AFULL (0x1 << 3) +#define DORQ_REG_DB_DROP_DETAILS_REL 0x100a28UL +#define DORQ_REG_INT_STS_WR 0x100188UL +#define DORQ_REG_DB_DROP_DETAILS_REASON 0x100a20UL diff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c index 71b3a39..e6d2351 100644 --- a/drivers/net/qede/qede_main.c +++ b/drivers/net/qede/qede_main.c @@ -36,6 +36,7 @@ static void qed_init_pci(struct ecore_dev *edev, struct rte_pci_device *pci_dev) { edev->regview = pci_dev->mem_resource[0].addr; edev->doorbells = pci_dev->mem_resource[2].addr; + edev->db_size = pci_dev->mem_resource[2].len; } static int