netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2.6.9-rc2 4/8] S2io: hardware fixes
@ 2004-10-08 23:30 Ravinandan Arakali
  2004-10-09  0:11 ` Jeff Garzik
  0 siblings, 1 reply; 7+ messages in thread
From: Ravinandan Arakali @ 2004-10-08 23:30 UTC (permalink / raw)
  To: 'Jeff Garzik', 'Francois Romieu'
  Cc: netdev, leonid.grossman, raghavendra.koushik, rapuru.sriram

[-- Attachment #1: Type: text/plain, Size: 1125 bytes --]

Hi,
Following are the code changes addressing the hardware errata in user guide.

1. Xena3's with a set of subsystem IDs had Link LED problems, fixed that
specifically for them.
2. To write into the Keyed Mac_Cfg register to enable broadcast, writing two
32 bit writes into it along with a write to the key register rather than a
single write to key and a 64 bit write to mac_cfg. This is necessary on 32
bit systems where a writeq(64 bit write) is actually two writel (32 bit
writes).
3. Writes to some special registers mentioned in UG is being done by a
special macro which defines which 32 bits of the 64 bit register is to be
written first. Again this applies only on 32 bit systems.
4. Configured pause frame related water marks and a shared_split value which
describes the Max TXDMA related split transaction that can be used without
giving room for the Rx transactions.
5. The mac_rmac_err_reg R1 register will be cleared in  the interrupt
handler itself rather than in the scheduled task as was being done
previously.
6. Even on PCC_FB_ECC error the card will be reset by disabling adapter
enable bit.

Thanks,
Ravi

[-- Attachment #2: s2io_hwfixes.patch4 --]
[-- Type: application/octet-stream, Size: 9942 bytes --]

diff -urN vanilla-linux/drivers/net/s2io.c linux-2.6.8.1/drivers/net/s2io.c
--- vanilla-linux/drivers/net/s2io.c	2004-10-07 11:44:04.000000000 -0700
+++ linux-2.6.8.1/drivers/net/s2io.c	2004-10-07 11:45:41.000000000 -0700
@@ -71,6 +71,15 @@
 static char s2io_driver_name[] = "s2io";
 static char s2io_driver_version[] = "Version 1.7.5.1";
 
+/* 
+ * Cards with following subsystem_id have a link state indication
+ * problem, 600B, 600C, 600D, 640B, 640C and 640D.
+ * macro below identifies these cards given the subsystem_id.
+ */
+#define CARDS_WITH_FAULTY_LINK_INDICATORS(subid) \
+		(((subid >= 0x600B) && (subid <= 0x600D)) || \
+		 ((subid >= 0x640B) && (subid <= 0x640D))) ? 1 : 0
+
 #define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \
 				      ADAPTER_STATUS_RMAC_LOCAL_FAULT)))
 #define TASKLET_IN_USE test_and_set_bit(0, \
@@ -563,10 +572,13 @@
 	schedule_timeout(HZ / 2);
 
 	/*  Enable Receiving broadcasts */
+	add = (void *) &bar0->mac_cfg;
 	val64 = readq(&bar0->mac_cfg);
 	val64 |= MAC_RMAC_BCAST_ENABLE;
 	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
-	writeq(val64, &bar0->mac_cfg);
+	writel((u32) val64, add);
+	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
+	writel((u32) (val64 >> 32), (add + 4));
 
 	/* Read registers in all blocks */
 	val64 = readq(&bar0->mac_int_mask);
@@ -598,8 +610,8 @@
 				dtx_cnt++;
 				goto mdio_cfg;
 			}
-			writeq(default_dtx_cfg[dtx_cnt],
-			       &bar0->dtx_control);
+			SPECIAL_REG_WRITE(default_dtx_cfg[dtx_cnt],
+					  &bar0->dtx_control, UF);
 			val64 = readq(&bar0->dtx_control);
 			dtx_cnt++;
 		}
@@ -609,8 +621,8 @@
 				mdio_cnt++;
 				goto dtx_cfg;
 			}
-			writeq(default_mdio_cfg[mdio_cnt],
-			       &bar0->mdio_control);
+			SPECIAL_REG_WRITE(default_mdio_cfg[mdio_cnt],
+					  &bar0->mdio_control, UF);
 			val64 = readq(&bar0->mdio_control);
 			mdio_cnt++;
 		}
@@ -873,6 +885,47 @@
 	writel((u32) (val64 >> 32), (add + 4));
 	val64 = readq(&bar0->mac_cfg);
 
+	/* 
+	 * Set the time value to be inserted in the pause frame 
+	 * generated by xena.
+	 */
+	val64 = readq(&bar0->rmac_pause_cfg);
+	val64 &= ~(RMAC_PAUSE_HG_PTIME(0xffff));
+	val64 |= RMAC_PAUSE_HG_PTIME(nic->mac_control.rmac_pause_time);
+	writeq(val64, &bar0->rmac_pause_cfg);
+
+	/* 
+	 * Set the Threshold Limit for Generating the pause frame
+	 * If the amount of data in any Queue exceeds ratio of
+	 * (mac_control.mc_pause_threshold_q0q3 or q4q7)/256
+	 * pause frame is generated
+	 */
+	val64 = 0;
+	for (i = 0; i < 4; i++) {
+		val64 |=
+		    (((u64) 0xFF00 | nic->mac_control.
+		      mc_pause_threshold_q0q3)
+		     << (i * 2 * 8));
+	}
+	writeq(val64, &bar0->mc_pause_thresh_q0q3);
+
+	val64 = 0;
+	for (i = 0; i < 4; i++) {
+		val64 |=
+		    (((u64) 0xFF00 | nic->mac_control.
+		      mc_pause_threshold_q4q7)
+		     << (i * 2 * 8));
+	}
+	writeq(val64, &bar0->mc_pause_thresh_q4q7);
+
+	/* 
+	 * TxDMA will stop Read request if the number of read split has 
+	 * exceeded the limit pointed by shared_splits
+	 */
+	val64 = readq(&bar0->pic_control);
+	val64 |= PIC_CNTL_SHARED_SPLITS(0);
+	writeq(val64, &bar0->pic_control);
+
 	return SUCCESS;
 }
 
@@ -1227,7 +1280,7 @@
 	 */
 	val64 = readq(&bar0->mc_rldram_mrs);
 	val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE | MC_RLDRAM_MRS_ENABLE;
-	writeq(val64, &bar0->mc_rldram_mrs);
+	SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF);
 	val64 = readq(&bar0->mc_rldram_mrs);
 
 	set_current_state(TASK_UNINTERRUPTIBLE);
@@ -1291,13 +1344,13 @@
 	 * force link down. Since link is already up, we will get
 	 * link state change interrupt after this reset
 	 */
-	writeq(0x80010515001E0000ULL, &bar0->dtx_control);
+	SPECIAL_REG_WRITE(0x80010515001E0000ULL, &bar0->dtx_control, UF);
 	val64 = readq(&bar0->dtx_control);
 	udelay(50);
-	writeq(0x80010515001E00E0ULL, &bar0->dtx_control);
+	SPECIAL_REG_WRITE(0x80010515001E00E0ULL, &bar0->dtx_control, UF);
 	val64 = readq(&bar0->dtx_control);
 	udelay(50);
-	writeq(0x80070515001F00E4ULL, &bar0->dtx_control);
+	SPECIAL_REG_WRITE(0x80070515001F00E4ULL, &bar0->dtx_control, UF);
 	val64 = readq(&bar0->dtx_control);
 	udelay(50);
 
@@ -1884,6 +1937,7 @@
 
 	/* Handling link status change error Intr */
 	err_reg = readq(&bar0->mac_rmac_err_reg);
+	writeq(err_reg, &bar0->mac_rmac_err_reg);
 	if (err_reg & RMAC_LINK_STATE_CHANGE_INT) {
 		schedule_work(&nic->set_link_task);
 	}
@@ -1896,6 +1950,22 @@
 		schedule_work(&nic->rst_timer_task);
 	}
 
+	/*
+	 * Also as mentioned in the latest Errata sheets if the PCC_FB_ECC
+	 * Error occurs, the adapter will be recycled by disabling the
+	 * adapter enable bit and enabling it again after the device 
+	 * becomes Quiescent.
+	 */
+	val64 = readq(&bar0->pcc_err_reg);
+	writeq(val64, &bar0->pcc_err_reg);
+	if (val64 & PCC_FB_ECC_DB_ERR) {
+		u64 ac = readq(&bar0->adapter_control);
+		ac &= ~(ADAPTER_CNTL_EN);
+		writeq(ac, &bar0->adapter_control);
+		ac = readq(&bar0->adapter_control);
+		schedule_work(&nic->set_link_task);
+	}
+
 	/* Other type of interrupts are not being handled now,  TODO */
 }
 
@@ -2870,12 +2940,13 @@
 
 static int s2io_ethtool_idnic(struct net_device *dev, u32 data)
 {
-	u64 val64 = 0;
+	u64 val64 = 0, last_gpio_ctrl_val;
 	nic_t *sp = dev->priv;
 	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
 	u16 subid;
 
 	subid = sp->pdev->subsystem_device;
+	last_gpio_ctrl_val = readq(&bar0->gpio_control);
 	if ((subid & 0xFF) < 0x07) {
 		val64 = readq(&bar0->adapter_control);
 		if (!(val64 & ADAPTER_CNTL_EN)) {
@@ -2897,6 +2968,11 @@
 		schedule_timeout(MAX_SCHEDULE_TIMEOUT);
 	del_timer_sync(&sp->id_timer);
 
+	if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) {
+		writeq(last_gpio_ctrl_val, &bar0->gpio_control);
+		last_gpio_ctrl_val = readq(&bar0->gpio_control);
+	}
+
 	return 0;
 }
 
@@ -2983,7 +3059,7 @@
 	val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
 	    I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ |
 	    I2C_CONTROL_CNTL_START;
-	writeq(val64, &bar0->i2c_control);
+	SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
 
 	while (exit_cnt < 5) {
 		val64 = readq(&bar0->i2c_control);
@@ -3024,7 +3100,7 @@
 	val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
 	    I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA(data) |
 	    I2C_CONTROL_CNTL_START;
-	writeq(val64, &bar0->i2c_control);
+	SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
 
 	while (exit_cnt < 5) {
 		val64 = readq(&bar0->i2c_control);
@@ -3352,10 +3428,10 @@
 
 	val64 = readq(&bar0->mc_rldram_mrs);
 	val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE;
-	writeq(val64, &bar0->mc_rldram_mrs);
+	SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF);
 
 	val64 |= MC_RLDRAM_MRS_ENABLE;
-	writeq(val64, &bar0->mc_rldram_mrs);
+	SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF);
 
 	while (iteration < 2) {
 		val64 = 0x55555555aaaa0000ULL;
@@ -3757,8 +3833,10 @@
 	nic_t *nic = (nic_t *) data;
 	struct net_device *dev = nic->dev;
 	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
-	register u64 val64, err_reg;
+	register u64 val64;
+	u16 subid;
 
+	subid = nic->pdev->subsystem_device;
 	/* 
 	 * Allow a small delay for the NICs self initiated 
 	 * cleanup to complete.
@@ -3768,16 +3846,19 @@
 
 	val64 = readq(&bar0->adapter_status);
 	if (verify_xena_quiescence(val64, nic->device_enabled_once)) {
-		/* Acknowledge Intr and clear R1 register. */
-		err_reg = readq(&bar0->mac_rmac_err_reg);
-		writeq(err_reg, &bar0->mac_rmac_err_reg);
-
 		if (LINK_IS_UP(val64)) {
 			val64 = readq(&bar0->adapter_control);
 			val64 |= ADAPTER_CNTL_EN;
 			writeq(val64, &bar0->adapter_control);
-			val64 |= ADAPTER_LED_ON;
-			writeq(val64, &bar0->adapter_control);
+			if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) {
+				val64 = readq(&bar0->gpio_control);
+				val64 |= GPIO_CTRL_GPIO_0;
+				writeq(val64, &bar0->gpio_control);
+				val64 = readq(&bar0->gpio_control);
+			} else {
+				val64 |= ADAPTER_LED_ON;
+				writeq(val64, &bar0->adapter_control);
+			}
 			val64 = readq(&bar0->adapter_status);
 			if (!LINK_IS_UP(val64)) {
 				DBG_PRINT(ERR_DBG, "%s:", dev->name);
@@ -3791,6 +3872,12 @@
 			}
 			s2io_link(nic, LINK_UP);
 		} else {
+			if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) {
+				val64 = readq(&bar0->gpio_control);
+				val64 &= ~GPIO_CTRL_GPIO_0;
+				writeq(val64, &bar0->gpio_control);
+				val64 = readq(&bar0->gpio_control);
+			}
 			s2io_link(nic, LINK_DOWN);
 		}
 	} else {		/* NIC is not Quiescent. */
@@ -3917,6 +4004,7 @@
 	return SUCCESS;
 }
 
+
 /**
  *  s2io_link - stops/starts the Tx queue.
  *  @sp : private member of the device structure, which is a pointer to the
diff -urN vanilla-linux/drivers/net/s2io.h linux-2.6.8.1/drivers/net/s2io.h
--- vanilla-linux/drivers/net/s2io.h	2004-10-07 11:44:04.000000000 -0700
+++ linux-2.6.8.1/drivers/net/s2io.h	2004-10-08 15:20:09.316690064 -0700
@@ -693,6 +693,27 @@
 	writel((u32) (val), addr);
 	writel((u32) (val >> 32), (addr + 4));
 }
+
+/* In 32 bit modes, some registers have to be written in a 
+ * particular order to expect correct hardware operation. The
+ * macro SPECIAL_REG_WRITE is used to perform such ordered 
+ * writes. Defines UF (Upper First) and LF (Lower First) will 
+ * be used to specify the required write order.
+ */
+#define UF	1
+#define LF	2
+static inline void SPECIAL_REG_WRITE(u64 val, void *addr, int order)
+{
+	if (order == LF) {
+		writel((u32) (val), addr);
+		writel((u32) (val >> 32), (addr + 4));
+	} else {
+		writel((u32) (val >> 32), (addr + 4));
+		writel((u32) (val), addr);
+	}
+}
+#else
+#define SPECIAL_REG_WRITE(val, addr, dummy) writeq(val, addr)
 #endif
 
 /*  Interrupt related values of Xena */

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2.6.9-rc2 4/8] S2io: hardware fixes
  2004-10-08 23:30 Ravinandan Arakali
@ 2004-10-09  0:11 ` Jeff Garzik
  2004-10-09  0:34   ` Ravinandan Arakali
  0 siblings, 1 reply; 7+ messages in thread
From: Jeff Garzik @ 2004-10-09  0:11 UTC (permalink / raw)
  To: ravinandan.arakali
  Cc: 'Francois Romieu', netdev, leonid.grossman,
	raghavendra.koushik, rapuru.sriram

48 hours passed between patch #3 and patch #4.  Is there a problem with 
your email system?

Also, your patches do not include the "signed-off-by" line described in 
the two documents I referenced.  The "signed-off-by" line makes the 
lawyers happy.

Since you missed that major legal item, please _read_ the following 
documents:

http://linux.yyz.us/patch-format.html (see #5, "Sign your work")
http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt

	Jeff

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2.6.9-rc2 4/8] S2io: hardware fixes
  2004-10-09  0:34   ` Ravinandan Arakali
@ 2004-10-09  0:31     ` Jeff Garzik
  2004-10-10  3:24     ` Randy.Dunlap
  1 sibling, 0 replies; 7+ messages in thread
From: Jeff Garzik @ 2004-10-09  0:31 UTC (permalink / raw)
  To: ravinandan.arakali
  Cc: 'Francois Romieu', netdev, leonid.grossman,
	raghavendra.koushik, rapuru.sriram

Ravinandan Arakali wrote:
> Jeff,
> Sorry about that. We'll add the signed-off-by line.
> We are sending the patches as and when they are completed.
> In the next couple of days, the remaining patches should
> be done. Do you want us to send them after all are complete
> or is it okay to send each patch as and when completed ?

I apply a patch series all at the same time.  So, right now I'm waiting 
for patches 5-8 before I will apply 1-8.

	Jeff

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH 2.6.9-rc2 4/8] S2io: hardware fixes
  2004-10-09  0:11 ` Jeff Garzik
@ 2004-10-09  0:34   ` Ravinandan Arakali
  2004-10-09  0:31     ` Jeff Garzik
  2004-10-10  3:24     ` Randy.Dunlap
  0 siblings, 2 replies; 7+ messages in thread
From: Ravinandan Arakali @ 2004-10-09  0:34 UTC (permalink / raw)
  To: 'Jeff Garzik'
  Cc: 'Francois Romieu', netdev, leonid.grossman,
	raghavendra.koushik, rapuru.sriram

