From: Ron Mercer <ron.mercer@qlogic.com>
To: Franco Fichtner <franco@marian.de>
Cc: jeff@garzik.org, netdev@vger.kernel.org, linux-driver@qlogic.com
Subject: Re: [PATCH 6/8] [RFC] qlge: Add mgmt port xface file qlge_mpi.c
Date: Thu, 11 Sep 2008 12:06:18 -0700 [thread overview]
Message-ID: <20080911190618.GA23939@susedev.qlogic.org> (raw)
In-Reply-To: <48C8D0C7.6060706@marian.de>
On Thu, Sep 11, 2008 at 10:03:19AM +0200, Franco Fichtner wrote:
> Ron Mercer wrote:
> >Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
> >---
> > drivers/net/qlge/qlge_mpi.c | 228
> > +++++++++++++++++++++++++++++++++++++++++++
> > 1 files changed, 228 insertions(+), 0 deletions(-)
> > create mode 100644 drivers/net/qlge/qlge_mpi.c
> >
> >diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
> >new file mode 100644
> >index 0000000..f235fc5
> >--- /dev/null
> >+++ b/drivers/net/qlge/qlge_mpi.c
> >@@ -0,0 +1,228 @@
> >+#include "qlge.h"
> >+
> >+/*
> >+ * Returns zero on success.
> >+ */
> >+static int ql_wait_mbx_cmd_cmplt(struct ql_adapter *qdev)
> >+{
> >+ int count = 50;
> >+ u32 temp;
> >+
> >+ while (count) {
> >+ temp = ql_read32(qdev, STS);
> >+ if (temp & STS_PI)
> >+ return 0;
> >+ mdelay(5);
>
> Do you really want to delay execution for 250ms in worst case (timeout)
> scenarios? A msleep() would be more graceful.
>
We do need to wait this long as the MPI firmware will be handling
mailbox commands for an FCOE function as well as this NIC function.
You're right about msleep() being a better choice and I will change it
for the next submission.
> >+ count--;
> >+ }
> >+ return -ETIMEDOUT;
> >+}
> >+
> >+static int ql_write_mbox_reg(struct ql_adapter *qdev, u32 reg, u32 data)
> >+{
> >+ int status = 0;
> >+ /* wait for reg to come ready */
> >+ status = ql_wait_addr_reg(qdev, PROC_ADDR, PROC_ADDR_RDY);
> >+ if (status)
> >+ goto exit;
> >+ /* write the data to the data reg */
> >+ ql_write32(qdev, PROC_DATA, data);
> >+ /* trigger the write */
> >+ ql_write32(qdev, PROC_ADDR, reg);
> >+ /* wait for reg to come ready */
> >+ status = ql_wait_addr_reg(qdev, PROC_ADDR, PROC_ADDR_RDY);
> >+ if (status)
> >+ goto exit;
>
> These two lines above are redundant. You cold also avoid the goto with
> opening a new block after the first if. Or how about just...
>
Right again. I was waiting before and after the function. You only
need to wait at one of them. I will remove the trailing wait.
> static int ql_write_mbox_reg(struct ql_adapter *qdev, u32 reg, u32 data)
> {
> /* wait for reg to come ready */
> if (ql_wait_addr_reg(qdev_ PROC_ADDR, PROC_ADDR_RDY)) {
> /* write the data to the data reg */
> ql_write32(qdev, PROC_DATA, data);
> /* trigger the write */
> ql_write32(qdev, PROC_ADDR, reg);
> }
>
> /* wait for reg to come ready */
> return ql_wait_addr_reg(qdev, PROC_ADDR, PROC_ADDR_RDY);
> }
>
> ... omitting the need for the status variable altogether.
I'll still need status, but won't initialize it and will drop the
trailing wait.
>
> >+exit:
> >+ return status;
> >+}
> >+
> >+static int ql_read_mbox_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
> >+{
> >+ int status = 0;
>
> Same here for the goto. And no need to initialize status with a constant
> which must be pulled from memory when there is no path using this
> default value anyway.
done...
>
> >+ /* wait for reg to come ready */
> >+ status = ql_wait_addr_reg(qdev, PROC_ADDR, PROC_ADDR_RDY);
> >+ if (status)
> >+ goto exit;
> >+ /* set up for reg read */
> >+ ql_write32(qdev, PROC_ADDR, reg | PROC_ADDR_R);
> >+ /* wait for reg to come ready */
> >+ status = ql_wait_addr_reg(qdev, PROC_ADDR, PROC_ADDR_RDY);
> >+ if (status)
> >+ goto exit;
> >+ /* get the data */
> >+ *data = ql_read32(qdev, PROC_DATA);
> >+exit:
> >+ return status;
> >+}
> >+
> >+static int ql_exec_mb_cmd(struct ql_adapter *qdev, struct mbox_params
> >*mbcp)
> >+{
> >+ int i, status;
> >+
> >+ /*
> >+ * Make sure there's nothing pending.
> >+ * This shouldn't happen.
> >+ */
> >+ if (ql_read32(qdev, CSR) & CSR_HRI)
> >+ return -EBUSY;
> >+
> >+ status = ql_sem_spinlock(qdev, SEM_PROC_REG_MASK);
> >+ if (status)
> >+ return -EBUSY;
> >+ /*
> >+ * Fill the outbound mailboxes.
> >+ */
> >+ for (i = 0; i < mbcp->in_count; i++) {
> >+ status =
> >+ ql_write_mbox_reg(qdev, qdev->mailbox_in + i,
> >+ mbcp->mbox_in[i]);
> >+ if (status)
> >+ goto end;
> >+ }
> >+ /*
> >+ * Wake up the MPI firmware.
> >+ */
> >+ ql_write32(qdev, CSR, CSR_CMD_SET_H2R_INT);
> >+end:
> >+ ql_sem_unlock(qdev, SEM_PROC_REG_MASK); /* does flush too */
> >+ return status;
> >+}
> >+
> >+int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
> >+{
> >+ int i, status = 0;
>
> Again, default value never used.
Done...
>
> >+
> >+ status = ql_sem_spinlock(qdev, SEM_PROC_REG_MASK);
> >+ if (status)
> >+ return -EBUSY;
> >+ for (i = 0; i < mbcp->out_count; i++) {
> >+ status =
> >+ ql_read_mbox_reg(qdev, qdev->mailbox_out + i,
> >+ &mbcp->mbox_out[i]);
> >+ if (status) {
> >+ QPRINTK(qdev, DRV, ERR, "Failed mailbox read.\n");
> >+ break;
> >+ }
> >+ }
> >+ ql_sem_unlock(qdev, SEM_PROC_REG_MASK); /* does flush too */
> >+ return status;
> >+}
> >+
> >+static void ql_link_up(struct ql_adapter *qdev)
> >+{
> >+ struct mbox_params mbc;
> >+ struct mbox_params *mbcp = &mbc;
> >+ mbcp->out_count = 2;
> >+
> >+ if (ql_get_mb_sts(qdev, mbcp))
> >+ goto exit;
> >+
> >+ qdev->link_status = mbcp->mbox_out[1];
> >+ QPRINTK(qdev, DRV, ERR, "Link Up.\n");
> >+ QPRINTK(qdev, DRV, ERR, "Link Status = 0x%.08x.\n",
> >mbcp->mbox_out[1]);
> >+ if (!netif_carrier_ok(qdev->ndev)) {
> >+ QPRINTK(qdev, LINK, INFO, "Link is Up.\n");
> >+ 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 mbc;
> >+ struct mbox_params *mbcp = &mbc;
> >+ mbcp->out_count = 3;
> >+
> >+ if (ql_get_mb_sts(qdev, mbcp)) {
> >+ QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
> >+ goto exit;
> >+ }
> >+
> >+ if (netif_carrier_ok(qdev->ndev)) {
> >+ QPRINTK(qdev, LINK, INFO, "Link is Down.\n");
> >+ netif_carrier_off(qdev->ndev);
> >+ netif_stop_queue(qdev->ndev);
> >+ }
> >+ 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 mbc;
> >+ struct mbox_params *mbcp = &mbc;
> >+ mbcp->out_count = 2;
> >+
> >+ if (ql_get_mb_sts(qdev, mbcp)) {
> >+ QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
> >+ goto exit;
> >+ }
> >+ 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. */
> >+ ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
> >+}
> >+
> >+void ql_mpi_work(struct work_struct *work)
> >+{
> >+ struct ql_adapter *qdev =
> >+ 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);
> >+ break;
> >+ case AEN_LINK_DOWN:
> >+ ql_link_down(qdev);
> >+ break;
> >+ case AEN_FW_INIT_DONE:
> >+#ifdef PALLADIUM
> >+/* Palladium Workaround Start */
> >+ case 0:
> >+/* Palladium Workaround End */
> >+#endif
> >+ ql_init_fw_done(qdev);
> >+ break;
> >+ case AEN_FW_INIT_FAIL:
> >+ break;
>
> No breaking here...
Thanks for bringing it to my attention. I am in the process of cleaning this up.
>
> >+ case AEN_SYS_ERR:
> >+ break;
>
> ...and here necessary to make things more consistent with the lines
> below. (Having no default seems ok here.)
>
This wasn't done and kind of fell through the cracks. It will be done
in the next submittal.
> >+ case MB_CMD_STS_GOOD:
> >+ case MB_CMD_STS_INTRMDT:
> >+ case MB_CMD_STS_ERR:
> >+ case AEN_IDC_CMPLT:
> >+ case AEN_IDC_REQ:
> >+ break;
> >+
> >+ }
> >+ }
> >+ ql_enable_completion_interrupt(qdev, 0);
> >+}
> >+
> >+void ql_mpi_reset_work(struct work_struct *work)
> >+{
> >+ struct ql_adapter *qdev =
> >+ container_of(work, struct ql_adapter, mpi_reset_work.work);
> >+ printk(KERN_ERR "%s: Enter, qdev = %p..\n", __func__, qdev);
> >+}
>
> Another inconsistency: you're not using QPRINTK() like before. Is this
> intended?
Not intended. I'll fix it.
Thanks for your help.
-Ron
next prev parent reply other threads:[~2008-09-11 19:07 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-10 20:58 [PATCH 0/8][RFC] qlge: New Qlogic 10Gb Ethernet Driver for 2.6.28 Ron Mercer
2008-09-10 20:58 ` [PATCH 1/8] [RFC] qlge: Add license file LICENSE.qlge Ron Mercer
2008-09-10 20:58 ` [PATCH 2/8] [RFC] qlge: Additions to driver/net/Makefile and Kconfig Ron Mercer
2008-09-10 20:58 ` [PATCH 3/8] [RFC] qlge: Added drivers/net/qlge/Makefile Ron Mercer
2008-09-10 20:58 ` [PATCH 4/8] [RFC] qlge: Add main header file qlge.h Ron Mercer
2008-09-10 20:58 ` [PATCH 5/8] [RFC] qlge: Add main source module qlge_main.c Ron Mercer
2008-09-11 8:39 ` Franco Fichtner
2008-09-12 0:58 ` Ron Mercer
2008-09-12 8:15 ` Franco Fichtner
2008-09-15 18:28 ` Ron Mercer
2008-09-10 20:59 ` [PATCH 6/8] [RFC] qlge: Add mgmt port xface file qlge_mpi.c Ron Mercer
2008-09-11 8:03 ` Franco Fichtner
2008-09-11 19:06 ` Ron Mercer [this message]
2008-09-10 20:59 ` [PATCH 7/8] [RFC] qlge: Add ethtool module qlge_ethtool.c Ron Mercer
2008-09-10 20:59 ` [PATCH 8/8] [RFC] qlge: Add debug module qlge_dbg.c Ron Mercer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080911190618.GA23939@susedev.qlogic.org \
--to=ron.mercer@qlogic.com \
--cc=franco@marian.de \
--cc=jeff@garzik.org \
--cc=linux-driver@qlogic.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).