* Tg3 updated driver
@ 2006-11-16 6:20 Patrick Stach
2006-11-16 15:45 ` Andrew D. Ball
0 siblings, 1 reply; 2+ messages in thread
From: Patrick Stach @ 2006-11-16 6:20 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1.1.1: Type: text/plain, Size: 1037 bytes --]
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I (well work) recently purchased a KFN5-D motherboard for a Xen VM
host. The TG3 5787 chipset interfaces that are found onboard weren't
supported in the 2.6.16.29 kernel that Xen stable is based on.
However stock 2.6.18.1 and RHEL 2.6.9-42.0.3 supports it, as well as
a dozen other TG3 chips found on many of the attractive new
motherboards on the market.
I've forward ported the RHEL driver, which is a backport of the
2.6.18.1 driver (judging from linux/pci_ids.h), and it runs stable
and has for over a week now. Attached is a patch for the
linux-2.6.16.29-xen patched tree to add support for the 5754, 5754M,
5755, 5755M, 5787 (tested), 5787M, 5714S, and 5715S.
Hope it is of some use to someone.
- -Patrick Stach
- --
Director of Research and Development
Stach & Liu, LLC
Email: pstach@stachliu.com
-----BEGIN PGP SIGNATURE-----
Version: PGP 8.0.2
iQA/AwUBRVwDQgy3VB5NWKwNEQJoPgCg7mLZpj4yfOqKRYy2XdMtamk1Fi8AoI3O
kBvZ5PzTQSTJ0tnDbPqi0weY
=EwQq
-----END PGP SIGNATURE-----
[-- Attachment #1.1.2: tg3-support.patch --]
[-- Type: application/octet-stream, Size: 49411 bytes --]
diff -ruN linux-2.6.16.29-xen/drivers/net/tg3.c linux-2.6.16.29-xen.hacked/drivers/net/tg3.c
--- linux-2.6.16.29-xen/drivers/net/tg3.c 2006-11-14 01:02:49.000000000 -0800
+++ linux-2.6.16.29-xen.hacked/drivers/net/tg3.c 2006-11-14 01:05:53.000000000 -0800
@@ -1,6 +1,9 @@
/*
* tg3.c: Broadcom Tigon3 ethernet driver.
*
+ * Forward port of back port of RHEL 2.6.9-42.0.3 to support newer TG3's
+ * by Patrick Stach (pstach@stachliu.com)
+ *
* Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com)
* Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com)
* Copyright (C) 2004 Sun Microsystems Inc.
@@ -65,12 +68,13 @@
#define TG3_TSO_SUPPORT 0
#endif
+#include "tg3_compat.h"
#include "tg3.h"
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.49"
-#define DRV_MODULE_RELDATE "Feb 2, 2006"
+#define DRV_MODULE_VERSION "3.52-rh"
+#define DRV_MODULE_RELDATE "Mar 06, 2006"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -221,10 +225,26 @@
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753F,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5754M,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5755M,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714S,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715S,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S,
@@ -534,6 +554,9 @@
(tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
(tp->last_tag << 24));
+ if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
+ tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+ (tp->last_tag << 24));
tg3_cond_int(tp);
}
@@ -1038,9 +1061,11 @@
struct net_device *dev_peer;
dev_peer = pci_get_drvdata(tp->pdev_peer);
+ /* remove_one() may have been run on the peer. */
if (!dev_peer)
- BUG();
- tp_peer = netdev_priv(dev_peer);
+ tp_peer = tp;
+ else
+ tp_peer = netdev_priv(dev_peer);
}
if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 ||
@@ -1131,7 +1156,7 @@
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)
+static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
{
u32 misc_host_ctrl;
u16 power_control, power_caps;
@@ -1150,7 +1175,7 @@
power_control |= PCI_PM_CTRL_PME_STATUS;
power_control &= ~(PCI_PM_CTRL_STATE_MASK);
switch (state) {
- case 0:
+ case PCI_D0:
power_control |= 0;
pci_write_config_word(tp->pdev,
pm + PCI_PM_CTRL,
@@ -1163,15 +1188,15 @@
return 0;
- case 1:
+ case PCI_D1:
power_control |= 1;
break;
- case 2:
+ case PCI_D2:
power_control |= 2;
break;
- case 3:
+ case PCI_D3hot:
power_control |= 3;
break;
@@ -2680,6 +2705,12 @@
err |= tg3_readphy(tp, MII_BMSR, &bmsr);
err |= tg3_readphy(tp, MII_BMSR, &bmsr);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
+ if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP)
+ bmsr |= BMSR_LSTATUS;
+ else
+ bmsr &= ~BMSR_LSTATUS;
+ }
err |= tg3_readphy(tp, MII_BMCR, &bmcr);
@@ -2748,6 +2779,13 @@
bmcr = new_bmcr;
err |= tg3_readphy(tp, MII_BMSR, &bmsr);
err |= tg3_readphy(tp, MII_BMSR, &bmsr);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
+ ASIC_REV_5714) {
+ if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP)
+ bmsr |= BMSR_LSTATUS;
+ else
+ bmsr &= ~BMSR_LSTATUS;
+ }
tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
}
}
@@ -3231,6 +3269,9 @@
tp->rx_rcb_ptr = sw_idx;
tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, sw_idx);
+ /* Some platforms need to sync memory here */
+ wmb();
+
/* Refill RX ring(s). */
if (work_mask & RXD_OPAQUE_RING_STD) {
sw_idx = tp->rx_std_ptr % TG3_RX_RING_SIZE;
@@ -3338,6 +3379,23 @@
spin_unlock_bh(&tp->lock);
}
+/* One-shot MSI handler - Chip automatically disables interrupt
+ * after sending MSI so driver doesn't have to do it.
+ */
+static irqreturn_t tg3_msi_1shot(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct net_device *dev = dev_id;
+ struct tg3 *tp = netdev_priv(dev);
+
+ prefetch(tp->hw_status);
+ prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+
+ if (likely(!tg3_irq_sync(tp)))
+ netif_rx_schedule(dev); /* schedule NAPI poll */
+
+ return IRQ_HANDLED;
+}
+
/* MSI ISR - No need to check for interrupt sharing and no need to
* flush status block and interrupt mailbox. PCI ordering rules
* guarantee that MSI will arrive after the status block.
@@ -3628,11 +3686,139 @@
txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT;
}
+/* hard_start_xmit for devices that don't have any bugs and
+ * support TG3_FLG2_HW_TSO_2 only.
+ */
static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct tg3 *tp = netdev_priv(dev);
dma_addr_t mapping;
u32 len, entry, base_flags, mss;
+
+ len = skb_headlen(skb);
+
+ /* No BH disabling for tx_lock here. We are running in BH disabled
+ * context and TX reclaim runs via tp->poll inside of a software
+ * interrupt. Furthermore, IRQ processing runs lockless so we have
+ * no IRQ context deadlocks to worry about either. Rejoice!
+ */
+ if (!spin_trylock(&tp->tx_lock))
+ return NETDEV_TX_LOCKED;
+
+ if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
+ 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);
+ return NETDEV_TX_BUSY;
+ }
+
+ entry = tp->tx_prod;
+ base_flags = 0;
+#if TG3_TSO_SUPPORT != 0
+ mss = 0;
+ if (skb->len > (tp->dev->mtu + ETH_HLEN) &&
+ (mss = skb_shinfo(skb)->gso_size) != 0) {
+ int tcp_opt_len, ip_tcp_len;
+
+ if (skb_header_cloned(skb) &&
+ pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
+ dev_kfree_skb(skb);
+ goto out_unlock;
+ }
+
+ tcp_opt_len = ((skb->h.th->doff - 5) * 4);
+ ip_tcp_len = (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr);
+
+ base_flags |= (TXD_FLAG_CPU_PRE_DMA |
+ TXD_FLAG_CPU_POST_DMA);
+
+ skb->nh.iph->check = 0;
+ skb->nh.iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len);
+
+ skb->h.th->check = 0;
+
+ mss |= (ip_tcp_len + tcp_opt_len) << 9;
+ }
+ else if (skb->ip_summed == CHECKSUM_HW)
+ base_flags |= TXD_FLAG_TCPUDP_CSUM;
+#else
+ mss = 0;
+ if (skb->ip_summed == CHECKSUM_HW)
+ base_flags |= TXD_FLAG_TCPUDP_CSUM;
+#endif
+#if TG3_VLAN_TAG_USED
+ if (tp->vlgrp != NULL && vlan_tx_tag_present(skb))
+ base_flags |= (TXD_FLAG_VLAN |
+ (vlan_tx_tag_get(skb) << 16));
+#endif
+
+ /* Queue skb data, a.k.a. the main skb fragment. */
+ mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+
+ tp->tx_buffers[entry].skb = skb;
+ pci_unmap_addr_set(&tp->tx_buffers[entry], mapping, mapping);
+
+ tg3_set_txd(tp, entry, mapping, len, base_flags,
+ (skb_shinfo(skb)->nr_frags == 0) | (mss << 1));
+
+ entry = NEXT_TX(entry);
+
+ /* Now loop through additional data fragments, and queue them. */
+ if (skb_shinfo(skb)->nr_frags > 0) {
+ unsigned int i, last;
+
+ last = skb_shinfo(skb)->nr_frags - 1;
+ for (i = 0; i <= last; i++) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+ len = frag->size;
+ mapping = pci_map_page(tp->pdev,
+ frag->page,
+ frag->page_offset,
+ len, PCI_DMA_TODEVICE);
+
+ tp->tx_buffers[entry].skb = NULL;
+ pci_unmap_addr_set(&tp->tx_buffers[entry], mapping, mapping);
+
+ tg3_set_txd(tp, entry, mapping, len,
+ base_flags, (i == last) | (mss << 1));
+
+ entry = NEXT_TX(entry);
+ }
+ }
+
+ /* Packets are ready, update Tx producer idx local and on card. */
+ tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry);
+
+ tp->tx_prod = entry;
+ if (TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1)) {
+ netif_stop_queue(dev);
+ if (TX_BUFFS_AVAIL(tp) > TG3_TX_WAKEUP_THRESH)
+ netif_wake_queue(tp->dev);
+ }
+
+out_unlock:
+ mmiowb();
+ spin_unlock(&tp->tx_lock);
+
+ dev->trans_start = jiffies;
+
+ return NETDEV_TX_OK;
+}
+
+/* hard_start_xmit for devices that have the 4G bug and/or 40-bit bug and
+ * support TG3_FLG2_HW_TSO_1 or firmware TSO only.
+ */
+static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
+{
+ struct tg3 *tp = netdev_priv(dev);
+ dma_addr_t mapping;
+ u32 len, entry, base_flags, mss;
int would_hit_hwbug;
len = skb_headlen(skb);
@@ -3787,6 +3973,9 @@
entry = start;
}
+ /* Some platforms need to sync memory here */
+ wmb();
+
/* Packets are ready, update Tx producer idx local and on card. */
tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry);
@@ -4369,6 +4558,11 @@
tp->nvram_lock_cnt = 0;
}
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+ tw32(GRC_FASTBOOT_PC, 0);
+
/*
* We must avoid the readl() that normally takes place.
* It locks machines, causes machine checks, and other
@@ -5518,6 +5712,9 @@
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+ if (!netif_running(dev))
+ return 0;
+
spin_lock_bh(&tp->lock);
__tg3_set_mac_addr(tp);
spin_unlock_bh(&tp->lock);
@@ -5585,6 +5782,9 @@
tg3_abort_hw(tp, 1);
}
+ if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
+ tg3_phy_reset(tp);
+
err = tg3_chip_reset(tp);
if (err)
return err;
@@ -5955,6 +6155,9 @@
gpio_mask |= GRC_LCLCTRL_GPIO_OE3 |
GRC_LCLCTRL_GPIO_OUTPUT3;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
+ gpio_mask |= GRC_LCLCTRL_GPIO_UART_SEL;
+
tp->grc_local_ctrl |= tr32(GRC_LOCAL_CTRL) & gpio_mask;
/* GPIO1 must be driven high for eeprom write protect */
@@ -5993,6 +6196,11 @@
}
}
+ /* Enable host coalescing bug fix */
+ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) ||
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787))
+ val |= (1 << 29);
+
tw32_f(WDMAC_MODE, val);
udelay(40);
@@ -6048,6 +6256,9 @@
udelay(100);
tp->rx_mode = RX_MODE_ENABLE;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
+ tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE;
+
tw32_f(MAC_RX_MODE, tp->rx_mode);
udelay(10);
@@ -6097,6 +6308,17 @@
tp->tg3_flags2 |= TG3_FLG2_HW_AUTONEG;
}
+ if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) &&
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) {
+ u32 tmp;
+
+ tmp = tr32(SERDES_RX_CTRL);
+ tw32(SERDES_RX_CTRL, tmp | SERDES_RX_SIG_DETECT);
+ tp->grc_local_ctrl &= ~GRC_LCLCTRL_USE_EXT_SIG_DETECT;
+ tp->grc_local_ctrl |= GRC_LCLCTRL_USE_SIG_DETECT;
+ tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
+ }
+
err = tg3_setup_phy(tp, 1);
if (err)
return err;
@@ -6175,7 +6397,7 @@
int err;
/* Force the chip into D0. */
- err = tg3_set_power_state(tp, 0);
+ err = tg3_set_power_state(tp, PCI_D0);
if (err)
goto out;
@@ -6331,6 +6553,26 @@
add_timer(&tp->timer);
}
+int tg3_request_irq(struct tg3 *tp)
+{
+ irqreturn_t (*fn)(int, void *, struct pt_regs *);
+ unsigned long flags;
+ struct net_device *dev = tp->dev;
+
+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+ fn = tg3_msi;
+ if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
+ fn = tg3_msi_1shot;
+ flags = SA_SAMPLE_RANDOM;
+ } else {
+ fn = tg3_interrupt;
+ if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
+ fn = tg3_interrupt_tagged;
+ flags = SA_SHIRQ | SA_SAMPLE_RANDOM;
+ }
+ return (request_irq(tp->pdev->irq, fn, flags, dev->name, dev));
+}
+
static int tg3_test_interrupt(struct tg3 *tp)
{
struct net_device *dev = tp->dev;
@@ -6367,16 +6609,7 @@
free_irq(tp->pdev->irq, dev);
- if (tp->tg3_flags2 & TG3_FLG2_USING_MSI)
- err = request_irq(tp->pdev->irq, tg3_msi,
- SA_SAMPLE_RANDOM, dev->name, dev);
- else {
- irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt;
- if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
- fn = tg3_interrupt_tagged;
- err = request_irq(tp->pdev->irq, fn,
- SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
- }
+ err = tg3_request_irq(tp);
if (err)
return err;
@@ -6428,14 +6661,7 @@
tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
- {
- irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt;
- if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
- fn = tg3_interrupt_tagged;
-
- err = request_irq(tp->pdev->irq, fn,
- SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
- }
+ err = tg3_request_irq(tp);
if (err)
return err;
@@ -6462,6 +6688,10 @@
tg3_full_lock(tp, 0);
+ err = tg3_set_power_state(tp, PCI_D0);
+ if (err)
+ return err;
+
tg3_disable_ints(tp);
tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
@@ -6476,7 +6706,9 @@
if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
(GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_AX) &&
- (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_BX)) {
+ (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_BX) &&
+ !((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) &&
+ (tp->pdev_peer == tp->pdev))) {
/* All MSI supporting chips should support tagged
* status. Assert that this is the case.
*/
@@ -6491,17 +6723,7 @@
tp->tg3_flags2 |= TG3_FLG2_USING_MSI;
}
}
- if (tp->tg3_flags2 & TG3_FLG2_USING_MSI)
- err = request_irq(tp->pdev->irq, tg3_msi,
- SA_SAMPLE_RANDOM, dev->name, dev);
- else {
- irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt;
- if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
- fn = tg3_interrupt_tagged;
-
- err = request_irq(tp->pdev->irq, fn,
- SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
- }
+ err = tg3_request_irq(tp);
if (err) {
if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
@@ -6566,6 +6788,14 @@
return err;
}
+
+ if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+ if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI) {
+ u32 val = tr32(0x7c04);
+
+ tw32(0x7c04, val | (1 << 29));
+ }
+ }
}
tg3_full_lock(tp, 0);
@@ -6839,7 +7069,6 @@
tp->tg3_flags &=
~(TG3_FLAG_INIT_COMPLETE |
TG3_FLAG_GOT_SERDES_FLOWCTL);
- netif_carrier_off(tp->dev);
tg3_full_unlock(tp);
@@ -6856,6 +7085,10 @@
tg3_free_consistent(tp);
+ tg3_set_power_state(tp, PCI_D3hot);
+
+ netif_carrier_off(tp->dev);
+
return 0;
}
@@ -7150,6 +7383,9 @@
{
struct tg3 *tp = netdev_priv(dev);
+ if (!netif_running(dev))
+ return;
+
tg3_full_lock(tp, 0);
__tg3_set_rx_mode(dev);
tg3_full_unlock(tp);
@@ -7174,6 +7410,9 @@
memset(p, 0, TG3_REGDUMP_LEN);
+ if (tp->link_config.phy_is_low_power)
+ return;
+
tg3_full_lock(tp, 0);
#define __GET_REG32(reg) (*(p)++ = tr32(reg))
@@ -7240,6 +7479,7 @@
}
static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val);
+static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val);
static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
{
@@ -7248,6 +7488,9 @@
u8 *pd;
u32 i, offset, len, val, b_offset, b_count;
+ if (tp->link_config.phy_is_low_power)
+ return -EAGAIN;
+
offset = eeprom->offset;
len = eeprom->len;
eeprom->len = 0;
@@ -7309,6 +7552,9 @@
u32 offset, len, b_offset, odd_len, start, end;
u8 *buf;
+ if (tp->link_config.phy_is_low_power)
+ return -EAGAIN;
+
if (eeprom->magic != TG3_EEPROM_MAGIC)
return -EINVAL;
@@ -7368,23 +7614,21 @@
cmd->supported |= (SUPPORTED_1000baseT_Half |
SUPPORTED_1000baseT_Full);
- if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) {
+ if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
cmd->supported |= (SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_MII);
- cmd->port = PORT_TP;
- } else {
+ else
cmd->supported |= SUPPORTED_FIBRE;
- cmd->port = PORT_FIBRE;
- }
cmd->advertising = tp->link_config.advertising;
if (netif_running(dev)) {
cmd->speed = tp->link_config.active_speed;
cmd->duplex = tp->link_config.active_duplex;
}
+ cmd->port = 0;
cmd->phy_address = PHY_ADDR;
cmd->transceiver = 0;
cmd->autoneg = tp->link_config.autoneg;
@@ -7444,6 +7688,7 @@
strcpy(info->driver, DRV_MODULE_NAME);
strcpy(info->version, DRV_MODULE_VERSION);
+ strcpy(info->fw_version, tp->fw_ver);
strcpy(info->bus_info, pci_name(tp->pdev));
}
@@ -7538,11 +7783,20 @@
ering->rx_max_pending = TG3_RX_RING_SIZE - 1;
ering->rx_mini_max_pending = 0;
- ering->rx_jumbo_max_pending = TG3_RX_JUMBO_RING_SIZE - 1;
+ if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE)
+ ering->rx_jumbo_max_pending = TG3_RX_JUMBO_RING_SIZE - 1;
+ else
+ ering->rx_jumbo_max_pending = 0;
+
+ ering->tx_max_pending = TG3_TX_RING_SIZE - 1;
ering->rx_pending = tp->rx_pending;
ering->rx_mini_pending = 0;
- ering->rx_jumbo_pending = tp->rx_jumbo_pending;
+ if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE)
+ ering->rx_jumbo_pending = tp->rx_jumbo_pending;
+ else
+ ering->rx_jumbo_pending = 0;
+
ering->tx_pending = tp->tx_pending;
}
@@ -7663,10 +7917,11 @@
return 0;
}
- if (data)
- dev->features |= NETIF_F_IP_CSUM;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+ ethtool_op_set_tx_hw_csum(dev, data);
else
- dev->features &= ~NETIF_F_IP_CSUM;
+ ethtool_op_set_tx_csum(dev, data);
return 0;
}
@@ -7736,29 +7991,52 @@
}
#define NVRAM_TEST_SIZE 0x100
+#define NVRAM_SELFBOOT_FORMAT1_SIZE 0x14
static int tg3_test_nvram(struct tg3 *tp)
{
- u32 *buf, csum;
- int i, j, err = 0;
+ u32 *buf, csum, magic;
+ int i, j, err = 0, size;
+
+ if (tg3_nvram_read_swab(tp, 0, &magic) != 0)
+ return -EIO;
+
+ if (magic == TG3_EEPROM_MAGIC)
+ size = NVRAM_TEST_SIZE;
+ else if ((magic & 0xff000000) == 0xa5000000) {
+ if ((magic & 0xe00000) == 0x200000)
+ size = NVRAM_SELFBOOT_FORMAT1_SIZE;
+ else
+ return 0;
+ } else
+ return -EIO;
- buf = kmalloc(NVRAM_TEST_SIZE, GFP_KERNEL);
+ buf = kmalloc(size, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
- for (i = 0, j = 0; i < NVRAM_TEST_SIZE; i += 4, j++) {
+ err = -EIO;
+ for (i = 0, j = 0; i < size; i += 4, j++) {
u32 val;
if ((err = tg3_nvram_read(tp, i, &val)) != 0)
break;
buf[j] = cpu_to_le32(val);
}
- if (i < NVRAM_TEST_SIZE)
+ if (i < size)
goto out;
- err = -EIO;
- if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC)
- goto out;
+ /* Selfboot format */
+ if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC) {
+ u8 *buf8 = (u8 *) buf, csum8 = 0;
+
+ for (i = 0; i < size; i++)
+ csum8 += buf8[i];
+
+ if (csum8 == 0)
+ return 0;
+ return -EIO;
+ }
/* Bootstrap checksum at offset 0x10 */
csum = calc_crc((unsigned char *) buf, 0x10);
@@ -8052,14 +8330,25 @@
{ 0x00008000, 0x02000},
{ 0x00010000, 0x0e000},
{ 0xffffffff, 0x00000}
+ }, mem_tbl_5755[] = {
+ { 0x00000200, 0x00008},
+ { 0x00004000, 0x00800},
+ { 0x00006000, 0x00800},
+ { 0x00008000, 0x02000},
+ { 0x00010000, 0x0c000},
+ { 0xffffffff, 0x00000}
};
struct mem_entry *mem_tbl;
int err = 0;
int i;
- if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
- mem_tbl = mem_tbl_5705;
- else
+ if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+ mem_tbl = mem_tbl_5755;
+ else
+ mem_tbl = mem_tbl_5705;
+ } else
mem_tbl = mem_tbl_570x;
for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) {
@@ -8144,6 +8433,9 @@
tp->tx_prod++;
num_pkts++;
+ /* Some platforms need to sync memory here */
+ wmb();
+
tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW,
tp->tx_prod);
tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW);
@@ -8231,6 +8523,9 @@
{
struct tg3 *tp = netdev_priv(dev);
+ if (tp->link_config.phy_is_low_power)
+ tg3_set_power_state(tp, PCI_D0);
+
memset(data, 0, sizeof(u64) * TG3_NUM_TEST);
if (tg3_test_nvram(tp) != 0) {
@@ -8259,6 +8554,9 @@
if (!err)
tg3_nvram_unlock(tp);
+ if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
+ tg3_phy_reset(tp);
+
if (tg3_test_registers(tp) != 0) {
etest->flags |= ETH_TEST_FL_FAILED;
data[2] = 1;
@@ -8288,6 +8586,9 @@
tg3_full_unlock(tp);
}
+ if (tp->link_config.phy_is_low_power)
+ tg3_set_power_state(tp, PCI_D3hot);
+
}
static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -8307,6 +8608,9 @@
if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
break; /* We have no PHY */
+ if (tp->link_config.phy_is_low_power)
+ return -EAGAIN;
+
spin_lock_bh(&tp->lock);
err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval);
spin_unlock_bh(&tp->lock);
@@ -8323,6 +8627,9 @@
if (!capable(CAP_NET_ADMIN))
return -EPERM;
+ if (tp->link_config.phy_is_low_power)
+ return -EAGAIN;
+
spin_lock_bh(&tp->lock);
err = tg3_writephy(tp, data->reg_num & 0x1f, data->val_in);
spin_unlock_bh(&tp->lock);
@@ -8461,19 +8768,21 @@
.get_ethtool_stats = tg3_get_ethtool_stats,
.get_coalesce = tg3_get_coalesce,
.set_coalesce = tg3_set_coalesce,
+#if 0 /* Not in RHEL4... */
.get_perm_addr = ethtool_op_get_perm_addr,
+#endif
};
static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
{
- u32 cursize, val;
+ u32 cursize, val, magic;
tp->nvram_size = EEPROM_CHIP_SIZE;
- if (tg3_nvram_read(tp, 0, &val) != 0)
+ if (tg3_nvram_read_swab(tp, 0, &magic) != 0)
return;
- if (swab32(val) != TG3_EEPROM_MAGIC)
+ if ((magic != TG3_EEPROM_MAGIC) && ((magic & 0xff000000) != 0xa5000000))
return;
/*
@@ -8481,13 +8790,13 @@
* When we encounter our validation signature, we know the addressing
* has wrapped around, and thus have our chip size.
*/
- cursize = 0x800;
+ cursize = 0x10;
while (cursize < tp->nvram_size) {
- if (tg3_nvram_read(tp, cursize, &val) != 0)
+ if (tg3_nvram_read_swab(tp, cursize, &val) != 0)
return;
- if (swab32(val) == TG3_EEPROM_MAGIC)
+ if (val == magic)
break;
cursize <<= 1;
@@ -8500,6 +8809,15 @@
{
u32 val;
+ if (tg3_nvram_read_swab(tp, 0, &val) != 0)
+ return;
+
+ /* Selfboot format */
+ if (val != TG3_EEPROM_MAGIC) {
+ tg3_get_eeprom_size(tp);
+ return;
+ }
+
if (tg3_nvram_read(tp, 0xf0, &val) == 0) {
if (val != 0) {
tp->nvram_size = (val >> 16) * 1024;
@@ -8623,6 +8941,85 @@
}
}
+static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp)
+{
+ u32 nvcfg1;
+
+ nvcfg1 = tr32(NVRAM_CFG1);
+
+ /* NVRAM protection for TPM */
+ if (nvcfg1 & (1 << 27))
+ tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
+
+ switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+ case FLASH_5755VENDOR_ATMEL_EEPROM_64KHZ:
+ case FLASH_5755VENDOR_ATMEL_EEPROM_376KHZ:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+
+ nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+ tw32(NVRAM_CFG1, nvcfg1);
+ break;
+ case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+ case FLASH_5755VENDOR_ATMEL_FLASH_1:
+ case FLASH_5755VENDOR_ATMEL_FLASH_2:
+ case FLASH_5755VENDOR_ATMEL_FLASH_3:
+ case FLASH_5755VENDOR_ATMEL_FLASH_4:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tp->nvram_pagesize = 264;
+ break;
+ case FLASH_5752VENDOR_ST_M45PE10:
+ case FLASH_5752VENDOR_ST_M45PE20:
+ case FLASH_5752VENDOR_ST_M45PE40:
+ tp->nvram_jedecnum = JEDEC_ST;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tp->nvram_pagesize = 256;
+ break;
+ }
+}
+
+static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp)
+{
+ u32 nvcfg1;
+
+ nvcfg1 = tr32(NVRAM_CFG1);
+
+ switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+ case FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ:
+ case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ:
+ case FLASH_5787VENDOR_MICRO_EEPROM_64KHZ:
+ case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+
+ nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+ tw32(NVRAM_CFG1, nvcfg1);
+ break;
+ case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+ case FLASH_5755VENDOR_ATMEL_FLASH_1:
+ case FLASH_5755VENDOR_ATMEL_FLASH_2:
+ case FLASH_5755VENDOR_ATMEL_FLASH_3:
+ tp->nvram_jedecnum = JEDEC_ATMEL;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tp->nvram_pagesize = 264;
+ break;
+ case FLASH_5752VENDOR_ST_M45PE10:
+ case FLASH_5752VENDOR_ST_M45PE20:
+ case FLASH_5752VENDOR_ST_M45PE40:
+ tp->nvram_jedecnum = JEDEC_ST;
+ tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+ tp->tg3_flags2 |= TG3_FLG2_FLASH;
+ tp->nvram_pagesize = 256;
+ break;
+ }
+}
+
/* Chips other than 5700/5701 use the NVRAM for fetching info. */
static void __devinit tg3_nvram_init(struct tg3 *tp)
{
@@ -8658,6 +9055,10 @@
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
tg3_get_5752_nvram_info(tp);
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
+ tg3_get_5755_nvram_info(tp);
+ else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+ tg3_get_5787_nvram_info(tp);
else
tg3_get_nvram_info(tp);
@@ -8727,6 +9128,34 @@
return 0;
}
+static u32 tg3_nvram_phys_addr(struct tg3 *tp, u32 addr)
+{
+ if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
+ (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
+ (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
+ (tp->nvram_jedecnum == JEDEC_ATMEL))
+
+ addr = ((addr / tp->nvram_pagesize) <<
+ ATMEL_AT45DB0X1B_PAGE_POS) +
+ (addr % tp->nvram_pagesize);
+
+ return addr;
+}
+
+static u32 tg3_nvram_logical_addr(struct tg3 *tp, u32 addr)
+{
+ if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
+ (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
+ (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
+ (tp->nvram_jedecnum == JEDEC_ATMEL))
+
+ addr = ((addr >> ATMEL_AT45DB0X1B_PAGE_POS) *
+ tp->nvram_pagesize) +
+ (addr & ((1 << ATMEL_AT45DB0X1B_PAGE_POS) - 1));
+
+ return addr;
+}
+
static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
{
int ret;
@@ -8739,14 +9168,7 @@
if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
return tg3_nvram_read_using_eeprom(tp, offset, val);
- if ((tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
- (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
- (tp->nvram_jedecnum == JEDEC_ATMEL)) {
-
- offset = ((offset / tp->nvram_pagesize) <<
- ATMEL_AT45DB0X1B_PAGE_POS) +
- (offset % tp->nvram_pagesize);
- }
+ offset = tg3_nvram_phys_addr(tp, offset);
if (offset > NVRAM_ADDR_MSK)
return -EINVAL;
@@ -8771,6 +9193,16 @@
return ret;
}
+static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val)
+{
+ int err;
+ u32 tmp;
+
+ err = tg3_nvram_read(tp, offset, &tmp);
+ *val = swab32(tmp);
+ return err;
+}
+
static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
u32 offset, u32 len, u8 *buf)
{
@@ -8923,15 +9355,7 @@
page_off = offset % tp->nvram_pagesize;
- if ((tp->tg3_flags2 & TG3_FLG2_FLASH) &&
- (tp->nvram_jedecnum == JEDEC_ATMEL)) {
-
- phy_addr = ((offset / tp->nvram_pagesize) <<
- ATMEL_AT45DB0X1B_PAGE_POS) + page_off;
- }
- else {
- phy_addr = offset;
- }
+ phy_addr = tg3_nvram_phys_addr(tp, offset);
tw32(NVRAM_ADDR, phy_addr);
@@ -8946,6 +9370,8 @@
nvram_cmd |= NVRAM_CMD_LAST;
if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752) &&
+ (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755) &&
+ (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787) &&
(tp->nvram_jedecnum == JEDEC_ST) &&
(nvram_cmd & NVRAM_CMD_FIRST)) {
@@ -9345,6 +9771,7 @@
{
unsigned char vpd_data[256];
int i;
+ u32 magic;
if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) {
/* Sun decided not to put the necessary bits in the
@@ -9354,16 +9781,43 @@
return;
}
- for (i = 0; i < 256; i += 4) {
- u32 tmp;
+ if (tg3_nvram_read_swab(tp, 0x0, &magic))
+ return;
- if (tg3_nvram_read(tp, 0x100 + i, &tmp))
- goto out_not_found;
+ if (magic == TG3_EEPROM_MAGIC) {
+ for (i = 0; i < 256; i += 4) {
+ u32 tmp;
+
+ if (tg3_nvram_read(tp, 0x100 + i, &tmp))
+ goto out_not_found;
+
+ vpd_data[i + 0] = ((tmp >> 0) & 0xff);
+ vpd_data[i + 1] = ((tmp >> 8) & 0xff);
+ vpd_data[i + 2] = ((tmp >> 16) & 0xff);
+ vpd_data[i + 3] = ((tmp >> 24) & 0xff);
+ }
+ } else {
+ int vpd_cap;
- vpd_data[i + 0] = ((tmp >> 0) & 0xff);
- vpd_data[i + 1] = ((tmp >> 8) & 0xff);
- vpd_data[i + 2] = ((tmp >> 16) & 0xff);
- vpd_data[i + 3] = ((tmp >> 24) & 0xff);
+ vpd_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_VPD);
+ for (i = 0; i < 256; i += 4) {
+ u32 tmp, j = 0;
+ u16 tmp16;
+
+ pci_write_config_word(tp->pdev, vpd_cap + PCI_VPD_ADDR,
+ i);
+ while (j++ < 100) {
+ pci_read_config_word(tp->pdev, vpd_cap +
+ PCI_VPD_ADDR, &tmp16);
+ if (tmp16 & 0x8000)
+ break;
+ msleep(1);
+ }
+ pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA,
+ &tmp);
+ tmp = cpu_to_le32(tmp);
+ memcpy(&vpd_data[i], &tmp, 4);
+ }
}
/* Now parse and find the part number. */
@@ -9410,6 +9864,46 @@
strcpy(tp->board_part_number, "none");
}
+static void __devinit tg3_read_fw_ver(struct tg3 *tp)
+{
+ u32 val, offset, start;
+
+ if (tg3_nvram_read_swab(tp, 0, &val))
+ return;
+
+ if (val != TG3_EEPROM_MAGIC)
+ return;
+
+ if (tg3_nvram_read_swab(tp, 0xc, &offset) ||
+ tg3_nvram_read_swab(tp, 0x4, &start))
+ return;
+
+ offset = tg3_nvram_logical_addr(tp, offset);
+ if (tg3_nvram_read_swab(tp, offset, &val))
+ return;
+
+ if ((val & 0xfc000000) == 0x0c000000) {
+ u32 ver_offset, addr;
+ int i;
+
+ if (tg3_nvram_read_swab(tp, offset + 4, &val) ||
+ tg3_nvram_read_swab(tp, offset + 8, &ver_offset))
+ return;
+
+ if (val != 0)
+ return;
+
+ addr = offset + ver_offset - start;
+ for (i = 0; i < 16; i += 4) {
+ if (tg3_nvram_read(tp, addr + i, &val))
+ return;
+
+ val = cpu_to_le32(val);
+ memcpy(tp->fw_ver + i, &val, 4);
+ }
+ }
+}
+
#ifdef CONFIG_SPARC64
static int __devinit tg3_is_sun_570X(struct tg3 *tp)
{
@@ -9446,6 +9940,8 @@
static struct pci_device_id write_reorder_chipsets[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_FE_GATE_700C) },
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD,
+ 0x7450) },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_8385_0) },
{ },
@@ -9554,36 +10050,12 @@
}
}
- /* The EPB bridge inside 5714, 5715, and 5780 cannot support
- * DMA addresses > 40-bit. This bridge may have other additional
- * 57xx devices behind it in some 4-port NIC designs for example.
- * Any tg3 device found behind the bridge will also need the 40-bit
- * DMA workaround.
- */
+ /* Find msi capability. */
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
tp->tg3_flags2 |= TG3_FLG2_5780_CLASS;
- tp->tg3_flags |= TG3_FLAG_40BIT_DMA_BUG;
tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
}
- else {
- struct pci_dev *bridge = NULL;
-
- do {
- bridge = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
- PCI_DEVICE_ID_SERVERWORKS_EPB,
- bridge);
- if (bridge && bridge->subordinate &&
- (bridge->subordinate->number <=
- tp->pdev->bus->number) &&
- (bridge->subordinate->subordinate >=
- tp->pdev->bus->number)) {
- tp->tg3_flags |= TG3_FLAG_40BIT_DMA_BUG;
- pci_dev_put(bridge);
- break;
- }
- } while (bridge);
- }
/* Initialize misc host control in PCI block. */
tp->misc_host_ctrl |= (misc_ctrl_reg &
@@ -9601,6 +10073,8 @@
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
@@ -9608,12 +10082,20 @@
(tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
tp->tg3_flags2 |= TG3_FLG2_5705_PLUS;
- if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
- tp->tg3_flags2 |= TG3_FLG2_HW_TSO;
+ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) {
+ tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
+ tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
+ } else
+ tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1;
+ }
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750 &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752)
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755 &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787)
tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE;
if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0)
@@ -9769,8 +10251,11 @@
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
+ tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
+
/* Force the chip into D0. */
- err = tg3_set_power_state(tp, 0);
+ err = tg3_set_power_state(tp, PCI_D0);
if (err) {
printk(KERN_ERR PFX "(%s) transition to D0 failed\n",
pci_name(tp->pdev));
@@ -9823,7 +10308,9 @@
if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0)
tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG;
- if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+ if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
+ (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755) &&
+ (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787))
tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
tp->coalesce_mode = 0;
@@ -9923,6 +10410,7 @@
}
tg3_read_partno(tp);
+ tg3_read_fw_ver(tp);
if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
tp->tg3_flags &= ~TG3_FLAG_USE_MI_INTERRUPT;
@@ -9958,10 +10446,14 @@
else
tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES;
- /* It seems all chips can get confused if TX buffers
+ /* All chips before 5787 can get confused if TX buffers
* straddle the 4GB address boundary in some cases.
*/
- tp->dev->hard_start_xmit = tg3_start_xmit;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+ tp->dev->hard_start_xmit = tg3_start_xmit;
+ else
+ tp->dev->hard_start_xmit = tg3_start_xmit_dma_bug;
tp->rx_offset = 2;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
@@ -9989,7 +10481,9 @@
if (prom_getproplen(node, "local-mac-address") == 6) {
prom_getproperty(node, "local-mac-address",
dev->dev_addr, 6);
+#if 0 /* Not in RHEL4... */
memcpy(dev->perm_addr, dev->dev_addr, 6);
+#endif
return 0;
}
}
@@ -10001,7 +10495,9 @@
struct net_device *dev = tp->dev;
memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
+#if 0 /* Not in RHEL4... */
memcpy(dev->perm_addr, idprom->id_ethaddr, 6);
+#endif
return 0;
}
#endif
@@ -10071,7 +10567,9 @@
#endif
return -EINVAL;
}
+#if 0 /* Not in RHEL4... */
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+#endif
return 0;
}
@@ -10329,14 +10827,7 @@
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
u32 ccval = (tr32(TG3PCI_CLOCK_CTRL) & 0x1f);
- /* If the 5704 is behind the EPB bridge, we can
- * do the less restrictive ONE_DMA workaround for
- * better performance.
- */
- if ((tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) &&
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
- tp->dma_rwctrl |= 0x8000;
- else if (ccval == 0x6 || ccval == 0x7)
+ if (ccval == 0x6 || ccval == 0x7)
tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA;
/* Set bit 23 to enable PCIX hw bug fix */
@@ -10489,7 +10980,6 @@
tp->link_config.speed = SPEED_INVALID;
tp->link_config.duplex = DUPLEX_INVALID;
tp->link_config.autoneg = AUTONEG_ENABLE;
- netif_carrier_off(tp->dev);
tp->link_config.active_speed = SPEED_INVALID;
tp->link_config.active_duplex = DUPLEX_INVALID;
tp->link_config.phy_is_low_power = 0;
@@ -10548,6 +11038,8 @@
case PHY_ID_BCM5752: return "5752";
case PHY_ID_BCM5714: return "5714";
case PHY_ID_BCM5780: return "5780";
+ case PHY_ID_BCM5755: return "5755";
+ case PHY_ID_BCM5787: return "5787";
case PHY_ID_BCM8002: return "8002/serdes";
case 0: return "serdes";
default: return "unknown";
@@ -10576,6 +11068,8 @@
strcat(str, "66MHz");
else if (clock_ctrl == 6)
strcat(str, "100MHz");
+ else if (clock_ctrl == 7)
+ strcat(str, "133MHz");
} else {
strcpy(str, "PCI:");
if (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED)
@@ -10792,20 +11286,19 @@
goto err_out_iounmap;
}
- /* The EPB bridge inside 5714, 5715, and 5780 and any
- * device behind the EPB cannot support DMA addresses > 40-bit.
+ /* 5714, 5715 and 5780 cannot support DMA addresses > 40-bit.
* On 64-bit systems with IOMMU, use 40-bit dma_mask.
* On 64-bit systems without IOMMU, use 64-bit dma_mask and
* do DMA address check in tg3_start_xmit().
*/
- if (tp->tg3_flags2 & TG3_FLG2_IS_5788)
- persist_dma_mask = dma_mask = DMA_32BIT_MASK;
- else if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) {
+ if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
persist_dma_mask = dma_mask = DMA_40BIT_MASK;
#ifdef CONFIG_HIGHMEM
dma_mask = DMA_64BIT_MASK;
#endif
- } else
+ } else if (tp->tg3_flags2 & TG3_FLG2_IS_5788)
+ persist_dma_mask = dma_mask = DMA_32BIT_MASK;
+ else
persist_dma_mask = dma_mask = DMA_64BIT_MASK;
/* Configure DMA attributes. */
@@ -10846,11 +11339,12 @@
tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
}
- /* TSO is off by default, user can enable using ethtool. */
-#if 0
- if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)
+ /* TSO is on by default on chips that support hardware TSO.
+ * Firmware TSO on older chips gives lower performance, so it
+ * is off by default, but can be enabled using ethtool.
+ */
+ if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
dev->features |= NETIF_F_TSO;
-#endif
#endif
@@ -10894,7 +11388,12 @@
* checksumming.
*/
if ((tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) == 0) {
- dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+ dev->features |= NETIF_F_HW_CSUM;
+ else
+ dev->features |= NETIF_F_IP_CSUM;
+ dev->features |= NETIF_F_SG;
tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
} else
tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
@@ -10942,10 +11441,10 @@
(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);
- printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n",
- dev->name, tp->dma_rwctrl,
- (pdev->dma_mask == DMA_32BIT_MASK) ? 32 :
- (((u64) pdev->dma_mask == DMA_40BIT_MASK) ? 40 : 64));
+ printk(KERN_INFO "%s: dma_rwctrl[%08x]\n",
+ dev->name, tp->dma_rwctrl);
+
+ netif_carrier_off(tp->dev);
return 0;
@@ -11042,7 +11541,7 @@
pci_restore_state(tp->pdev);
- err = tg3_set_power_state(tp, 0);
+ err = tg3_set_power_state(tp, PCI_D0);
if (err)
return err;
diff -ruN linux-2.6.16.29-xen/drivers/net/tg3_compat.h linux-2.6.16.29-xen.hacked/drivers/net/tg3_compat.h
--- linux-2.6.16.29-xen/drivers/net/tg3_compat.h 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.16.29-xen.hacked/drivers/net/tg3_compat.h 2006-11-05 19:07:34.000000000 -0800
@@ -0,0 +1,55 @@
+#ifndef __TG3_COMPAT_H__
+#define __TG3_COMPAT_H__
+
+#define DMA_40BIT_MASK 0x000000ffffffffffULL
+
+#define skb_header_cloned(skb) 0
+
+//#define pci_choose_state(pdev, state) (state)
+
+//typedef u32 pm_message_t;
+
+//typedef int __bitwise pci_power_t;
+
+#define PCI_D0 ((pci_power_t __force) 0)
+#define PCI_D1 ((pci_power_t __force) 1)
+#define PCI_D2 ((pci_power_t __force) 2)
+#define PCI_D3hot ((pci_power_t __force) 3)
+#define PCI_D3cold ((pci_power_t __force) 4)
+
+#//define pci_choose_state(pdev, state) (state)
+
+#ifndef ADVERTISE_PAUSE
+#define ADVERTISE_PAUSE_CAP 0x0400
+#endif
+#ifndef ADVERTISE_PAUSE_ASYM
+#define ADVERTISE_PAUSE_ASYM 0x0800
+#endif
+#ifndef LPA_PAUSE
+#define LPA_PAUSE_CAP 0x0400
+#endif
+#ifndef LPA_PAUSE_ASYM
+#define LPA_PAUSE_ASYM 0x0800
+#endif
+
+#if 0
+/**
+ * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not.
+ * @ids: A pointer to a null terminated list of struct pci_device_id structures
+ * that describe the type of PCI device the caller is trying to find.
+ *
+ * This is a cheap knock-off, just to help in back-porting tg3 from
+ * later kernels...beware of changes in usage...
+ */
+static inline int pci_dev_present(const struct pci_device_id *ids)
+{
+ const struct pci_device_id *dev;
+
+ for (dev = ids; dev->vendor; dev++) {
+ if (pci_find_device(dev->vendor, dev->device, NULL))
+ return 1;
+ }
+ return 0;
+}
+#endif
+#endif /* __TG3_COMPAT_H__ */
diff -ruN linux-2.6.16.29-xen/drivers/net/tg3.h linux-2.6.16.29-xen.hacked/drivers/net/tg3.h
--- linux-2.6.16.29-xen/drivers/net/tg3.h 2006-09-12 11:02:10.000000000 -0700
+++ linux-2.6.16.29-xen.hacked/drivers/net/tg3.h 2006-11-05 18:36:05.000000000 -0800
@@ -138,6 +138,8 @@
#define ASIC_REV_5752 0x06
#define ASIC_REV_5780 0x08
#define ASIC_REV_5714 0x09
+#define ASIC_REV_5755 0x0a
+#define ASIC_REV_5787 0x0b
#define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8)
#define CHIPREV_5700_AX 0x70
#define CHIPREV_5700_BX 0x71
@@ -455,6 +457,7 @@
#define RX_MODE_PROMISC 0x00000100
#define RX_MODE_NO_CRC_CHECK 0x00000200
#define RX_MODE_KEEP_VLAN_TAG 0x00000400
+#define RX_MODE_IPV6_CSUM_ENABLE 0x01000000
#define MAC_RX_STATUS 0x0000046c
#define RX_STATUS_REMOTE_TX_XOFFED 0x00000001
#define RX_STATUS_XOFF_RCVD 0x00000002
@@ -1339,6 +1342,7 @@
#define GRC_LCLCTRL_CLEARINT 0x00000002
#define GRC_LCLCTRL_SETINT 0x00000004
#define GRC_LCLCTRL_INT_ON_ATTN 0x00000008
+#define GRC_LCLCTRL_GPIO_UART_SEL 0x00000010 /* 5755 only */
#define GRC_LCLCTRL_USE_SIG_DETECT 0x00000010 /* 5714/5780 only */
#define GRC_LCLCTRL_USE_EXT_SIG_DETECT 0x00000020 /* 5714/5780 only */
#define GRC_LCLCTRL_GPIO_INPUT3 0x00000020
@@ -1393,6 +1397,7 @@
#define GRC_MDI_CTRL 0x00006844
#define GRC_SEEPROM_DELAY 0x00006848
/* 0x684c --> 0x6c00 unused */
+#define GRC_FASTBOOT_PC 0x00006894 /* 5752, 5755, 5787 */
/* 0x6c00 --> 0x7000 unused */
@@ -1436,6 +1441,16 @@
#define FLASH_5752VENDOR_ST_M45PE10 0x02400000
#define FLASH_5752VENDOR_ST_M45PE20 0x02400002
#define FLASH_5752VENDOR_ST_M45PE40 0x02400001
+#define FLASH_5755VENDOR_ATMEL_FLASH_1 0x03400001
+#define FLASH_5755VENDOR_ATMEL_FLASH_2 0x03400002
+#define FLASH_5755VENDOR_ATMEL_FLASH_3 0x03400000
+#define FLASH_5755VENDOR_ATMEL_FLASH_4 0x00000003
+#define FLASH_5755VENDOR_ATMEL_EEPROM_64KHZ 0x03c00003
+#define FLASH_5755VENDOR_ATMEL_EEPROM_376KHZ 0x03c00002
+#define FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ 0x03000003
+#define FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ 0x03000002
+#define FLASH_5787VENDOR_MICRO_EEPROM_64KHZ 0x03000000
+#define FLASH_5787VENDOR_MICRO_EEPROM_376KHZ 0x02000000
#define NVRAM_CFG1_5752PAGE_SIZE_MASK 0x70000000
#define FLASH_5752PAGE_SIZE_256 0x00000000
#define FLASH_5752PAGE_SIZE_512 0x10000000
@@ -2163,7 +2178,6 @@
#define TG3_FLAG_10_100_ONLY 0x01000000
#define TG3_FLAG_PAUSE_AUTONEG 0x02000000
#define TG3_FLAG_IN_RESET_TASK 0x04000000
-#define TG3_FLAG_40BIT_DMA_BUG 0x08000000
#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000
#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000
#define TG3_FLAG_SPLIT_MODE 0x40000000
@@ -2185,7 +2199,7 @@
#define TG3_FLG2_PHY_SERDES 0x00002000
#define TG3_FLG2_CAPACITIVE_COUPLING 0x00004000
#define TG3_FLG2_FLASH 0x00008000
-#define TG3_FLG2_HW_TSO 0x00010000
+#define TG3_FLG2_HW_TSO_1 0x00010000
#define TG3_FLG2_SERDES_PREEMPHASIS 0x00020000
#define TG3_FLG2_5705_PLUS 0x00040000
#define TG3_FLG2_5750_PLUS 0x00080000
@@ -2198,6 +2212,9 @@
#define TG3_FLG2_PARALLEL_DETECT 0x01000000
#define TG3_FLG2_ICH_WORKAROUND 0x02000000
#define TG3_FLG2_5780_CLASS 0x04000000
+#define TG3_FLG2_HW_TSO_2 0x08000000
+#define TG3_FLG2_HW_TSO (TG3_FLG2_HW_TSO_1 | TG3_FLG2_HW_TSO_2)
+#define TG3_FLG2_1SHOT_MSI 0x10000000
u32 split_mode_max_reqs;
#define SPLIT_MODE_5704_MAX_REQ 3
@@ -2229,6 +2246,7 @@
u8 pci_lat_timer;
u8 pci_hdr_type;
u8 pci_bist;
+ u32 pci_cfg_state[64 / sizeof(u32)];
int pm_cap;
int msi_cap;
@@ -2247,6 +2265,8 @@
#define PHY_ID_BCM5752 0x60008100
#define PHY_ID_BCM5714 0x60008340
#define PHY_ID_BCM5780 0x60008350
+#define PHY_ID_BCM5755 0xbc050cc0
+#define PHY_ID_BCM5787 0xbc050ce0
#define PHY_ID_BCM8002 0x60010140
#define PHY_ID_INVALID 0xffffffff
#define PHY_ID_REV_MASK 0x0000000f
@@ -2258,6 +2278,7 @@
u32 led_ctrl;
char board_part_number[24];
+ char fw_ver[16];
u32 nic_sram_data_cfg;
u32 pci_clock_ctrl;
struct pci_dev *pdev_peer;
@@ -2271,7 +2292,8 @@
(X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \
(X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \
(X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \
- (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM8002)
+ (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM5787 || \
+ (X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM8002)
struct tg3_hw_stats *hw_stats;
dma_addr_t stats_mapping;
diff -ruN linux-2.6.16.29-xen/include/linux/pci_ids.h linux-2.6.16.29-xen.hacked/include/linux/pci_ids.h
--- linux-2.6.16.29-xen/include/linux/pci_ids.h 2006-09-12 11:02:10.000000000 -0700
+++ linux-2.6.16.29-xen.hacked/include/linux/pci_ids.h 2006-11-05 18:47:22.000000000 -0800
@@ -1860,16 +1860,24 @@
#define PCI_DEVICE_ID_TIGON3_5705M 0x165d
#define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e
#define PCI_DEVICE_ID_TIGON3_5714 0x1668
+#define PCI_DEVICE_ID_TIGON3_5714S 0x1669
#define PCI_DEVICE_ID_TIGON3_5780 0x166a
#define PCI_DEVICE_ID_TIGON3_5780S 0x166b
#define PCI_DEVICE_ID_TIGON3_5705F 0x166e
+#define PCI_DEVICE_ID_TIGON3_5754M 0x1672
+#define PCI_DEVICE_ID_TIGON3_5755M 0x1673
#define PCI_DEVICE_ID_TIGON3_5750 0x1676
#define PCI_DEVICE_ID_TIGON3_5751 0x1677
#define PCI_DEVICE_ID_TIGON3_5715 0x1678
+#define PCI_DEVICE_ID_TIGON3_5715S 0x1679
+#define PCI_DEVICE_ID_TIGON3_5754 0x167a
+#define PCI_DEVICE_ID_TIGON3_5755 0x167b
#define PCI_DEVICE_ID_TIGON3_5750M 0x167c
#define PCI_DEVICE_ID_TIGON3_5751M 0x167d
#define PCI_DEVICE_ID_TIGON3_5751F 0x167e
+#define PCI_DEVICE_ID_TIGON3_5787M 0x1693
#define PCI_DEVICE_ID_TIGON3_5782 0x1696
+#define PCI_DEVICE_ID_TIGON3_5787 0x169b
#define PCI_DEVICE_ID_TIGON3_5788 0x169c
#define PCI_DEVICE_ID_TIGON3_5789 0x169d
#define PCI_DEVICE_ID_TIGON3_5702X 0x16a6
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 3653 bytes --]
[-- Attachment #2: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2006-11-16 15:45 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-16 6:20 Tg3 updated driver Patrick Stach
2006-11-16 15:45 ` Andrew D. Ball
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.