Jeff,
Sorry about that. We'll add the signed-off-by line.
We are sending the patches as and when they are completed.
In the next couple of days, the remaining patches should
be done. Do you want us to send them after all are complete
or is it okay to send each patch as and when completed ?

Thanks,
Ravi

-----Original Message-----
From: Jeff Garzik [mailto:jgarzik@pobox.com]
Sent: Friday, October 08, 2004 5:11 PM
To: ravinandan.arakali@s2io.com
Cc: 'Francois Romieu'; netdev@oss.sgi.com; leonid.grossman@s2io.com;
raghavendra.koushik@s2io.com; rapuru.sriram@s2io.com
Subject: Re: [PATCH 2.6.9-rc2 4/8] S2io: hardware fixes


48 hours passed between patch #3 and patch #4.  Is there a problem with 
your email system?

Also, your patches do not include the "signed-off-by" line described in 
the two documents I referenced.  The "signed-off-by" line makes the 
lawyers happy.

Since you missed that major legal item, please _read_ the following 
documents:

http://linux.yyz.us/patch-format.html (see #5, "Sign your work")
http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt

	Jeff

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2.6.9-rc2 4/8] S2io: hardware fixes
  2004-10-09  0:34   ` Ravinandan Arakali
  2004-10-09  0:31     ` Jeff Garzik
