aboutsummaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/pcnet32.c5
-rw-r--r--drivers/net/s2io.c10
-rw-r--r--drivers/net/sk98lin/skge.c4
-rw-r--r--drivers/net/skge.c10
-rw-r--r--drivers/net/tg3.c257
-rw-r--r--drivers/net/tg3.h7
6 files changed, 182 insertions, 111 deletions
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index be319229f54..8f6cf8c896a 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -1251,12 +1251,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
if (memcmp(promaddr, dev->dev_addr, 6)
|| !is_valid_ether_addr(dev->dev_addr)) {
-#ifndef __powerpc__
if (is_valid_ether_addr(promaddr)) {
-#else
- if (!is_valid_ether_addr(dev->dev_addr)
- && is_valid_ether_addr(promaddr)) {
-#endif
if (pcnet32_debug & NETIF_MSG_PROBE) {
printk(" warning: CSR address invalid,\n");
printk(KERN_INFO " using instead PROM address of");
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index e57df8dfe6b..669dd52c412 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -3078,7 +3078,7 @@ int s2io_set_swapper(nic_t * sp)
static int wait_for_msix_trans(nic_t *nic, int i)
{
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ XENA_dev_config_t __iomem *bar0 = nic->bar0;
u64 val64;
int ret = 0, cnt = 0;
@@ -3099,7 +3099,7 @@ static int wait_for_msix_trans(nic_t *nic, int i)
void restore_xmsi_data(nic_t *nic)
{
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ XENA_dev_config_t __iomem *bar0 = nic->bar0;
u64 val64;
int i;
@@ -3117,7 +3117,7 @@ void restore_xmsi_data(nic_t *nic)
static void store_xmsi_data(nic_t *nic)
{
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ XENA_dev_config_t __iomem *bar0 = nic->bar0;
u64 val64, addr, data;
int i;
@@ -3140,7 +3140,7 @@ static void store_xmsi_data(nic_t *nic)
int s2io_enable_msi(nic_t *nic)
{
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ XENA_dev_config_t __iomem *bar0 = nic->bar0;
u16 msi_ctrl, msg_val;
struct config_param *config = &nic->config;
struct net_device *dev = nic->dev;
@@ -3190,7 +3190,7 @@ int s2io_enable_msi(nic_t *nic)
int s2io_enable_msi_x(nic_t *nic)
{
- XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+ XENA_dev_config_t __iomem *bar0 = nic->bar0;
u64 tx_mat, rx_mat;
u16 msi_control; /* Temp variable */
int ret, i, j, msix_indx = 1;
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index 00c5d7f04c6..ae734393475 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -818,7 +818,7 @@ uintptr_t VNextDescr; /* the virtual bus address of the next descriptor */
/* set the pointers right */
pDescr->VNextRxd = VNextDescr & 0xffffffffULL;
pDescr->pNextRxd = pNextDescr;
- pDescr->TcpSumStarts = 0;
+ if (!IsTx) pDescr->TcpSumStarts = ETH_HLEN << 16 | ETH_HLEN;
/* advance one step */
pPrevDescr = pDescr;
@@ -2169,7 +2169,7 @@ rx_start:
} /* frame > SK_COPY_TRESHOLD */
#ifdef USE_SK_RX_CHECKSUM
- pMsg->csum = pRxd->TcpSums;
+ pMsg->csum = pRxd->TcpSums & 0xffff;
pMsg->ip_summed = CHECKSUM_HW;
#else
pMsg->ip_summed = CHECKSUM_NONE;
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 716467879b9..00d683063c0 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -2280,11 +2280,13 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
}
if (unlikely(skge->tx_avail < skb_shinfo(skb)->nr_frags +1)) {
- netif_stop_queue(dev);
- spin_unlock_irqrestore(&skge->tx_lock, flags);
+ if (!netif_queue_stopped(dev)) {
+ netif_stop_queue(dev);
- printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
- dev->name);
+ printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
+ dev->name);
+ }
+ spin_unlock_irqrestore(&skge->tx_lock, flags);
return NETDEV_TX_BUSY;
}
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 1828a6bf845..cefb0c08a68 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -68,8 +68,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.43"
-#define DRV_MODULE_RELDATE "Oct 24, 2005"
+#define DRV_MODULE_VERSION "3.46"
+#define DRV_MODULE_RELDATE "Dec 19, 2005"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -341,6 +341,16 @@ static struct {
{ "interrupt test (offline)" },
};
+static void tg3_write32(struct tg3 *tp, u32 off, u32 val)
+{
+ writel(val, tp->regs + off);
+}
+
+static u32 tg3_read32(struct tg3 *tp, u32 off)
+{
+ return (readl(tp->regs + off));
+}
+
static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
{
unsigned long flags;
@@ -411,13 +421,29 @@ static u32 tg3_read_indirect_mbox(struct tg3 *tp, u32 off)
return val;
}
-static void _tw32_flush(struct tg3 *tp, u32 off, u32 val)
+/* usec_wait specifies the wait time in usec when writing to certain registers
+ * where it is unsafe to read back the register without some delay.
+ * GRC_LOCAL_CTRL is one example if the GPIOs are toggled to switch power.
+ * TG3PCI_CLOCK_CTRL is another example if the clock frequencies are changed.
+ */
+static void _tw32_flush(struct tg3 *tp, u32 off, u32 val, u32 usec_wait)
{
- tp->write32(tp, off, val);
- if (!(tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) &&
- !(tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) &&
- !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))
- tp->read32(tp, off); /* flush */
+ if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) ||
+ (tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))
+ /* Non-posted methods */
+ tp->write32(tp, off, val);
+ else {
+ /* Posted method */
+ tg3_write32(tp, off, val);
+ if (usec_wait)
+ udelay(usec_wait);
+ tp->read32(tp, off);
+ }
+ /* Wait again after the read for the posted method to guarantee that
+ * the wait time is met.
+ */
+ if (usec_wait)
+ udelay(usec_wait);
}
static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val)
@@ -438,16 +464,6 @@ static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val)
readl(mbox);
}
-static void tg3_write32(struct tg3 *tp, u32 off, u32 val)
-{
- writel(val, tp->regs + off);
-}
-
-static u32 tg3_read32(struct tg3 *tp, u32 off)
-{
- return (readl(tp->regs + off));
-}
-
#define tw32_mailbox(reg, val) tp->write32_mbox(tp, reg, val)
#define tw32_mailbox_f(reg, val) tw32_mailbox_flush(tp, (reg), (val))
#define tw32_rx_mbox(reg, val) tp->write32_rx_mbox(tp, reg, val)
@@ -455,7 +471,8 @@ static u32 tg3_read32(struct tg3 *tp, u32 off)
#define tr32_mailbox(reg) tp->read32_mbox(tp, reg)
#define tw32(reg,val) tp->write32(tp, reg, val)
-#define tw32_f(reg,val) _tw32_flush(tp,(reg),(val))
+#define tw32_f(reg,val) _tw32_flush(tp,(reg),(val), 0)
+#define tw32_wait_f(reg,val,us) _tw32_flush(tp,(reg),(val), (us))
#define tr32(reg) tp->read32(tp, reg)
static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
@@ -595,21 +612,19 @@ static void tg3_switch_clocks(struct tg3 *tp)
if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
if (orig_clock_ctrl & CLOCK_CTRL_625_CORE) {
- tw32_f(TG3PCI_CLOCK_CTRL,
- clock_ctrl | CLOCK_CTRL_625_CORE);
- udelay(40);
+ tw32_wait_f(TG3PCI_CLOCK_CTRL,
+ clock_ctrl | CLOCK_CTRL_625_CORE, 40);
}
} else if ((orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE) != 0) {
- tw32_f(TG3PCI_CLOCK_CTRL,
- clock_ctrl |
- (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK));
- udelay(40);
- tw32_f(TG3PCI_CLOCK_CTRL,
- clock_ctrl | (CLOCK_CTRL_ALTCLK));
- udelay(40);
+ tw32_wait_f(TG3PCI_CLOCK_CTRL,
+ clock_ctrl |
+ (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK),
+ 40);
+ tw32_wait_f(TG3PCI_CLOCK_CTRL,
+ clock_ctrl | (CLOCK_CTRL_ALTCLK),
+ 40);
}
- tw32_f(TG3PCI_CLOCK_CTRL, clock_ctrl);
- udelay(40);
+ tw32_wait_f(TG3PCI_CLOCK_CTRL, clock_ctrl, 40);
}
#define PHY_BUSY_LOOPS 5000
@@ -1017,37 +1032,50 @@ static void tg3_frob_aux_power(struct tg3 *tp)
if ((tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) != 0)
return;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
- tp_peer = pci_get_drvdata(tp->pdev_peer);
- if (!tp_peer)
+ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) {
+ struct net_device *dev_peer;
+
+ dev_peer = pci_get_drvdata(tp->pdev_peer);
+ if (!dev_peer)
BUG();
+ tp_peer = netdev_priv(dev_peer);
}
-
if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 ||
- (tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0) {
+ (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0 ||
+ (tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 ||
+ (tp_peer->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
- tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
- (GRC_LCLCTRL_GPIO_OE0 |
- GRC_LCLCTRL_GPIO_OE1 |
- GRC_LCLCTRL_GPIO_OE2 |
- GRC_LCLCTRL_GPIO_OUTPUT0 |
- GRC_LCLCTRL_GPIO_OUTPUT1));
- udelay(100);
+ tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+ (GRC_LCLCTRL_GPIO_OE0 |
+ GRC_LCLCTRL_GPIO_OE1 |
+ GRC_LCLCTRL_GPIO_OE2 |
+ GRC_LCLCTRL_GPIO_OUTPUT0 |
+ GRC_LCLCTRL_GPIO_OUTPUT1),
+ 100);
} else {
u32 no_gpio2;
- u32 grc_local_ctrl;
+ u32 grc_local_ctrl = 0;
if (tp_peer != tp &&
(tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0)
return;
+ /* Workaround to prevent overdrawing Amps. */
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
+ ASIC_REV_5714) {
+ grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
+ tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+ grc_local_ctrl, 100);
+ }
+
/* On 5753 and variants, GPIO2 cannot be used. */
no_gpio2 = tp->nic_sram_data_cfg &
NIC_SRAM_DATA_CFG_NO_GPIO2;
- grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 |
+ grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE0 |
GRC_LCLCTRL_GPIO_OE1 |
GRC_LCLCTRL_GPIO_OE2 |
GRC_LCLCTRL_GPIO_OUTPUT1 |
@@ -1056,21 +1084,18 @@ static void tg3_frob_aux_power(struct tg3 *tp)
grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 |
GRC_LCLCTRL_GPIO_OUTPUT2);
}
- tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
- grc_local_ctrl);
- udelay(100);
+ tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+ grc_local_ctrl, 100);
grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0;
- tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
- grc_local_ctrl);
- udelay(100);
+ tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+ grc_local_ctrl, 100);
if (!no_gpio2) {
grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2;
- tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
- grc_local_ctrl);
- udelay(100);
+ tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+ grc_local_ctrl, 100);
}
}
} else {
@@ -1080,19 +1105,16 @@ static void tg3_frob_aux_power(struct tg3 *tp)
(tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0)
return;
- tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
- (GRC_LCLCTRL_GPIO_OE1 |
- GRC_LCLCTRL_GPIO_OUTPUT1));
- udelay(100);
+ tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+ (GRC_LCLCTRL_GPIO_OE1 |
+ GRC_LCLCTRL_GPIO_OUTPUT1), 100);
- tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
- (GRC_LCLCTRL_GPIO_OE1));
- udelay(100);
+ tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+ GRC_LCLCTRL_GPIO_OE1, 100);
- tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
- (GRC_LCLCTRL_GPIO_OE1 |
- GRC_LCLCTRL_GPIO_OUTPUT1));
- udelay(100);
+ tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+ (GRC_LCLCTRL_GPIO_OE1 |
+ GRC_LCLCTRL_GPIO_OUTPUT1), 100);
}
}
}
@@ -1105,6 +1127,8 @@ static int tg3_setup_phy(struct tg3 *, int);
static void tg3_write_sig_post_reset(struct tg3 *, int);
static int tg3_halt_cpu(struct tg3 *, u32);
+static int tg3_nvram_lock(struct tg3 *);
+static void tg3_nvram_unlock(struct tg3 *);
static int tg3_set_power_state(struct tg3 *tp, int state)
{
@@ -1133,10 +1157,8 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
udelay(100); /* Delay after power state change */
/* Switch out of Vaux if it is not a LOM */
- if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT)) {
- tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
- udelay(100);
- }
+ if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT))
+ tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100);
return 0;
@@ -1179,6 +1201,21 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
tg3_setup_phy(tp, 0);
}
+ if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+ int i;
+ u32 val;
+
+ for (i = 0; i < 200; i++) {
+ tg3_read_mem(tp, NIC_SRAM_FW_ASF_STATUS_MBOX, &val);
+ if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
+ break;
+ msleep(1);
+ }
+ }
+ tg3_write_mem(tp, NIC_SRAM_WOL_MBOX, WOL_SIGNATURE |
+ WOL_DRV_STATE_SHUTDOWN |
+ WOL_DRV_WOL | WOL_SET_MAGIC_PKT);
+
pci_read_config_word(tp->pdev, pm + PCI_PM_PMC, &power_caps);
if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) {
@@ -1220,10 +1257,8 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
base_val |= (CLOCK_CTRL_RXCLK_DISABLE |
CLOCK_CTRL_TXCLK_DISABLE);
- tw32_f(TG3PCI_CLOCK_CTRL, base_val |
- CLOCK_CTRL_ALTCLK |
- CLOCK_CTRL_PWRDOWN_PLL133);
- udelay(40);
+ tw32_wait_f(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK |
+ CLOCK_CTRL_PWRDOWN_PLL133, 40);
} else if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
/* do nothing */
} else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
@@ -1244,11 +1279,11 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE;
}
- tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits1);
- udelay(40);
+ tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits1,
+ 40);
- tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2);
- udelay(40);
+ tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2,
+ 40);
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
u32 newbits3;
@@ -1262,9 +1297,20 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
newbits3 = CLOCK_CTRL_44MHZ_CORE;
}
- tw32_f(TG3PCI_CLOCK_CTRL,
- tp->pci_clock_ctrl | newbits3);
- udelay(40);
+ tw32_wait_f(TG3PCI_CLOCK_CTRL,
+ tp->pci_clock_ctrl | newbits3, 40);
+ }
+ }
+
+ if (!(tp->tg3_flags & TG3_FLAG_WOL_ENABLE) &&
+ !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+ /* Turn off the PHY */
+ if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
+ tg3_writephy(tp, MII_TG3_EXT_CTRL,
+ MII_TG3_EXT_CTRL_FORCE_LED_OFF);
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700)
+ tg3_writephy(tp, MII_BMCR, BMCR_PDOWN);
}
}
@@ -1277,8 +1323,12 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1);
tw32(0x7d00, val);
- if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+ if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+ tg3_nvram_lock(tp);
tg3_halt_cpu(tp, RX_CPU_BASE);
+ tw32_f(NVRAM_SWARB, SWARB_REQ_CLR0);
+ tg3_nvram_unlock(tp);
+ }
}
/* Finally, set the new power state. */
@@ -1812,7 +1862,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
}
}
relink:
- if (current_link_up == 0) {
+ if (current_link_up == 0 || tp->link_config.phy_is_low_power) {
u32 tmp;
tg3_phy_copper_begin(tp);
@@ -3565,12 +3615,15 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (!spin_trylock(&tp->tx_lock))
return NETDEV_TX_LOCKED;
- /* This is a hard error, log it. */
if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
- netif_stop_queue(dev);
+ if (!netif_queue_stopped(dev)) {
+ netif_stop_queue(dev);
+
+ /* This is a hard error, log it. */
+ printk(KERN_ERR PFX "%s: BUG! Tx Ring full when "
+ "queue awake!\n", dev->name);
+ }
spin_unlock(&tp->tx_lock);
- printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
- dev->name);
return NETDEV_TX_BUSY;
}
@@ -7922,13 +7975,12 @@ static int tg3_test_memory(struct tg3 *tp)
u32 offset;
u32 len;
} mem_tbl_570x[] = {
- { 0x00000000, 0x01000},
+ { 0x00000000, 0x00b50},
{ 0x00002000, 0x1c000},
{ 0xffffffff, 0x00000}
}, mem_tbl_5705[] = {
{ 0x00000100, 0x0000c},
{ 0x00000200, 0x00008},
- { 0x00000b50, 0x00400},
{ 0x00004000, 0x00800},
{ 0x00006000, 0x01000},
{ 0x00008000, 0x02000},
@@ -8530,6 +8582,7 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
tp->tg3_flags |= TG3_FLAG_NVRAM;
+ tg3_nvram_lock(tp);
tg3_enable_nvram_access(tp);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
@@ -8540,6 +8593,7 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
tg3_get_nvram_size(tp);
tg3_disable_nvram_access(tp);
+ tg3_nvram_unlock(tp);
} else {
tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED);
@@ -8637,10 +8691,10 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
if (ret == 0)
*val = swab32(tr32(NVRAM_RDDATA));
- tg3_nvram_unlock(tp);
-
tg3_disable_nvram_access(tp);
+ tg3_nvram_unlock(tp);
+
return ret;
}
@@ -8725,6 +8779,10 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
offset = offset + (pagesize - page_off);
+ /* Nvram lock released by tg3_nvram_read() above,
+ * so need to get it again.
+ */
+ tg3_nvram_lock(tp);
tg3_enable_nvram_access(tp);
/*
@@ -10423,7 +10481,7 @@ static char * __devinit tg3_bus_string(struct tg3 *tp, char *str)
return str;
}
-static struct pci_dev * __devinit tg3_find_5704_peer(struct tg3 *tp)
+static struct pci_dev * __devinit tg3_find_peer(struct tg3 *tp)
{
struct pci_dev *peer;
unsigned int func, devnr = tp->pdev->devfn & ~7;
@@ -10434,8 +10492,13 @@ static struct pci_dev * __devinit tg3_find_5704_peer(struct tg3 *tp)
break;
pci_dev_put(peer);
}
- if (!peer || peer == tp->pdev)
- BUG();
+ /* 5704 can be configured in single-port mode, set peer to
+ * tp->pdev in that case.
+ */
+ if (!peer) {
+ peer = tp->pdev;
+ return peer;
+ }
/*
* We don't need to keep the refcount elevated; there's no way
@@ -10671,8 +10734,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tp->rx_pending = 63;
}
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
- tp->pdev_peer = tg3_find_5704_peer(tp);
+ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714))
+ tp->pdev_peer = tg3_find_peer(tp);
err = tg3_get_device_address(tp);
if (err) {
@@ -10817,12 +10881,14 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
tg3_full_lock(tp, 0);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+ tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
tg3_full_unlock(tp);
err = tg3_set_power_state(tp, pci_choose_state(pdev, state));
if (err) {
tg3_full_lock(tp, 0);
+ tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
tg3_init_hw(tp);
tp->timer.expires = jiffies + tp->timer_offset;
@@ -10856,6 +10922,7 @@ static int tg3_resume(struct pci_dev *pdev)
tg3_full_lock(tp, 0);
+ tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
tg3_init_hw(tp);
tp->timer.expires = jiffies + tp->timer_offset;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index fb7e2a5f4a0..94dbcf3537e 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1529,6 +1529,12 @@
#define NIC_SRAM_MAC_ADDR_HIGH_MBOX 0x00000c14
#define NIC_SRAM_MAC_ADDR_LOW_MBOX 0x00000c18
+#define NIC_SRAM_WOL_MBOX 0x00000d30
+#define WOL_SIGNATURE 0x474c0000
+#define WOL_DRV_STATE_SHUTDOWN 0x00000001
+#define WOL_DRV_WOL 0x00000002
+#define WOL_SET_MAGIC_PKT 0x00000004
+
#define NIC_SRAM_DATA_CFG_2 0x00000d38
#define SHASTA_EXT_LED_MODE_MASK 0x00018000
@@ -1565,6 +1571,7 @@
#define MII_TG3_EXT_CTRL 0x10 /* Extended control register */
#define MII_TG3_EXT_CTRL_FIFO_ELASTIC 0x0001
#define MII_TG3_EXT_CTRL_LNK3_LED_MODE 0x0002
+#define MII_TG3_EXT_CTRL_FORCE_LED_OFF 0x0008
#define MII_TG3_EXT_CTRL_TBI 0x8000
#define MII_TG3_EXT_STAT 0x11 /* Extended status register */