Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2537

kernel-2.6.18-238.el5.src.rpm

From: Andy Gospodarek <gospo@redhat.com>
Date: Thu, 4 Dec 2008 16:56:48 -0500
Subject: [net] cxgb3: eeh and eeprom fixups
Message-id: 20081204215648.GJ26358@gospo.rdu.redhat.com
O-Subject: [RHEL5.3 PATCH] cxgb3: eeh and eeprom fixups
Bugzilla: 441959
RH-Acked-by: John W. Linville <linville@redhat.com>
RH-Acked-by: David Miller <davem@redhat.com>

Hopefully this is the last set of changes that Chelsio would like us to
include for 5.3.  In addition to a fixing a bug introduced by one of my
backports, this patch adds the following upstream commits:

    commit 0ca41c0413a4d9ca58767d53d23accea9aa1cdef
    Author: Divy Le Ray <divy@chelsio.com>
    Date:   Thu Sep 25 14:05:28 2008 +0000

        [2.6.28,1/1] cxgb3 - fix race in EEH

    commit 9f64306b8a3949b74cb11d3b2f613e8a2af20fa6
    Author: Divy Le Ray <divy@chelsio.com>
    Date:   Sun Nov 9 00:55:28 2008 -0800

        cxgb3 - eeprom read fixes

This has been tested by a partner and was suggested by the driver
maintainer at Chelsio, so I feel good about it.

This will resolve RHBZ 441959.

diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 1b6ff1c..3c1b1bb 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -295,6 +295,7 @@ void t3_os_link_changed(struct adapter *adapter, int port_id, int link_status,
 
 void t3_sge_start(struct adapter *adap);
 void t3_sge_stop(struct adapter *adap);
+void t3_stop_sge_timers(struct adapter *adap);
 void t3_free_sge_resources(struct adapter *adap);
 void t3_sge_err_intr_handler(struct adapter *adapter);
 intr_handler_t t3_intr_handler(struct adapter *adap, int polling, 
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index cb7efd3..7873d53 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -533,9 +533,10 @@ static int setup_sge_qsets(struct adapter *adap)
 				(adap->flags & USING_MSIX) ? qset_idx + 1 :
 							     irq_idx,
 				&adap->params.sge.qset[qset_idx], ntxq,
-				j == 0 ? dev :
+				j == pi->first_qset ? dev :
 					 adap-> dummy_netdev[dummy_dev_idx++]);
 			if (err) {
+				t3_stop_sge_timers(adap);
 				t3_free_sge_resources(adap);
 				return err;
 			}
@@ -2580,6 +2581,9 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev,
 	    test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
 		offload_close(&adapter->tdev);
 
+	/* Stop SGE timers */
+	t3_stop_sge_timers(adapter);
+
 	adapter->flags &= ~FULL_INIT_DONE;
 
 	pci_disable_device(pdev);
@@ -2663,7 +2667,7 @@ static void set_nqsets(struct adapter *adap)
 	int hwports = adap->params.nports;
 	int nqsets = SGE_QSETS;
 
-	if (adap->params.rev > 0) {
+	if (adap->params.rev > 0 && adap->flags & USING_MSIX) {
 		if (hwports == 2 &&
 		    (hwports * nqsets > SGE_QSETS ||
 		     num_cpus >= nqsets / hwports))
@@ -2970,6 +2974,7 @@ static void __devexit remove_one(struct pci_dev *pdev)
 		    if (test_bit(i, &adapter->registered_device_map))
 			unregister_netdev(adapter->port[i]);
 
+		t3_stop_sge_timers(adapter);
 		t3_free_sge_resources(adapter);
 		cxgb_disable_msi(adapter);
 
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index f958232..95d18ac 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -583,7 +583,7 @@ static void t3_reset_qset(struct sge_qset *q)
 	memset(q->fl, 0, sizeof(struct sge_fl) * SGE_RXQ_PER_SET);
 	memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET);
 	q->txq_stopped = 0;
-	memset(&q->tx_reclaim_timer, 0, sizeof(q->tx_reclaim_timer));
+	q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */
 	kfree(q->lro_frag_tbl);
 	q->lro_nfrags = q->lro_frag_len = 0;
 }
@@ -3044,6 +3044,24 @@ err:
 }
 
 /**
+ *	t3_stop_sge_timers - stop SGE timer call backs
+ *	@adap: the adapter
+ *
+ *	Stops each SGE queue set's timer call back
+ */
+void t3_stop_sge_timers(struct adapter *adap)
+{
+	int i;
+
+	for (i = 0; i < SGE_QSETS; ++i) {
+		struct sge_qset *q = &adap->sge.qs[i];
+
+		if (q->tx_reclaim_timer.function)
+			del_timer_sync(&q->tx_reclaim_timer);
+	}
+}
+
+/**
  *	t3_free_sge_resources - free SGE resources
  *	@adap: the adapter
  *
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index dce82ac..3be0058 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -522,7 +522,7 @@ struct t3_vpd {
 	u32 pad;		/* for multiple-of-4 sizing and alignment */
 };
 
-#define EEPROM_MAX_POLL   4
+#define EEPROM_MAX_POLL   40
 #define EEPROM_STAT_ADDR  0x4000
 #define VPD_BASE          0xc00
 
@@ -3628,6 +3628,12 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
 			++j;
 
 		p->port_type = &port_types[adapter->params.vpd.port_type[j]];
+		if (!p->port_type->phy_prep) {
+			CH_ALERT(adapter, "Invalid port type index %d\n",
+				 adapter->params.vpd.port_type[j]);
+			return -EINVAL;
+		}
+
 		p->port_type->phy_prep(&p->phy, adapter, ai->phy_base_addr + j,
 				       ai->mdio_ops);
 		mac_prep(&p->mac, adapter, j);