@ 2004-10-10  3:24     ` Randy.Dunlap
  1 sibling, 0 replies; 7+ messages in thread
From: Randy.Dunlap @ 2004-10-10  3:24 UTC (permalink / raw)
  To: ravinandan.arakali
  Cc: 'Jeff Garzik', 'Francois Romieu', netdev,
	leonid.grossman, raghavendra.koushik, rapuru.sriram

Ravinandan Arakali wrote:
> Jeff,
> Sorry about that. We'll add the signed-off-by line.
> We are sending the patches as and when they are completed.
> In the next couple of days, the remaining patches should
> be done. Do you want us to send them after all are complete
> or is it okay to send each patch as and when completed ?
> 
> Thanks,
> Ravi
> 
> -----Original Message-----
> From: Jeff Garzik [mailto:jgarzik@pobox.com]
> Sent: Friday, October 08, 2004 5:11 PM
> To: ravinandan.arakali@s2io.com
> Cc: 'Francois Romieu'; netdev@oss.sgi.com; leonid.grossman@s2io.com;
> raghavendra.koushik@s2io.com; rapuru.sriram@s2io.com
> Subject: Re: [PATCH 2.6.9-rc2 4/8] S2io: hardware fixes
> 
> 
> 48 hours passed between patch #3 and patch #4.  Is there a problem with 
> your email system?
> 
> Also, your patches do not include the "signed-off-by" line described in 
> the two documents I referenced.  The "signed-off-by" line makes the 
> lawyers happy.
> 
> Since you missed that major legal item, please _read_ the following 
> documents:
> 
> http://linux.yyz.us/patch-format.html (see #5, "Sign your work")
> http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt

Hi,

Maybe you already have this planned or patched, but it wasn't
in the "cosmetic" patch file.

In s2io.c, please convert this struct to C99 syntax:
static struct pci_driver s2io_driver = {
       name:"S2IO",
       id_table:s2io_tbl,
       probe:s2io_init_nic,
       remove:__devexit_p(s2io_rem_nic),
};

so that sparse won't complain like so:
drivers/net/s2io.c:238:7: warning: obsolete struct initializer, use 
C99 syntax
drivers/net/s2io.c:239:7: warning: obsolete struct initializer, use 
C99 syntax
drivers/net/s2io.c:240:7: warning: obsolete struct initializer, use 
C99 syntax
drivers/net/s2io.c:241:7: warning: obsolete struct initializer, use 
C99 syntax

and if you haven't tried sparse on the driver, that would be a
good idea.


-- 
~Randy

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2.6.9-rc2 4/8] S2io: hardware fixes
@ 2004-10-14  1:14 Ravinandan Arakali
  2004-10-14 14:47 ` Jeff Garzik
  0 siblings, 1 reply; 7+ messages in thread
