* [TIGON3]: Driver test update
@ 2004-04-01 22:25 David S. Miller
0 siblings, 0 replies; only message in thread
From: David S. Miller @ 2004-04-01 22:25 UTC (permalink / raw)
To: linux-net; +Cc: netdev
[-- Attachment #1: Type: text/plain, Size: 388 bytes --]
I'm trying to kill the remaining link detection problems that
seem to linger in just about every ethernet driver ever written.
:-)
Enclosed are patches against current 2.4.x and 2.6.x vanilla kernel
tg3 driver sources, give it a go and let me know how it goes.
If you're going to report a failure or a "it didn't work before now
it does", please include full 'dmesg' output.
Thanks.
[-- Attachment #2: diff24 --]
[-- Type: application/octet-stream, Size: 11116 bytes --]
--- marcelo-2.4/drivers/net/tg3.c 2004-04-01 14:20:40.569568000 -0800
+++ tg3-2.4/drivers/net/tg3.c 2004-04-01 14:21:57.969568000 -0800
@@ -55,8 +55,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "2.9"
-#define DRV_MODULE_RELDATE "March 8, 2004"
+#define DRV_MODULE_VERSION "3.0"
+#define DRV_MODULE_RELDATE "April 1, 2004"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -642,7 +642,14 @@
tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200);
tg3_writephy(tp, 0x16, 0x0000);
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
+ /* Set Extended packet length bit for jumbo frames */
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4400);
+ }
+ else {
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+ }
tg3_writephy(tp, MII_TG3_CTRL, phy9_orig);
@@ -656,7 +663,7 @@
/* This will reset the tigon3 PHY if there is no valid
* link unless the FORCE argument is non-zero.
*/
-static int tg3_phy_reset(struct tg3 *tp, int force)
+static int tg3_phy_reset(struct tg3 *tp)
{
u32 phy_status;
int err;
@@ -666,12 +673,6 @@
if (err != 0)
return -EBUSY;
- /* If we have link, and not forcing a reset, then nothing
- * to do.
- */
- if ((phy_status & BMSR_LSTATUS) != 0 && (force == 0))
- return 0;
-
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
@@ -698,6 +699,15 @@
tg3_writephy(tp, 0x1c, 0x8d68);
tg3_writephy(tp, 0x1c, 0x8d68);
}
+ /* Set Extended packet length bit (bit 14) on all chips that */
+ /* support jumbo frames */
+ if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401 ||
+ (tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5411) {
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
+ }
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4400);
+ }
tg3_phy_set_wirespeed(tp);
return 0;
}
@@ -1049,6 +1059,8 @@
u32 new_adv;
int i;
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+
if (tp->link_config.phy_is_low_power) {
/* Entering low power mode. Disable gigabit and
* 100baseT advertisements.
@@ -1189,7 +1201,8 @@
int err;
/* Turn off tap power management. */
- err = tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c20);
+ /* Set Extended packet length bit */
+ err = tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x0012);
err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x1804);
@@ -1211,6 +1224,27 @@
return err;
}
+static int tg3_copper_is_advertising_all(struct tg3 *tp)
+{
+ u32 adv_reg, all_mask;
+
+ tg3_readphy(tp, MII_ADVERTISE, &adv_reg);
+ all_mask = (ADVERTISE_10HALF | ADVERTISE_10FULL |
+ ADVERTISE_100HALF | ADVERTISE_100FULL);
+ if ((adv_reg & all_mask) != all_mask)
+ return 0;
+ if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) {
+ u32 tg3_ctrl;
+
+ tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl);
+ all_mask = (MII_TG3_CTRL_ADV_1000_HALF |
+ MII_TG3_CTRL_ADV_1000_FULL);
+ if ((tg3_ctrl & all_mask) != all_mask)
+ return 0;
+ }
+ return 1;
+}
+
static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
{
int current_link_up;
@@ -1239,7 +1273,7 @@
*/
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
- tp->pci_chip_rev_id == CHIPREV_ID_5705_A0) &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
netif_carrier_ok(tp->dev)) {
tg3_readphy(tp, MII_BMSR, &bmsr);
tg3_readphy(tp, MII_BMSR, &bmsr);
@@ -1247,7 +1281,7 @@
force_reset = 1;
}
if (force_reset)
- tg3_phy_reset(tp, 1);
+ tg3_phy_reset(tp);
if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
tg3_readphy(tp, MII_BMSR, &bmsr);
@@ -1274,7 +1308,7 @@
if ((tp->phy_id & PHY_ID_REV_MASK) == PHY_REV_BCM5401_B0 &&
!(bmsr & BMSR_LSTATUS) &&
tp->link_config.active_speed == SPEED_1000) {
- err = tg3_phy_reset(tp, 1);
+ err = tg3_phy_reset(tp);
if (!err)
err = tg3_init_5401phy_dsp(tp);
if (err)
@@ -1309,8 +1343,14 @@
current_speed = SPEED_INVALID;
current_duplex = DUPLEX_INVALID;
- tg3_readphy(tp, MII_BMSR, &bmsr);
- tg3_readphy(tp, MII_BMSR, &bmsr);
+ bmsr = 0;
+ for (i = 0; i < 100; i++) {
+ tg3_readphy(tp, MII_BMSR, &bmsr);
+ tg3_readphy(tp, MII_BMSR, &bmsr);
+ if (bmsr & BMSR_LSTATUS)
+ break;
+ udelay(40);
+ }
if (bmsr & BMSR_LSTATUS) {
u32 aux_stat, bmcr;
@@ -1326,22 +1366,25 @@
tg3_aux_stat_to_speed_duplex(tp, aux_stat,
¤t_speed,
¤t_duplex);
- tg3_readphy(tp, MII_BMCR, &bmcr);
- tg3_readphy(tp, MII_BMCR, &bmcr);
+
+ bmcr = 0;
+ for (i = 0; i < 200; i++) {
+ tg3_readphy(tp, MII_BMCR, &bmcr);
+ tg3_readphy(tp, MII_BMCR, &bmcr);
+ if (bmcr && bmcr != 0x7fff)
+ break;
+ udelay(10);
+ }
+
if (tp->link_config.autoneg == AUTONEG_ENABLE) {
if (bmcr & BMCR_ANENABLE) {
- u32 gig_ctrl;
-
current_link_up = 1;
/* Force autoneg restart if we are exiting
* low power mode.
*/
- tg3_readphy(tp, MII_TG3_CTRL, &gig_ctrl);
- if (!(gig_ctrl & (MII_TG3_CTRL_ADV_1000_HALF |
- MII_TG3_CTRL_ADV_1000_FULL))) {
+ if (!tg3_copper_is_advertising_all(tp))
current_link_up = 0;
- }
} else {
current_link_up = 0;
}
@@ -2003,6 +2046,13 @@
(6 << TX_LENGTHS_IPG_SHIFT) |
(32 << TX_LENGTHS_SLOT_TIME_SHIFT)));
+ if (netif_carrier_ok(tp->dev)) {
+ tw32(HOSTCC_STAT_COAL_TICKS,
+ DEFAULT_STAT_COAL_TICKS);
+ } else {
+ tw32(HOSTCC_STAT_COAL_TICKS, 0);
+ }
+
return err;
}
@@ -4543,6 +4593,13 @@
tw32(TG3PCI_PCISTATE, val);
}
+ if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5704_BX) {
+ /* Enable some hw fixes. */
+ val = tr32(TG3PCI_MSI_DATA);
+ val |= (1 << 26) | (1 << 28) | (1 << 29);
+ tw32(TG3PCI_MSI_DATA, val);
+ }
+
/* Descriptor ring init may make accesses to the
* NIC SRAM area to setup the TX descriptors, so we
* can only do this after the hardware has been
@@ -4573,8 +4630,10 @@
(GRC_MODE_IRQ_ON_MAC_ATTN | GRC_MODE_HOST_STACKUP));
/* Setup the timer prescalar register. Clock is always 66Mhz. */
- tw32(GRC_MISC_CFG,
- (65 << GRC_MISC_CFG_PRESCALAR_SHIFT));
+ val = tr32(GRC_MISC_CFG);
+ val &= ~0xff;
+ val |= (65 << GRC_MISC_CFG_PRESCALAR_SHIFT);
+ tw32(GRC_MISC_CFG, val);
/* Initialize MBUF/DESC pool. */
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
@@ -4635,19 +4694,6 @@
return -ENODEV;
}
- tw32(FTQ_RESET, 0xffffffff);
- tw32(FTQ_RESET, 0x00000000);
- for (i = 0; i < 2000; i++) {
- if (tr32(FTQ_RESET) == 0x00000000)
- break;
- udelay(10);
- }
- if (i >= 2000) {
- printk(KERN_ERR PFX "tg3_reset_hw cannot reset FTQ for %s.\n",
- tp->dev->name);
- return -ENODEV;
- }
-
/* Clear statistics/status block in chip, and status block in ram. */
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
for (i = NIC_SRAM_STATS_BLK;
@@ -4979,8 +5025,17 @@
tw32_f(MAC_RX_MODE, tp->rx_mode);
udelay(10);
- if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1)
- tw32(MAC_SERDES_CFG, 0x616000);
+ if (tp->phy_id == PHY_ID_SERDES) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
+ /* Set drive transmission level to 1.2V */
+ val = tr32(MAC_SERDES_CFG);
+ val &= 0xfffff000;
+ val |= 0x880;
+ tw32(MAC_SERDES_CFG, val);
+ }
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1)
+ tw32(MAC_SERDES_CFG, 0x616000);
+ }
/* Prevent chip from dropping frames when flow control
* is enabled.
@@ -5871,6 +5926,16 @@
tp->link_config.phy_is_low_power)
return -EAGAIN;
+ if (tp->phy_id == PHY_ID_SERDES) {
+ /* These are the only valid advertisement bits allowed. */
+ if (cmd->autoneg == AUTONEG_ENABLE &&
+ (cmd->advertising & ~(ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full |
+ ADVERTISED_Autoneg |
+ ADVERTISED_FIBRE)))
+ return -EINVAL;
+ }
+
spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
@@ -5880,6 +5945,7 @@
tp->link_config.speed = SPEED_INVALID;
tp->link_config.duplex = DUPLEX_INVALID;
} else {
+ tp->link_config.advertising = 0;
tp->link_config.speed = cmd->speed;
tp->link_config.duplex = cmd->duplex;
}
@@ -6476,38 +6542,61 @@
}
}
- err = tg3_phy_reset(tp, 1);
- if (err)
- return err;
+ if (tp->phy_id != PHY_ID_SERDES &&
+ !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+ u32 bmsr, adv_reg, tg3_ctrl;
- if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
- tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) {
- u32 mii_tg3_ctrl;
-
- /* These chips, when reset, only advertise 10Mb
- * capabilities. Fix that.
- */
- err = tg3_writephy(tp, MII_ADVERTISE,
- (ADVERTISE_CSMA |
- ADVERTISE_PAUSE_CAP |
- ADVERTISE_10HALF |
- ADVERTISE_10FULL |
- ADVERTISE_100HALF |
- ADVERTISE_100FULL));
- mii_tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF |
- MII_TG3_CTRL_ADV_1000_FULL |
- MII_TG3_CTRL_AS_MASTER |
- MII_TG3_CTRL_ENABLE_AS_MASTER);
- if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
- mii_tg3_ctrl = 0;
+ tg3_readphy(tp, MII_BMSR, &bmsr);
+ tg3_readphy(tp, MII_BMSR, &bmsr);
+
+ if ((bmsr & BMSR_LSTATUS) &&
+ !(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705))
+ goto skip_phy_reset;
+
+ err = tg3_phy_reset(tp);
+ if (err)
+ return err;
+
+ adv_reg = (ADVERTISE_10HALF | ADVERTISE_10FULL |
+ ADVERTISE_100HALF | ADVERTISE_100FULL |
+ ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
+ tg3_ctrl = 0;
+ if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) {
+ tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF |
+ MII_TG3_CTRL_ADV_1000_FULL);
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
+ tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)
+ tg3_ctrl |= (MII_TG3_CTRL_AS_MASTER |
+ MII_TG3_CTRL_ENABLE_AS_MASTER);
+ }
- err |= tg3_writephy(tp, MII_TG3_CTRL, mii_tg3_ctrl);
- err |= tg3_writephy(tp, MII_BMCR,
- (BMCR_ANRESTART | BMCR_ANENABLE));
+ if (!tg3_copper_is_advertising_all(tp)) {
+ tg3_writephy(tp, MII_ADVERTISE, adv_reg);
+
+ if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
+ tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl);
+
+ tg3_writephy(tp, MII_BMCR,
+ BMCR_ANENABLE | BMCR_ANRESTART);
+ }
+ tg3_phy_set_wirespeed(tp);
+
+ tg3_writephy(tp, MII_ADVERTISE, adv_reg);
+ if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
+ tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl);
+ }
+
+skip_phy_reset:
+ if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
+ err = tg3_init_5401phy_dsp(tp);
+ if (err)
+ return err;
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) {
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c00);
tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x201f);
tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x2aaa);
}
[-- Attachment #3: diff26 --]
[-- Type: application/octet-stream, Size: 11114 bytes --]
--- linus-2.6/drivers/net/tg3.c 2004-03-31 15:14:55.000000000 -0800
+++ tg3-2.6/drivers/net/tg3.c 2004-04-01 14:21:41.089568000 -0800
@@ -56,8 +56,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "2.9"
-#define DRV_MODULE_RELDATE "March 8, 2004"
+#define DRV_MODULE_VERSION "3.0"
+#define DRV_MODULE_RELDATE "April 1, 2004"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -643,7 +643,14 @@
tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200);
tg3_writephy(tp, 0x16, 0x0000);
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
+ /* Set Extended packet length bit for jumbo frames */
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4400);
+ }
+ else {
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+ }
tg3_writephy(tp, MII_TG3_CTRL, phy9_orig);
@@ -657,7 +664,7 @@
/* This will reset the tigon3 PHY if there is no valid
* link unless the FORCE argument is non-zero.
*/
-static int tg3_phy_reset(struct tg3 *tp, int force)
+static int tg3_phy_reset(struct tg3 *tp)
{
u32 phy_status;
int err;
@@ -667,12 +674,6 @@
if (err != 0)
return -EBUSY;
- /* If we have link, and not forcing a reset, then nothing
- * to do.
- */
- if ((phy_status & BMSR_LSTATUS) != 0 && (force == 0))
- return 0;
-
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
@@ -699,6 +700,15 @@
tg3_writephy(tp, 0x1c, 0x8d68);
tg3_writephy(tp, 0x1c, 0x8d68);
}
+ /* Set Extended packet length bit (bit 14) on all chips that */
+ /* support jumbo frames */
+ if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401 ||
+ (tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5411) {
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
+ }
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4400);
+ }
tg3_phy_set_wirespeed(tp);
return 0;
}
@@ -1050,6 +1060,8 @@
u32 new_adv;
int i;
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+
if (tp->link_config.phy_is_low_power) {
/* Entering low power mode. Disable gigabit and
* 100baseT advertisements.
@@ -1190,7 +1202,8 @@
int err;
/* Turn off tap power management. */
- err = tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c20);
+ /* Set Extended packet length bit */
+ err = tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x0012);
err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x1804);
@@ -1212,6 +1225,27 @@
return err;
}
+static int tg3_copper_is_advertising_all(struct tg3 *tp)
+{
+ u32 adv_reg, all_mask;
+
+ tg3_readphy(tp, MII_ADVERTISE, &adv_reg);
+ all_mask = (ADVERTISE_10HALF | ADVERTISE_10FULL |
+ ADVERTISE_100HALF | ADVERTISE_100FULL);
+ if ((adv_reg & all_mask) != all_mask)
+ return 0;
+ if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) {
+ u32 tg3_ctrl;
+
+ tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl);
+ all_mask = (MII_TG3_CTRL_ADV_1000_HALF |
+ MII_TG3_CTRL_ADV_1000_FULL);
+ if ((tg3_ctrl & all_mask) != all_mask)
+ return 0;
+ }
+ return 1;
+}
+
static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
{
int current_link_up;
@@ -1240,7 +1274,7 @@
*/
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
- tp->pci_chip_rev_id == CHIPREV_ID_5705_A0) &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
netif_carrier_ok(tp->dev)) {
tg3_readphy(tp, MII_BMSR, &bmsr);
tg3_readphy(tp, MII_BMSR, &bmsr);
@@ -1248,7 +1282,7 @@
force_reset = 1;
}
if (force_reset)
- tg3_phy_reset(tp, 1);
+ tg3_phy_reset(tp);
if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
tg3_readphy(tp, MII_BMSR, &bmsr);
@@ -1275,7 +1309,7 @@
if ((tp->phy_id & PHY_ID_REV_MASK) == PHY_REV_BCM5401_B0 &&
!(bmsr & BMSR_LSTATUS) &&
tp->link_config.active_speed == SPEED_1000) {
- err = tg3_phy_reset(tp, 1);
+ err = tg3_phy_reset(tp);
if (!err)
err = tg3_init_5401phy_dsp(tp);
if (err)
@@ -1310,8 +1344,14 @@
current_speed = SPEED_INVALID;
current_duplex = DUPLEX_INVALID;
- tg3_readphy(tp, MII_BMSR, &bmsr);
- tg3_readphy(tp, MII_BMSR, &bmsr);
+ bmsr = 0;
+ for (i = 0; i < 100; i++) {
+ tg3_readphy(tp, MII_BMSR, &bmsr);
+ tg3_readphy(tp, MII_BMSR, &bmsr);
+ if (bmsr & BMSR_LSTATUS)
+ break;
+ udelay(40);
+ }
if (bmsr & BMSR_LSTATUS) {
u32 aux_stat, bmcr;
@@ -1327,22 +1367,25 @@
tg3_aux_stat_to_speed_duplex(tp, aux_stat,
¤t_speed,
¤t_duplex);
- tg3_readphy(tp, MII_BMCR, &bmcr);
- tg3_readphy(tp, MII_BMCR, &bmcr);
+
+ bmcr = 0;
+ for (i = 0; i < 200; i++) {
+ tg3_readphy(tp, MII_BMCR, &bmcr);
+ tg3_readphy(tp, MII_BMCR, &bmcr);
+ if (bmcr && bmcr != 0x7fff)
+ break;
+ udelay(10);
+ }
+
if (tp->link_config.autoneg == AUTONEG_ENABLE) {
if (bmcr & BMCR_ANENABLE) {
- u32 gig_ctrl;
-
current_link_up = 1;
/* Force autoneg restart if we are exiting
* low power mode.
*/
- tg3_readphy(tp, MII_TG3_CTRL, &gig_ctrl);
- if (!(gig_ctrl & (MII_TG3_CTRL_ADV_1000_HALF |
- MII_TG3_CTRL_ADV_1000_FULL))) {
+ if (!tg3_copper_is_advertising_all(tp))
current_link_up = 0;
- }
} else {
current_link_up = 0;
}
@@ -2004,6 +2047,13 @@
(6 << TX_LENGTHS_IPG_SHIFT) |
(32 << TX_LENGTHS_SLOT_TIME_SHIFT)));
+ if (netif_carrier_ok(tp->dev)) {
+ tw32(HOSTCC_STAT_COAL_TICKS,
+ DEFAULT_STAT_COAL_TICKS);
+ } else {
+ tw32(HOSTCC_STAT_COAL_TICKS, 0);
+ }
+
return err;
}
@@ -4552,6 +4602,13 @@
tw32(TG3PCI_PCISTATE, val);
}
+ if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5704_BX) {
+ /* Enable some hw fixes. */
+ val = tr32(TG3PCI_MSI_DATA);
+ val |= (1 << 26) | (1 << 28) | (1 << 29);
+ tw32(TG3PCI_MSI_DATA, val);
+ }
+
/* Descriptor ring init may make accesses to the
* NIC SRAM area to setup the TX descriptors, so we
* can only do this after the hardware has been
@@ -4582,8 +4639,10 @@
(GRC_MODE_IRQ_ON_MAC_ATTN | GRC_MODE_HOST_STACKUP));
/* Setup the timer prescalar register. Clock is always 66Mhz. */
- tw32(GRC_MISC_CFG,
- (65 << GRC_MISC_CFG_PRESCALAR_SHIFT));
+ val = tr32(GRC_MISC_CFG);
+ val &= ~0xff;
+ val |= (65 << GRC_MISC_CFG_PRESCALAR_SHIFT);
+ tw32(GRC_MISC_CFG, val);
/* Initialize MBUF/DESC pool. */
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
@@ -4644,19 +4703,6 @@
return -ENODEV;
}
- tw32(FTQ_RESET, 0xffffffff);
- tw32(FTQ_RESET, 0x00000000);
- for (i = 0; i < 2000; i++) {
- if (tr32(FTQ_RESET) == 0x00000000)
- break;
- udelay(10);
- }
- if (i >= 2000) {
- printk(KERN_ERR PFX "tg3_reset_hw cannot reset FTQ for %s.\n",
- tp->dev->name);
- return -ENODEV;
- }
-
/* Clear statistics/status block in chip, and status block in ram. */
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
for (i = NIC_SRAM_STATS_BLK;
@@ -4988,8 +5034,17 @@
tw32_f(MAC_RX_MODE, tp->rx_mode);
udelay(10);
- if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1)
- tw32(MAC_SERDES_CFG, 0x616000);
+ if (tp->phy_id == PHY_ID_SERDES) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
+ /* Set drive transmission level to 1.2V */
+ val = tr32(MAC_SERDES_CFG);
+ val &= 0xfffff000;
+ val |= 0x880;
+ tw32(MAC_SERDES_CFG, val);
+ }
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1)
+ tw32(MAC_SERDES_CFG, 0x616000);
+ }
/* Prevent chip from dropping frames when flow control
* is enabled.
@@ -5882,6 +5937,16 @@
tp->link_config.phy_is_low_power)
return -EAGAIN;
+ if (tp->phy_id == PHY_ID_SERDES) {
+ /* These are the only valid advertisement bits allowed. */
+ if (cmd->autoneg == AUTONEG_ENABLE &&
+ (cmd->advertising & ~(ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full |
+ ADVERTISED_Autoneg |
+ ADVERTISED_FIBRE)))
+ return -EINVAL;
+ }
+
spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock);
@@ -5891,6 +5956,7 @@
tp->link_config.speed = SPEED_INVALID;
tp->link_config.duplex = DUPLEX_INVALID;
} else {
+ tp->link_config.advertising = 0;
tp->link_config.speed = cmd->speed;
tp->link_config.duplex = cmd->duplex;
}
@@ -6487,38 +6553,61 @@
}
}
- err = tg3_phy_reset(tp, 1);
- if (err)
- return err;
+ if (tp->phy_id != PHY_ID_SERDES &&
+ !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+ u32 bmsr, adv_reg, tg3_ctrl;
- if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
- tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) {
- u32 mii_tg3_ctrl;
-
- /* These chips, when reset, only advertise 10Mb
- * capabilities. Fix that.
- */
- err = tg3_writephy(tp, MII_ADVERTISE,
- (ADVERTISE_CSMA |
- ADVERTISE_PAUSE_CAP |
- ADVERTISE_10HALF |
- ADVERTISE_10FULL |
- ADVERTISE_100HALF |
- ADVERTISE_100FULL));
- mii_tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF |
- MII_TG3_CTRL_ADV_1000_FULL |
- MII_TG3_CTRL_AS_MASTER |
- MII_TG3_CTRL_ENABLE_AS_MASTER);
- if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
- mii_tg3_ctrl = 0;
+ tg3_readphy(tp, MII_BMSR, &bmsr);
+ tg3_readphy(tp, MII_BMSR, &bmsr);
+
+ if ((bmsr & BMSR_LSTATUS) &&
+ !(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705))
+ goto skip_phy_reset;
+
+ err = tg3_phy_reset(tp);
+ if (err)
+ return err;
+
+ adv_reg = (ADVERTISE_10HALF | ADVERTISE_10FULL |
+ ADVERTISE_100HALF | ADVERTISE_100FULL |
+ ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
+ tg3_ctrl = 0;
+ if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) {
+ tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF |
+ MII_TG3_CTRL_ADV_1000_FULL);
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
+ tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)
+ tg3_ctrl |= (MII_TG3_CTRL_AS_MASTER |
+ MII_TG3_CTRL_ENABLE_AS_MASTER);
+ }
- err |= tg3_writephy(tp, MII_TG3_CTRL, mii_tg3_ctrl);
- err |= tg3_writephy(tp, MII_BMCR,
- (BMCR_ANRESTART | BMCR_ANENABLE));
+ if (!tg3_copper_is_advertising_all(tp)) {
+ tg3_writephy(tp, MII_ADVERTISE, adv_reg);
+
+ if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
+ tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl);
+
+ tg3_writephy(tp, MII_BMCR,
+ BMCR_ANENABLE | BMCR_ANRESTART);
+ }
+ tg3_phy_set_wirespeed(tp);
+
+ tg3_writephy(tp, MII_ADVERTISE, adv_reg);
+ if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY))
+ tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl);
+ }
+
+skip_phy_reset:
+ if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
+ err = tg3_init_5401phy_dsp(tp);
+ if (err)
+ return err;
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) {
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c00);
tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x201f);
tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x2aaa);
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2004-04-01 22:25 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-04-01 22:25 [TIGON3]: Driver test update David S. Miller
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).