netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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

  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).