From: Ravinandan Arakali @ 2004-10-14  1:14 UTC (permalink / raw)
  To: 'Jeff Garzik', 'Francois Romieu'
  Cc: netdev, leonid.grossman, raghavendra.koushik, rapuru.sriram

[-- Attachment #1: Type: text/plain, Size: 1215 bytes --]

Hi,
Following are the code changes addressing the hardware errata mentioned in
user guide.

1. Xena3's with a set of subsystem IDs had Link LED problems, fixed that
specifically for
   them.
2. To write into the Keyed Mac_Cfg register to enable broadcast, writing two
32 bit writes
   into it along with a write to the key register rather than a single write
to key and a 64
   bit write to mac_cfg. This is necessary on 32 bit systems where a
writeq(64 bit write) is
   actually two writel (32 bit writes).
3. Writes to some special registers mentioned in UG is being done by a
special macro which
   defines which 32 bits of the 64 bit register is to be written first.
Again this applies
   only on 32 bit systems.
4. Configured pause frame related water marks and a shared_split value which
describes the
   Max TXDMA related split transaction that can be used without giving room
for the Rx
   transactions.
5. The mac_rmac_err_reg R1 register will be cleared in  the interrupt
handler itself rather
   than in the scheduled task as was being done previously.
6. Even on PCC_FB_ECC error the card will be reset by disabling adapter
enable bit.

Signed-off-by: Raghavendra Koushik <raghavendra.koushik@s2io.com>

[-- Attachment #2: s2io_hwfixes.patch4 --]
[-- Type: application/octet-stream, Size: 9942 bytes --]

diff -urN vanilla-linux/drivers/net/s2io.c linux-2.6.8.1/drivers/net/s2io.c
--- vanilla-linux/drivers/net/s2io.c	2004-10-07 11:44:04.000000000 -0700
+++ linux-2.6.8.1/drivers/net/s2io.c	2004-10-07 11:45:41.000000000 -0700
@@ -71,6 +71,15 @@
 static char s2io_driver_name[] = "s2io";
 static char s2io_driver_version[] = "Version 1.7.5.1";
 
+/* 
+ * Cards with following subsystem_id have a link state indication
+ * problem, 600B, 600C, 600D, 640B, 640C and 640D.
+ * macro below identifies these cards given the subsystem_id.
+ */
+#define CARDS_WITH_FAULTY_LINK_INDICATORS(subid) \
+		(((subid >= 0x600B) && (subid <= 0x600D)) || \
+		 ((subid >= 0x640B) && (subid <= 0x640D))) ? 1 : 0
+
 #define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \
 				      ADAPTER_STATUS_RMAC_LOCAL_FAULT)))
 #define TASKLET_IN_USE test_and_set_bit(0, \
