From: Franco Fichtner <franco@marian.de>
To: Ron Mercer <ron.mercer@qlogic.com>
Cc: jeff@garzik.org, netdev@vger.kernel.org, linux-driver@qlogic.com
Subject: Re: [PATCH 5/8] [RFC] qlge: Add main source module qlge_main.c
Date: Thu, 11 Sep 2008 10:39:19 +0200 [thread overview]
Message-ID: <48C8D937.5020708@marian.de> (raw)
In-Reply-To: <12210803433594-git-send-email-ron.mercer@qlogic.com>
Ron Mercer wrote:
[snipped some code]
> +static int ql_wait_port_init_cmplt(struct ql_adapter *qdev)
> +{
> + int count = 100;
> + u32 temp;
> +
> + while (count) {
> + temp = ql_read32(qdev, STS);
> + if (temp & qdev->port_init)
> + return 0;
> + mdelay(5);
Wrost case: delaying for 500ms... msleep() here please.
> + QPRINTK(qdev, LINK, INFO, "Wait for MAC Port to Initialize.\n");
I don't know what QPRINTK does, but it gets executed 100 times. That
can't possibly be intended?
> + count--;
> + }
> + return -ETIMEDOUT;
> +}
> +
> +/* The CFG register is used to download TX and RX control blocks
> + * to the chip. This function waits for an operation to complete.
> + */
> +static int ql_wait_cfg(struct ql_adapter *qdev, u32 bit)
> +{
> + int count = MSLEEP_COUNT;
> + u32 temp;
> +
> + while (count) {
> + temp = ql_read32(qdev, CFG);
> + if (!(temp & bit))
> + return 0;
> + if (temp & CFG_LE)
> + return -EIO;
> + spin_unlock(&qdev->hw_lock);
> + msleep(MSLEEP_DELAY);
> + spin_lock(&qdev->hw_lock);
If this is why mdelay() is used in the other places... keeping the locks
shouldn't hurt when changing them to msleep()? I don't see how a
possible deadlock could occur in the mdelay() scenarios. And besides,
you seem to operate your spinlocks on a higher level than e.g. this
function? Wouldn't that render multi-cpu usage pratically useless?
> + count--;
> + }
> + return -ETIMEDOUT;
> +}
> +
> +/* Used to issue init control blocks to hw. Maps control block,
> + * sets address, triggers download, waits for completion.
> + */
> +int ql_write_cfg(struct ql_adapter *qdev, void *ptr, int size, u32 bit,
> + u16 q_id)
> +{
> + u64 map;
> + int status = 0;
> + int direction;
> + u32 mask;
> + u32 value;
> +
> + direction =
> + (bit & (CFG_LRQ | CFG_LR | CFG_LCQ)) ? PCI_DMA_TODEVICE :
> + PCI_DMA_FROMDEVICE;
> +
> + map = pci_map_single(qdev->pdev, ptr, size, direction);
> + if (pci_dma_mapping_error(map)) {
> + QPRINTK(qdev, IFUP, ERR, "Couldn't map DMA area.\n");
> + return -ENOMEM;
> + }
> +
> + status = ql_wait_cfg(qdev, bit);
> + if (status) {
> + QPRINTK(qdev, IFUP, ERR,
> + "Timed out waiting for CFG to come ready.\n");
> + goto exit;
> + }
> +
> + status = ql_sem_spinlock(qdev, SEM_ICB_MASK);
> + if (status)
> + goto exit;
> + ql_write32(qdev, ICB_L, (u32) map);
> + ql_write32(qdev, ICB_H, (u32) (map >> 32));
> + ql_sem_unlock(qdev, SEM_ICB_MASK); /* does flush too */
> +
> + mask = CFG_Q_MASK | (bit << 16);
> + value = bit | (q_id << CFG_Q_SHIFT);
> + ql_write32(qdev, CFG, (mask | value));
> +
> + /*
> + * Wait for the bit to clear after signaling hw.
> + */
> + status = ql_wait_cfg(qdev, bit);
> +exit:
> + pci_unmap_single(qdev->pdev, map, size, direction);
> + return status;
> +}
> +
> +/* This chip has several addr/data register pairs that are used
> + * to index into another set of registers. This function waits
> + * for a specified register set to be ready for access.
> + * Examples would be setting up the CAM with MAC addresses, setting
> + * up the frame routing table.
> + */
> +static int ql_wait_idx_reg(struct ql_adapter *qdev, u32 reg, u32 flag)
> +{
> + int count = 200;
> + u32 temp;
> +
> + while (count) {
> + temp = ql_read32(qdev, reg);
> + if (temp & flag)
> + return 0;
> + mdelay(5);
Delaying for a 1000ms worst case.
> + count--;
> + }
> + return -ETIMEDOUT;
> +}
[snipped more code]
> +static int ql_port_initialize(struct ql_adapter *qdev)
> +{
> + int status = 0;
> + u32 data;
> +
> + if (ql_sem_trylock(qdev, qdev->xg_sem_mask)) {
> + /* Another function has the semaphore, so
> + * wait for the port init bit to come ready.
> + */
> + QPRINTK(qdev, LINK, INFO,
> + "Another function has the semaphore, so wait for the port init bit to come ready.\n");
> + status = ql_wait_port_init_cmplt(qdev);
> + if (status) {
> + QPRINTK(qdev, LINK, CRIT,
> + "Port initialize timed out.\n");
> + }
> + return status;
> + }
> +
> + QPRINTK(qdev, LINK, INFO, "Got xgmac semaphore!.\n");
> + /* Set the core reset. */
> + status = ql_read_xgmac_reg(qdev, GLOBAL_CFG, &data);
> + if (status)
> + goto end;
> + data |= GLOBAL_CFG_RESET;
> + status = ql_write_xgmac_reg(qdev, GLOBAL_CFG, data);
> + if (status)
> + goto end;
> +
> + mdelay(100);
Again.
> +
> + /* Clear the core reset and turn on jumbo for receiver. */
> + data &= ~GLOBAL_CFG_RESET; /* Clear core reset. */
> + data |= GLOBAL_CFG_JUMBO; /* Turn on jumbo. */
> + data |= GLOBAL_CFG_TX_STAT_EN;
> + data |= GLOBAL_CFG_RX_STAT_EN;
> + status = ql_write_xgmac_reg(qdev, GLOBAL_CFG, data);
> + if (status)
> + goto end;
> +
> + /* Enable transmitter, and clear it's reset. */
> + status = ql_read_xgmac_reg(qdev, TX_CFG, &data);
> + if (status)
> + goto end;
> + data &= ~TX_CFG_RESET; /* Clear the TX MAC reset. */
> + data |= TX_CFG_EN; /* Enable the transmitter. */
> + status = ql_write_xgmac_reg(qdev, TX_CFG, data);
> + if (status)
> + goto end;
> +
> + /* Enable receiver and clear it's reset. */
> + status = ql_read_xgmac_reg(qdev, RX_CFG, &data);
> + if (status)
> + goto end;
> + data &= ~RX_CFG_RESET; /* Clear the RX MAC reset. */
> + data |= RX_CFG_EN; /* Enable the receiver. */
> + status = ql_write_xgmac_reg(qdev, RX_CFG, data);
> + if (status)
> + goto end;
> +
> + /* Turn on jumbo. */
> + status =
> + ql_write_xgmac_reg(qdev, MAC_TX_PARAMS, MAC_TX_PARAMS_JUMBO | (0x2580 << 16));
> + if (status)
> + goto end;
> + status =
> + ql_write_xgmac_reg(qdev, MAC_RX_PARAMS, 0x2580);
> + if (status)
> + goto end;
> +
> + /* Signal to the world that the port is enabled. */
> + ql_write32(qdev, STS, ((qdev->port_init << 16) | qdev->port_init));
> +end:
> + ql_sem_unlock(qdev, qdev->xg_sem_mask);
> + return status;
> +}
> +
> +/* Get the next large buffer. */
> +struct bq_desc *ql_get_curr_lbuf(struct rx_ring *rx_ring)
> +{
> + struct bq_desc *lbq_desc = &rx_ring->lbq[rx_ring->lbq_curr_idx];
> + rx_ring->lbq_curr_idx++;
> + if (rx_ring->lbq_curr_idx == rx_ring->lbq_len)
> + rx_ring->lbq_curr_idx = 0;
> + rx_ring->lbq_free_cnt++;
> + return lbq_desc;
> +}
[ remaining code snipped, a bit too much for today ]
Franco
next prev parent reply other threads:[~2008-09-11 8:39 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 [this message]
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
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=48C8D937.5020708@marian.de \
--to=franco@marian.de \
--cc=jeff@garzik.org \
--cc=linux-driver@qlogic.com \
--cc=netdev@vger.kernel.org \
--cc=ron.mercer@qlogic.com \
/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).