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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.