@@ -563,10 +572,13 @@
 	schedule_timeout(HZ / 2);
 
 	/*  Enable Receiving broadcasts */
+	add = (void *) &bar0->mac_cfg;
 	val64 = readq(&bar0->mac_cfg);
 	val64 |= MAC_RMAC_BCAST_ENABLE;
 	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
-	writeq(val64, &bar0->mac_cfg);
+	writel((u32) val64, add);
+	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
+	writel((u32) (val64 >> 32), (add + 4));
 
 	/* Read registers in all blocks */
 	val64 = readq(&bar0->mac_int_mask);
@@ -598,8 +610,8 @@
 				dtx_cnt++;
 				goto mdio_cfg;
 			}
-			writeq(default_dtx_cfg[dtx_cnt],
-			       &bar0->dtx_control);
+			SPECIAL_REG_WRITE(default_dtx_cfg[dtx_cnt],
+					  &bar0->dtx_control, UF);
 			val64 = readq(&bar0->dtx_control);
 			dtx_cnt++;
 		}
@@ -609,8 +621,8 @@
 				mdio_cnt++;
 				goto dtx_cfg;
 			}
-			writeq(default_mdio_cfg[mdio_cnt],
-			       &bar0->mdio_control);
+			SPECIAL_REG_WRITE(default_mdio_cfg[mdio_cnt],
+					  &bar0->mdio_control, UF);
 			val64 = readq(&bar0->mdio_control);
 			mdio_cnt++;
 		}
@@ -873,6 +885,47 @@
 	writel((u32) (val64 >> 32), (add + 4));
 	val64 = readq(&bar0->mac_cfg);
 
+	/* 
+	 * Set the time value to be inserted in the pause frame 
+	 * generated by xena.
+	 */
+	val64 = readq(&bar0->rmac_pause_cfg);
+	val64 &= ~(RMAC_PAUSE_HG_PTIME(0xffff));
+	val64 |= RMAC_PAUSE_HG_PTIME(nic->mac_control.rmac_pause_time);
+	writeq(val64, &bar0->rmac_pause_cfg);
+
+	/* 
+	 * Set the Threshold Limit for Generating the pause frame
+	 * If the amount of data in any Queue exceeds ratio of
+	 * (mac_control.mc_pause_threshold_q0q3 or q4q7)/256
+	 * pause frame is generated
+	 */
+	val64 = 0;
+	for (i = 0; i < 4; i++) {
+		val64 |=
+		    (((u64) 0xFF00 | nic->mac_control.
+		      mc_pause_threshold_q0q3)
+		     << (i * 2 * 8));
+	}
+	writeq(val64, &bar0->mc_pause_thresh_q0q3);
+
+	val64 = 0;
+	for (i = 0; i < 4; i++) {
+		val64 |=
+		    (((u64) 0xFF00 | nic->mac_control.
+		      mc_pause_threshold_q4q7)
+		     << (i * 2 * 8));
+	}
+	writeq(val64, &bar0->mc_pause_thresh_q4q7);
+
+	/* 
+	 * TxDMA will stop Read request if the number of read split has 
+	 * exceeded the limit pointed by shared_splits
+	 */
+	val64 = readq(&bar0->pic_control);
+	val64 |= PIC_CNTL_SHARED_SPLITS(0);
+	writeq(val64, &bar0->pic_control);
+
 	return SUCCESS;
 }
 
@@ -1227,7 +1280,7 @@
 	 */
 	val64 = readq(&bar0->mc_rldram_mrs);
 	val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE | MC_RLDRAM_MRS_ENABLE;
-	writeq(val64, &bar0->mc_rldram_mrs);
+	SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF);
 	val64 = readq(&bar0->mc_rldram_mrs);
 
 	set_current_state(TASK_UNINTERRUPTIBLE);
