Commit c6026d08 authored by David S. Miller's avatar David S. Miller

Merge nuts.davemloft.net:/disk1/BK/tg3work-2.6

into nuts.davemloft.net:/disk1/BK/tg3-2.6
parents eccf6f14 0a4a1881
...@@ -56,8 +56,8 @@ ...@@ -56,8 +56,8 @@
#define DRV_MODULE_NAME "tg3" #define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": " #define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "2.9" #define DRV_MODULE_VERSION "3.1"
#define DRV_MODULE_RELDATE "March 8, 2004" #define DRV_MODULE_RELDATE "April 3, 2004"
#define TG3_DEF_MAC_MODE 0 #define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0 #define TG3_DEF_RX_MODE 0
...@@ -643,7 +643,14 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) ...@@ -643,7 +643,14 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200); tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200);
tg3_writephy(tp, 0x16, 0x0000); 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); tg3_writephy(tp, MII_TG3_CTRL, phy9_orig);
...@@ -657,7 +664,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) ...@@ -657,7 +664,7 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
/* This will reset the tigon3 PHY if there is no valid /* This will reset the tigon3 PHY if there is no valid
* link unless the FORCE argument is non-zero. * 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; u32 phy_status;
int err; int err;
...@@ -667,12 +674,6 @@ static int tg3_phy_reset(struct tg3 *tp, int force) ...@@ -667,12 +674,6 @@ static int tg3_phy_reset(struct tg3 *tp, int force)
if (err != 0) if (err != 0)
return -EBUSY; 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 || 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_5704 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
...@@ -699,6 +700,15 @@ static int tg3_phy_reset(struct tg3 *tp, int force) ...@@ -699,6 +700,15 @@ static int tg3_phy_reset(struct tg3 *tp, int force)
tg3_writephy(tp, 0x1c, 0x8d68); tg3_writephy(tp, 0x1c, 0x8d68);
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); tg3_phy_set_wirespeed(tp);
return 0; return 0;
} }
...@@ -1050,6 +1060,8 @@ static int tg3_phy_copper_begin(struct tg3 *tp) ...@@ -1050,6 +1060,8 @@ static int tg3_phy_copper_begin(struct tg3 *tp)
u32 new_adv; u32 new_adv;
int i; int i;
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
if (tp->link_config.phy_is_low_power) { if (tp->link_config.phy_is_low_power) {
/* Entering low power mode. Disable gigabit and /* Entering low power mode. Disable gigabit and
* 100baseT advertisements. * 100baseT advertisements.
...@@ -1190,7 +1202,8 @@ static int tg3_init_5401phy_dsp(struct tg3 *tp) ...@@ -1190,7 +1202,8 @@ static int tg3_init_5401phy_dsp(struct tg3 *tp)
int err; int err;
/* Turn off tap power management. */ /* 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_ADDRESS, 0x0012);
err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x1804); err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x1804);
...@@ -1212,6 +1225,27 @@ static int tg3_init_5401phy_dsp(struct tg3 *tp) ...@@ -1212,6 +1225,27 @@ static int tg3_init_5401phy_dsp(struct tg3 *tp)
return err; 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) static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
{ {
int current_link_up; int current_link_up;
...@@ -1240,7 +1274,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) ...@@ -1240,7 +1274,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
*/ */
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || 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_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)) { netif_carrier_ok(tp->dev)) {
tg3_readphy(tp, MII_BMSR, &bmsr); tg3_readphy(tp, MII_BMSR, &bmsr);
tg3_readphy(tp, MII_BMSR, &bmsr); tg3_readphy(tp, MII_BMSR, &bmsr);
...@@ -1248,7 +1282,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) ...@@ -1248,7 +1282,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
force_reset = 1; force_reset = 1;
} }
if (force_reset) if (force_reset)
tg3_phy_reset(tp, 1); tg3_phy_reset(tp);
if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
tg3_readphy(tp, MII_BMSR, &bmsr); tg3_readphy(tp, MII_BMSR, &bmsr);
...@@ -1275,7 +1309,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) ...@@ -1275,7 +1309,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
if ((tp->phy_id & PHY_ID_REV_MASK) == PHY_REV_BCM5401_B0 && if ((tp->phy_id & PHY_ID_REV_MASK) == PHY_REV_BCM5401_B0 &&
!(bmsr & BMSR_LSTATUS) && !(bmsr & BMSR_LSTATUS) &&
tp->link_config.active_speed == SPEED_1000) { tp->link_config.active_speed == SPEED_1000) {
err = tg3_phy_reset(tp, 1); err = tg3_phy_reset(tp);
if (!err) if (!err)
err = tg3_init_5401phy_dsp(tp); err = tg3_init_5401phy_dsp(tp);
if (err) if (err)
...@@ -1310,8 +1344,14 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) ...@@ -1310,8 +1344,14 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
current_speed = SPEED_INVALID; current_speed = SPEED_INVALID;
current_duplex = DUPLEX_INVALID; current_duplex = DUPLEX_INVALID;
tg3_readphy(tp, MII_BMSR, &bmsr); bmsr = 0;
tg3_readphy(tp, MII_BMSR, &bmsr); 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) { if (bmsr & BMSR_LSTATUS) {
u32 aux_stat, bmcr; u32 aux_stat, bmcr;
...@@ -1327,22 +1367,25 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) ...@@ -1327,22 +1367,25 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
tg3_aux_stat_to_speed_duplex(tp, aux_stat, tg3_aux_stat_to_speed_duplex(tp, aux_stat,
&current_speed, &current_speed,
&current_duplex); &current_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 (tp->link_config.autoneg == AUTONEG_ENABLE) {
if (bmcr & BMCR_ANENABLE) { if (bmcr & BMCR_ANENABLE) {
u32 gig_ctrl;
current_link_up = 1; current_link_up = 1;
/* Force autoneg restart if we are exiting /* Force autoneg restart if we are exiting
* low power mode. * low power mode.
*/ */
tg3_readphy(tp, MII_TG3_CTRL, &gig_ctrl); if (!tg3_copper_is_advertising_all(tp))
if (!(gig_ctrl & (MII_TG3_CTRL_ADV_1000_HALF |
MII_TG3_CTRL_ADV_1000_FULL))) {
current_link_up = 0; current_link_up = 0;
}
} else { } else {
current_link_up = 0; current_link_up = 0;
} }
...@@ -2004,6 +2047,13 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset) ...@@ -2004,6 +2047,13 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
(6 << TX_LENGTHS_IPG_SHIFT) | (6 << TX_LENGTHS_IPG_SHIFT) |
(32 << TX_LENGTHS_SLOT_TIME_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; return err;
} }
...@@ -3398,10 +3448,11 @@ static int tg3_abort_hw(struct tg3 *tp) ...@@ -3398,10 +3448,11 @@ static int tg3_abort_hw(struct tg3 *tp)
} }
/* tp->lock is held. */ /* tp->lock is held. */
static void tg3_chip_reset(struct tg3 *tp) static int tg3_chip_reset(struct tg3 *tp)
{ {
u32 val; u32 val;
u32 flags_save; u32 flags_save;
int i;
if (!(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) { if (!(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) {
/* Force NVRAM to settle. /* Force NVRAM to settle.
...@@ -3469,6 +3520,8 @@ static void tg3_chip_reset(struct tg3 *tp) ...@@ -3469,6 +3520,8 @@ static void tg3_chip_reset(struct tg3 *tp)
tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
tw32(GRC_MODE, tp->grc_mode);
if ((tp->nic_sram_data_cfg & NIC_SRAM_DATA_CFG_MINI_PCI) != 0 && if ((tp->nic_sram_data_cfg & NIC_SRAM_DATA_CFG_MINI_PCI) != 0 &&
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
tp->pci_clock_ctrl |= tp->pci_clock_ctrl |=
...@@ -3476,7 +3529,45 @@ static void tg3_chip_reset(struct tg3 *tp) ...@@ -3476,7 +3529,45 @@ static void tg3_chip_reset(struct tg3 *tp)
tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl);
} }
tw32(TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl); /* Prevent PXE from restarting. */
tg3_write_mem(tp,
NIC_SRAM_FIRMWARE_MBOX,
NIC_SRAM_FIRMWARE_MBOX_MAGIC1);
if (tp->phy_id == PHY_ID_SERDES) {
tp->mac_mode = MAC_MODE_PORT_MODE_TBI;
tw32_f(MAC_MODE, tp->mac_mode);
} else
tw32_f(MAC_MODE, 0);
udelay(40);
/* Wait for firmware initialization to complete. */
for (i = 0; i < 100000; i++) {
tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val);
if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
break;
udelay(10);
}
if (i >= 100000 &&
!(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) {
printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, "
"firmware will not restart magic=%08x\n",
tp->dev->name, val);
return -ENODEV;
}
/* Reprobe ASF enable state. */
tp->tg3_flags &= ~TG3_FLAG_ENABLE_ASF;
tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
if (val == NIC_SRAM_DATA_SIG_MAGIC) {
u32 nic_cfg;
tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE)
tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
}
return 0;
} }
/* tp->lock is held. */ /* tp->lock is held. */
...@@ -3503,40 +3594,17 @@ static void tg3_stop_fw(struct tg3 *tp) ...@@ -3503,40 +3594,17 @@ static void tg3_stop_fw(struct tg3 *tp)
/* tp->lock is held. */ /* tp->lock is held. */
static int tg3_halt(struct tg3 *tp) static int tg3_halt(struct tg3 *tp)
{ {
u32 val; int err;
int i;
tg3_stop_fw(tp); tg3_stop_fw(tp);
tg3_abort_hw(tp); tg3_abort_hw(tp);
tg3_chip_reset(tp); err = tg3_chip_reset(tp);
tg3_write_mem(tp, if (err)
NIC_SRAM_FIRMWARE_MBOX, return err;
NIC_SRAM_FIRMWARE_MBOX_MAGIC1);
for (i = 0; i < 100000; i++) {
tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val);
if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
break;
udelay(10);
}
if (i >= 100000 &&
!(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) {
printk(KERN_ERR PFX "tg3_halt timed out for %s, "
"firmware will not restart magic=%08x\n",
tp->dev->name, val);
return -ENODEV;
}
if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)
if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)
tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
DRV_STATE_WOL);
else
tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
DRV_STATE_UNLOAD);
} else
tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX, tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
DRV_STATE_SUSPEND); DRV_STATE_UNLOAD);
return 0; return 0;
} }
...@@ -4500,36 +4568,9 @@ static int tg3_reset_hw(struct tg3 *tp) ...@@ -4500,36 +4568,9 @@ static int tg3_reset_hw(struct tg3 *tp)
return err; return err;
} }
tg3_chip_reset(tp); err = tg3_chip_reset(tp);
if (err)
val = tr32(GRC_MODE); return err;
val &= GRC_MODE_HOST_STACKUP;
tw32(GRC_MODE, val | tp->grc_mode);
tg3_write_mem(tp,
NIC_SRAM_FIRMWARE_MBOX,
NIC_SRAM_FIRMWARE_MBOX_MAGIC1);
if (tp->phy_id == PHY_ID_SERDES) {
tp->mac_mode = MAC_MODE_PORT_MODE_TBI;
tw32_f(MAC_MODE, tp->mac_mode);
} else
tw32_f(MAC_MODE, 0);
udelay(40);
/* Wait for firmware initialization to complete. */
for (i = 0; i < 100000; i++) {
tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val);
if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
break;
udelay(10);
}
if (i >= 100000 &&
!(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) {
printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, "
"firmware will not restart magic=%08x\n",
tp->dev->name, val);
return -ENODEV;
}
if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)
tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX, tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
...@@ -4552,6 +4593,13 @@ static int tg3_reset_hw(struct tg3 *tp) ...@@ -4552,6 +4593,13 @@ static int tg3_reset_hw(struct tg3 *tp)
tw32(TG3PCI_PCISTATE, val); 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 /* Descriptor ring init may make accesses to the
* NIC SRAM area to setup the TX descriptors, so we * NIC SRAM area to setup the TX descriptors, so we
* can only do this after the hardware has been * can only do this after the hardware has been
...@@ -4582,8 +4630,10 @@ static int tg3_reset_hw(struct tg3 *tp) ...@@ -4582,8 +4630,10 @@ static int tg3_reset_hw(struct tg3 *tp)
(GRC_MODE_IRQ_ON_MAC_ATTN | GRC_MODE_HOST_STACKUP)); (GRC_MODE_IRQ_ON_MAC_ATTN | GRC_MODE_HOST_STACKUP));
/* Setup the timer prescalar register. Clock is always 66Mhz. */ /* Setup the timer prescalar register. Clock is always 66Mhz. */
tw32(GRC_MISC_CFG, val = tr32(GRC_MISC_CFG);
(65 << GRC_MISC_CFG_PRESCALAR_SHIFT)); val &= ~0xff;
val |= (65 << GRC_MISC_CFG_PRESCALAR_SHIFT);
tw32(GRC_MISC_CFG, val);
/* Initialize MBUF/DESC pool. */ /* Initialize MBUF/DESC pool. */
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
...@@ -4644,19 +4694,6 @@ static int tg3_reset_hw(struct tg3 *tp) ...@@ -4644,19 +4694,6 @@ static int tg3_reset_hw(struct tg3 *tp)
return -ENODEV; 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. */ /* Clear statistics/status block in chip, and status block in ram. */
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
for (i = NIC_SRAM_STATS_BLK; for (i = NIC_SRAM_STATS_BLK;
...@@ -4988,8 +5025,17 @@ static int tg3_reset_hw(struct tg3 *tp) ...@@ -4988,8 +5025,17 @@ static int tg3_reset_hw(struct tg3 *tp)
tw32_f(MAC_RX_MODE, tp->rx_mode); tw32_f(MAC_RX_MODE, tp->rx_mode);
udelay(10); udelay(10);
if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1) if (tp->phy_id == PHY_ID_SERDES) {
tw32(MAC_SERDES_CFG, 0x616000); 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 /* Prevent chip from dropping frames when flow control
* is enabled. * is enabled.
...@@ -5882,6 +5928,16 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -5882,6 +5928,16 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
tp->link_config.phy_is_low_power) tp->link_config.phy_is_low_power)
return -EAGAIN; 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_irq(&tp->lock);
spin_lock(&tp->tx_lock); spin_lock(&tp->tx_lock);
...@@ -5891,6 +5947,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -5891,6 +5947,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
tp->link_config.speed = SPEED_INVALID; tp->link_config.speed = SPEED_INVALID;
tp->link_config.duplex = DUPLEX_INVALID; tp->link_config.duplex = DUPLEX_INVALID;
} else { } else {
tp->link_config.advertising = 0;
tp->link_config.speed = cmd->speed; tp->link_config.speed = cmd->speed;
tp->link_config.duplex = cmd->duplex; tp->link_config.duplex = cmd->duplex;
} }
...@@ -6357,8 +6414,8 @@ static struct subsys_tbl_ent subsys_id_to_phy_id[] = { ...@@ -6357,8 +6414,8 @@ static struct subsys_tbl_ent subsys_id_to_phy_id[] = {
{ PCI_VENDOR_ID_BROADCOM, 0x0007, PHY_ID_SERDES }, /* BCM95701A7 */ { PCI_VENDOR_ID_BROADCOM, 0x0007, PHY_ID_SERDES }, /* BCM95701A7 */
{ PCI_VENDOR_ID_BROADCOM, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */ { PCI_VENDOR_ID_BROADCOM, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */
{ PCI_VENDOR_ID_BROADCOM, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */ { PCI_VENDOR_ID_BROADCOM, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */
{ PCI_VENDOR_ID_BROADCOM, 0x0009, PHY_ID_BCM5701 }, /* BCM95703Ax1 */ { PCI_VENDOR_ID_BROADCOM, 0x0009, PHY_ID_BCM5703 }, /* BCM95703Ax1 */
{ PCI_VENDOR_ID_BROADCOM, 0x8009, PHY_ID_BCM5701 }, /* BCM95703Ax2 */ { PCI_VENDOR_ID_BROADCOM, 0x8009, PHY_ID_BCM5703 }, /* BCM95703Ax2 */
/* 3com boards. */ /* 3com boards. */
{ PCI_VENDOR_ID_3COM, 0x1000, PHY_ID_BCM5401 }, /* 3C996T */ { PCI_VENDOR_ID_3COM, 0x1000, PHY_ID_BCM5401 }, /* 3C996T */
...@@ -6458,19 +6515,27 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) ...@@ -6458,19 +6515,27 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
tp->tg3_flags |= TG3_FLAG_SERDES_WOL_CAP; tp->tg3_flags |= TG3_FLAG_SERDES_WOL_CAP;
} }
/* Now read the physical PHY_ID from the chip and verify /* Reading the PHY ID register can conflict with ASF
* that it is sane. If it doesn't look good, we fall back * firwmare access to the PHY hardware.
* to either the hard-coded table based PHY_ID and failing
* that the value found in the eeprom area.
*/ */
err = tg3_readphy(tp, MII_PHYSID1, &hw_phy_id_1); err = 0;
err |= tg3_readphy(tp, MII_PHYSID2, &hw_phy_id_2); if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
hw_phy_id = hw_phy_id_masked = PHY_ID_INVALID;
} else {
/* Now read the physical PHY_ID from the chip and verify
* that it is sane. If it doesn't look good, we fall back
* to either the hard-coded table based PHY_ID and failing
* that the value found in the eeprom area.
*/
err |= tg3_readphy(tp, MII_PHYSID1, &hw_phy_id_1);
err |= tg3_readphy(tp, MII_PHYSID2, &hw_phy_id_2);
hw_phy_id = (hw_phy_id_1 & 0xffff) << 10; hw_phy_id = (hw_phy_id_1 & 0xffff) << 10;
hw_phy_id |= (hw_phy_id_2 & 0xfc00) << 16; hw_phy_id |= (hw_phy_id_2 & 0xfc00) << 16;
hw_phy_id |= (hw_phy_id_2 & 0x03ff) << 0; hw_phy_id |= (hw_phy_id_2 & 0x03ff) << 0;
hw_phy_id_masked = hw_phy_id & PHY_ID_MASK; hw_phy_id_masked = hw_phy_id & PHY_ID_MASK;
}
if (!err && KNOWN_PHY_ID(hw_phy_id_masked)) { if (!err && KNOWN_PHY_ID(hw_phy_id_masked)) {
tp->phy_id = hw_phy_id; tp->phy_id = hw_phy_id;
...@@ -6487,38 +6552,61 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) ...@@ -6487,38 +6552,61 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
} }
} }
err = tg3_phy_reset(tp, 1); if (tp->phy_id != PHY_ID_SERDES &&
if (err) !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
return err; u32 bmsr, adv_reg, tg3_ctrl;
if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 || tg3_readphy(tp, MII_BMSR, &bmsr);
tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) { tg3_readphy(tp, MII_BMSR, &bmsr);
u32 mii_tg3_ctrl;
if ((bmsr & BMSR_LSTATUS) &&
/* These chips, when reset, only advertise 10Mb !(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
* capabilities. Fix that. GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
*/ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705))
err = tg3_writephy(tp, MII_ADVERTISE, goto skip_phy_reset;
(ADVERTISE_CSMA |
ADVERTISE_PAUSE_CAP | err = tg3_phy_reset(tp);
ADVERTISE_10HALF | if (err)
ADVERTISE_10FULL | return err;
ADVERTISE_100HALF |
ADVERTISE_100FULL)); adv_reg = (ADVERTISE_10HALF | ADVERTISE_10FULL |
mii_tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF | ADVERTISE_100HALF | ADVERTISE_100FULL |
MII_TG3_CTRL_ADV_1000_FULL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
MII_TG3_CTRL_AS_MASTER | tg3_ctrl = 0;
MII_TG3_CTRL_ENABLE_AS_MASTER); if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) {
if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF |
mii_tg3_ctrl = 0; 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);
}
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);
err |= tg3_writephy(tp, MII_TG3_CTRL, mii_tg3_ctrl); tg3_writephy(tp, MII_BMCR,
err |= tg3_writephy(tp, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
(BMCR_ANRESTART | BMCR_ANENABLE)); }
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) { 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_ADDRESS, 0x201f);
tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x2aaa); tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x2aaa);
} }
...@@ -7739,6 +7827,19 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, ...@@ -7739,6 +7827,19 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
printk("%2.2x%c", dev->dev_addr[i], printk("%2.2x%c", dev->dev_addr[i],
i == 5 ? '\n' : ':'); i == 5 ? '\n' : ':');
printk(KERN_INFO "%s: HostTXDS[%d] RXcsums[%d] LinkChgREG[%d] "
"MIirq[%d] ASF[%d] Split[%d] WireSpeed[%d] "
"TSOcap[%d] \n",
dev->name,
(tp->tg3_flags & TG3_FLAG_HOST_TXDS) != 0,
(tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0,
(tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0,
(tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0,
(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0,
(tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0,
(tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0,
(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
return 0; return 0;
err_out_iounmap: err_out_iounmap:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment