From patchwork Fri Jan 23 15:16:32 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ron Mercer X-Patchwork-Id: 20071 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 1E3D0DDFDD for ; Sat, 24 Jan 2009 02:18:44 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754356AbZAWPSL (ORCPT ); Fri, 23 Jan 2009 10:18:11 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754861AbZAWPSI (ORCPT ); Fri, 23 Jan 2009 10:18:08 -0500 Received: from avexch1.qlogic.com ([198.70.193.115]:48587 "EHLO avexch1.qlogic.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754401AbZAWPR7 (ORCPT ); Fri, 23 Jan 2009 10:17:59 -0500 Received: from linux-ox1b.qlogic.com ([172.17.161.157]) by avexch1.qlogic.com with Microsoft SMTPSVC(6.0.3790.1830); Fri, 23 Jan 2009 07:16:49 -0800 Received: by linux-ox1b.qlogic.com (Postfix, from userid 1000) id 154262C6C8; Fri, 23 Jan 2009 07:16:40 -0800 (PST) From: Ron Mercer To: davem@davemloft.net Cc: netdev@vger.kernel.org, linux-driver@qlogic.com, ron.mercer@qlogic.com Subject: [PATCH 14/21] [next] qlge: Clean up MPI firware event handler. Date: Fri, 23 Jan 2009 07:16:32 -0800 Message-Id: <1232723799-8620-14-git-send-email-ron.mercer@qlogic.com> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <20090123151513.GA8526@linux-ox1b.qlogic.org> References: <20090123151513.GA8526@linux-ox1b.qlogic.org> X-OriginalArrivalTime: 23 Jan 2009 15:16:49.0079 (UTC) FILETIME=[9CB51470:01C97D6D] Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Signed-off-by: Ron Mercer --- drivers/net/qlge/qlge.h | 1 + drivers/net/qlge/qlge_main.c | 2 +- drivers/net/qlge/qlge_mpi.c | 101 ++++++++++++++++++++++++++---------------- 3 files changed, 64 insertions(+), 40 deletions(-) diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 02c7812..0779f07 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -1512,6 +1512,7 @@ void ql_queue_asic_error(struct ql_adapter *qdev); u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr); void ql_set_ethtool_ops(struct net_device *ndev); int ql_read_xgmac_reg64(struct ql_adapter *qdev, u32 reg, u64 *data); +int ql_cam_route_initialize(struct ql_adapter *qdev); #if 1 #define QL_ALL_DUMP diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 023dfe9..ec01dbf 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -2937,7 +2937,7 @@ exit: return status; } -static int ql_cam_route_initialize(struct ql_adapter *qdev) +int ql_cam_route_initialize(struct ql_adapter *qdev) { int status; diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c index eda17b0..867baca 100644 --- a/drivers/net/qlge/qlge_mpi.c +++ b/drivers/net/qlge/qlge_mpi.c @@ -75,7 +75,7 @@ static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp) mbcp->out_count = 2; if (ql_get_mb_sts(qdev, mbcp)) - goto exit; + return; qdev->link_status = mbcp->mbox_out[1]; QPRINTK(qdev, DRV, ERR, "Link Up.\n"); @@ -85,9 +85,6 @@ static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp) netif_carrier_on(qdev->ndev); netif_wake_queue(qdev->ndev); } -exit: - /* Clear the MPI firmware status. */ - ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT); } static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp) @@ -96,7 +93,7 @@ static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp) if (ql_get_mb_sts(qdev, mbcp)) { QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n"); - goto exit; + return; } if (netif_carrier_ok(qdev->ndev)) { @@ -106,27 +103,77 @@ static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp) } QPRINTK(qdev, DRV, ERR, "Link Down.\n"); QPRINTK(qdev, DRV, ERR, "Link Status = 0x%.08x.\n", mbcp->mbox_out[1]); -exit: - /* Clear the MPI firmware status. */ - ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT); } static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp) { + int status; + mbcp->out_count = 2; if (ql_get_mb_sts(qdev, mbcp)) { QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n"); - goto exit; + return; + } + status = ql_cam_route_initialize(qdev); + if (status) { + QPRINTK(qdev, IFUP, ERR, + "Failed to init CAM/Routing tables.\n"); + return; } QPRINTK(qdev, DRV, ERR, "Firmware initialized!\n"); QPRINTK(qdev, DRV, ERR, "Firmware status = 0x%.08x.\n", mbcp->mbox_out[0]); QPRINTK(qdev, DRV, ERR, "Firmware Revision = 0x%.08x.\n", mbcp->mbox_out[1]); -exit: - /* Clear the MPI firmware status. */ +} + +/* Process an async event and clear it unless it's an + * error condition. + * This can get called iteratively from the mpi_work thread + * when events arrive via an interrupt. + * It also gets called when a mailbox command is polling for + * it's completion. */ +static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp) +{ + int status; + + /* Just get mailbox zero for now. */ + mbcp->out_count = 1; + status = ql_get_mb_sts(qdev, mbcp); + if (status) { + QPRINTK(qdev, DRV, ERR, + "Could not read MPI, resetting ASIC!\n"); + ql_queue_asic_error(qdev); + goto end; + } + + switch (mbcp->mbox_out[0]) { + + case AEN_LINK_UP: + ql_link_up(qdev, mbcp); + break; + + case AEN_LINK_DOWN: + ql_link_down(qdev, mbcp); + break; + + case AEN_FW_INIT_DONE: + ql_init_fw_done(qdev, mbcp); + break; + + case AEN_FW_INIT_FAIL: + case AEN_SYS_ERR: + case MB_CMD_STS_ERR: + default: + ql_queue_fw_error(qdev); + QPRINTK(qdev, DRV, ERR, + "Unsupported AE %.08x.\n", mbcp->mbox_out[0]); + /* Clear the MPI firmware status. */ + } +end: ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT); + return status; } void ql_mpi_work(struct work_struct *work) @@ -135,37 +182,13 @@ void ql_mpi_work(struct work_struct *work) container_of(work, struct ql_adapter, mpi_work.work); struct mbox_params mbc; struct mbox_params *mbcp = &mbc; - mbcp->out_count = 1; while (ql_read32(qdev, STS) & STS_PI) { - if (ql_get_mb_sts(qdev, mbcp)) { - QPRINTK(qdev, DRV, ERR, - "Could not read MPI, resetting ASIC!\n"); - ql_queue_asic_error(qdev); - } - - switch (mbcp->mbox_out[0]) { - case AEN_LINK_UP: - ql_link_up(qdev, mbcp); - break; - case AEN_LINK_DOWN: - ql_link_down(qdev, mbcp); - break; - case AEN_FW_INIT_DONE: - ql_init_fw_done(qdev, mbcp); - break; - case MB_CMD_STS_GOOD: - break; - case AEN_FW_INIT_FAIL: - case AEN_SYS_ERR: - case MB_CMD_STS_ERR: - ql_queue_fw_error(qdev); - default: - /* Clear the MPI firmware status. */ - ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT); - break; - } + memset(mbcp, 0, sizeof(struct mbox_params)); + mbcp->out_count = 1; + ql_mpi_handler(qdev, mbcp); } + ql_enable_completion_interrupt(qdev, 0); }