@@ -1291,13 +1344,13 @@
 	 * force link down. Since link is already up, we will get
 	 * link state change interrupt after this reset
 	 */
-	writeq(0x80010515001E0000ULL, &bar0->dtx_control);
+	SPECIAL_REG_WRITE(0x80010515001E0000ULL, &bar0->dtx_control, UF);
 	val64 = readq(&bar0->dtx_control);
 	udelay(50);
-	writeq(0x80010515001E00E0ULL, &bar0->dtx_control);
+	SPECIAL_REG_WRITE(0x80010515001E00E0ULL, &bar0->dtx_control, UF);
 	val64 = readq(&bar0->dtx_control);
 	udelay(50);
-	writeq(0x80070515001F00E4ULL, &bar0->dtx_control);
+	SPECIAL_REG_WRITE(0x80070515001F00E4ULL, &bar0->dtx_control, UF);
 	val64 = readq(&bar0->dtx_control);
 	udelay(50);
 
@@ -1884,6 +1937,7 @@
 
 	/* Handling link status change error Intr */
 	err_reg = readq(&bar0->mac_rmac_err_reg);
+	writeq(err_reg, &bar0->mac_rmac_err_reg);
 	if (err_reg & RMAC_LINK_STATE_CHANGE_INT) {
 		schedule_work(&nic->set_link_task);
 	}
@@ -1896,6 +1950,22 @@
 		schedule_work(&nic->rst_timer_task);
 	}
 
+	/*
+	 * Also as mentioned in the latest Errata sheets if the PCC_FB_ECC
+	 * Error occurs, the adapter will be recycled by disabling the
+	 * adapter enable bit and enabling it again after the device 
+	 * becomes Quiescent.
+	 */
+	val64 = readq(&bar0->pcc_err_reg);
+	writeq(val64, &bar0->pcc_err_reg);
+	if (val64 & PCC_FB_ECC_DB_ERR) {
+		u64 ac = readq(&bar0->adapter_control);
+		ac &= ~(ADAPTER_CNTL_EN);
+		writeq(ac, &bar0->adapter_control);
+		ac = readq(&bar0->adapter_control);
+		schedule_work(&nic->set_link_task);
+	}
+
 	/* Other type of interrupts are not being handled now,  TODO */
 }
 
@@ -2870,12 +2940,13 @@
 
 static int s2io_ethtool_idnic(struct net_device *dev, u32 data)
 {
-	u64 val64 = 0;
+	u64 val64 = 0, last_gpio_ctrl_val;
 	nic_t *sp = dev->priv;
 	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
 	u16 subid;
 
 	subid = sp->pdev->subsystem_device;
+	last_gpio_ctrl_val = readq(&bar0->gpio_control);
 	if ((subid & 0xFF) < 0x07) {
 		val64 = readq(&bar0->adapter_control);
 		if (!(val64 & ADAPTER_CNTL_EN)) {
@@ -2897,6 +2968,11 @@
 		schedule_timeout(MAX_SCHEDULE_TIMEOUT);
 	del_timer_sync(&sp->id_timer);
 
+	if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) {
+		writeq(last_gpio_ctrl_val, &bar0->gpio_control);
+		last_gpio_ctrl_val = readq(&bar0->gpio_control);
+	}
+
 	return 0;
 }
 
@@ -2983,7 +3059,7 @@
 	val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
 	    I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ |
 	    I2C_CONTROL_CNTL_START;
-	writeq(val64, &bar0->i2c_control);
+	SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
 
 	while (exit_cnt < 5) {
 		val64 = readq(&bar0->i2c_control);
@@ -3024,7 +3100,7 @@
 	val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
 	    I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA(data) |
 	    I2C_CONTROL_CNTL_START;
-	writeq(val64, &bar0->i2c_control);
+	SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
 
 	while (exit_cnt < 5) {
 		val64 = readq(&bar0->i2c_control);
@@ -3352,10 +3428,10 @@
 
 	val64 = readq(&bar0->mc_rldram_mrs);
 	val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE;
-	writeq(val64, &bar0->mc_rldram_mrs);
+	SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF);
 
 	val64 |= MC_RLDRAM_MRS_ENABLE;
-	writeq(val64, &bar0->mc_rldram_mrs);
+	SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF);
 
 	while (iteration < 2) {
 		val64 = 0x55555555aaaa0000ULL;
@@ -3757,8 +3833,10 @@
 	nic_t *nic = (nic_t *) data;
 	struct net_device *dev = nic->dev;
 	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
-	register u64 val64, err_reg;
+	register u64 val64;
+	u16 subid;
 
+	subid = nic->pdev->subsystem_device;
 	/* 
 	 * Allow a small delay for the NICs self initiated 
 	 * cleanup to complete.
@@ -3768,16 +3846,19 @@
 
 	val64 = readq(&bar0->adapter_status);
 	if (verify_xena_quiescence(val64, nic->device_enabled_once)) {
-		/* Acknowledge Intr and clear R1 register. */
-		err_reg = readq(&bar0->mac_rmac_err_reg);
-		writeq(err_reg, &bar0->mac_rmac_err_reg);
-
 		if (LINK_IS_UP(val64)) {
 			val64 = readq(&bar0->adapter_control);
 			val64 |= ADAPTER_CNTL_EN;
 			writeq(val64, &bar0->adapter_control);
-			val64 |= ADAPTER_LED_ON;
-			writeq(val64, &bar0->adapter_control);
+			if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) {
+				val64 = readq(&bar0->gpio_control);
+				val64 |= GPIO_CTRL_GPIO_0;
+				writeq(val64, &bar0->gpio_control);
+				val64 = readq(&bar0->gpio_control);
+			} else {
+				val64 |= ADAPTER_LED_ON;
+				writeq(val64, &bar0->adapter_control);
+			}
 			val64 = readq(&bar0->adapter_status);
 			if (!LINK_IS_UP(val64)) {
 				DBG_PRINT(ERR_DBG, "%s:", dev->name);
@@ -3791,6 +3872,12 @@
 			}
 			s2io_link(nic, LINK_UP);
 		} else {
+			if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) {
+				val64 = readq(&bar0->gpio_control);
+				val64 &= ~GPIO_CTRL_GPIO_0;
+				writeq(val64, &bar0->gpio_control);
+				val64 = readq(&bar0->gpio_control);
+			}
 			s2io_link(nic, LINK_DOWN);
 		}
 	} else {		/* NIC is not Quiescent. */
@@ -3917,6 +4004,7 @@
 	return SUCCESS;
 }
 
+
 /**
  *  s2io_link - stops/starts the Tx queue.
  *  @sp : private member of the device structure, which is a pointer to the
diff -urN vanilla-linux/drivers/net/s2io.h linux-2.6.8.1/drivers/net/s2io.h
--- vanilla-linux/drivers/net/s2io.h	2004-10-07 11:44:04.000000000 -0700
+++ linux-2.6.8.1/drivers/net/s2io.h	2004-10-08 15:20:09.316690064 -0700
@@ -693,6 +693,27 @@
 	writel((u32) (val), addr);
 	writel((u32) (val >> 32), (addr + 4));
 }
+
+/* In 32 bit modes, some registers have to be written in a 
+ * particular order to expect correct hardware operation. The
+ * macro SPECIAL_REG_WRITE is used to perform such ordered 
+ * writes. Defines UF (Upper First) and LF (Lower First) will 
+ * be used to specify the required write order.
+ */
+#define UF	1
+#define LF	2
+static inline void SPECIAL_REG_WRITE(u64 val, void *addr, int order)
+{
+	if (order == LF) {
+		writel((u32) (val), addr);
+		writel((u32) (val >> 32), (addr + 4));
+	} else {
+		writel((u32) (val >> 32), (addr + 4));
+		writel((u32) (val), addr);
+	}
+}
+#else
+#define SPECIAL_REG_WRITE(val, addr, dummy) writeq(val, addr)
 #endif
 
 /*  Interrupt related values of Xena */

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2.6.9-rc2 4/8] S2io: hardware fixes
  2004-10-14  1:14 [PATCH 2.6.9-rc2 4/8] S2io: hardware fixes Ravinandan Arakali
@ 2004-10-14 14:47 ` Jeff Garzik
  0 siblings, 0 replies; 7+ messages in thread
From: Jeff Garzik @ 2004-10-14 14:47 UTC (permalink / raw)
  To: ravinandan.arakali
  Cc: 'Francois Romieu', netdev, leonid.grossman,
	raghavendra.koushik, rapuru.sriram

no objections to this patch

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2004-10-14 14:47 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-10-14  1:14 [PATCH 2.6.9-rc2 4/8] S2io: hardware fixes Ravinandan Arakali
2004-10-14 14:47 ` Jeff Garzik
  -- strict thread matches above, loose matches on Subject: below --
2004-10-08 23:30 Ravinandan Arakali
2004-10-09  0:11 ` Jeff Garzik
2004-10-09  0:34   ` Ravinandan Arakali
2004-10-09  0:31     ` Jeff Garzik
2004-10-10  3:24     ` Randy.Dunlap

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