summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@mandrakesoft.com>2002-03-12 09:17:29 -0500
committerJeff Garzik <jgarzik@mandrakesoft.com>2002-03-12 09:17:29 -0500
commitcebccfecc88df6b0340afd9c5d4bd6e3401b5db2 (patch)
tree7df49794ea531b5f146e3ac96a3310bf29b7fb4a
parent86a348813f17025f0c57db34fc40cb434a42d365 (diff)
tg3 gige net driver update:
* Merge several bug fixes from vger cvs * Merge h/w VLAN support, now that API is in the main tree * Add support for TX/RX coalescing
-rw-r--r--drivers/net/tg3.c636
-rw-r--r--drivers/net/tg3.h51
2 files changed, 604 insertions, 83 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 8fc97de4602d..7261252d2401 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -1,4 +1,4 @@
-/* $Id: tg3.c,v 1.43.2.74 2002/03/06 22:22:29 davem Exp $
+/* $Id: tg3.c,v 1.43.2.79 2002/03/12 07:11:17 davem Exp $
* tg3.c: Broadcom Tigon3 ethernet driver.
*
* Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com)
@@ -42,7 +42,11 @@
*/
#define TG3_MINI_RING_WORKS 0
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#define TG3_VLAN_TAG_USED 1
+#else
#define TG3_VLAN_TAG_USED 0
+#endif
#include "tg3.h"
@@ -78,15 +82,16 @@
* them in the NIC onboard memory.
*/
#define TG3_RX_RING_SIZE 512
-#define TG3_RX_RING_PENDING 200
+#define TG3_DEF_RX_RING_PENDING 200
#if TG3_MINI_RING_WORKS
#define TG3_RX_MINI_RING_SIZE 256 /* ??? */
-#define TG3_RX_MINI_RING_PENDING 100
+#define TG3_DEF_RX_MINI_RING_PENDING 100
#endif
#define TG3_RX_JUMBO_RING_SIZE 256
-#define TG3_RX_JUMBO_RING_PENDING 100
+#define TG3_DEF_RX_JUMBO_RING_PENDING 100
#define TG3_RX_RCB_RING_SIZE 1024
#define TG3_TX_RING_SIZE 512
+#define TG3_DEF_TX_RING_PENDING (TG3_TX_RING_SIZE - 1)
#define TG3_RX_RING_BYTES (sizeof(struct tg3_rx_buffer_desc) * \
TG3_RX_RING_SIZE)
@@ -100,10 +105,12 @@
TG3_RX_RCB_RING_SIZE)
#define TG3_TX_RING_BYTES (sizeof(struct tg3_tx_buffer_desc) * \
TG3_TX_RING_SIZE)
+#define TX_RING_GAP(TP) \
+ (TG3_TX_RING_SIZE - (TP)->tx_pending)
#define TX_BUFFS_AVAIL(TP) \
(((TP)->tx_cons <= (TP)->tx_prod) ? \
- (TP)->tx_cons + (TG3_TX_RING_SIZE - 1) - (TP)->tx_prod : \
- (TP)->tx_cons - (TP)->tx_prod - 1)
+ (TP)->tx_cons + (TP)->tx_pending - (TP)->tx_prod : \
+ (TP)->tx_cons - (TP)->tx_prod - TX_RING_GAP(TP))
#define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1))
#define RX_PKT_BUF_SZ (1536 + tp->rx_offset + 64)
@@ -1346,6 +1353,7 @@ static int tg3_setup_fiber_phy(struct tg3 *tp)
aninfo.flags |= (MR_AN_ENABLE);
for (i = 0; i < 6; i++) {
+ unsigned int tick;
u32 tmp;
tw32(MAC_TX_AUTO_NEG, 0);
@@ -1358,7 +1366,8 @@ static int tg3_setup_fiber_phy(struct tg3 *tp)
aninfo.state = ANEG_STATE_UNKNOWN;
aninfo.cur_time = 0;
- while (aninfo.cur_time < 95000) {
+ tick = 0;
+ while (++tick < 95000) {
status = tg3_fiber_aneg_smachine(tp, &aninfo);
if (status == ANEG_DONE ||
status == ANEG_FAILED)
@@ -1782,7 +1791,7 @@ static void tg3_rx(struct tg3 *tp)
skb = copy_skb;
}
- if (!(tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) &&
+ if ((tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) &&
(desc->type_flags & RXD_FLAG_TCPUDP_CSUM)) {
skb->csum = htons((desc->ip_tcp_csum & RXD_TCPCSUM_MASK)
>> RXD_TCPCSUM_SHIFT);
@@ -1835,61 +1844,99 @@ next_pkt_nopost:
#endif
}
-#define RATE_SAMPLE_INTERVAL (1 * HZ)
-
#define PKT_RATE_LOW 22000
#define PKT_RATE_HIGH 61000
static void tg3_rate_sample(struct tg3 *tp, unsigned long ticks)
{
u32 delta, rx_now, tx_now;
- int new_vals;
+ int new_vals, do_tx, do_rx;
rx_now = tp->hw_stats->rx_ucast_packets.low;
tx_now = tp->hw_stats->COS_out_packets[0].low;
delta = (rx_now - tp->last_rx_count);
delta += (tx_now - tp->last_tx_count);
- delta /= (ticks / RATE_SAMPLE_INTERVAL);
+ delta /= (ticks / tp->coalesce_config.rate_sample_jiffies);
tp->last_rx_count = rx_now;
tp->last_tx_count = tx_now;
new_vals = 0;
- if (delta < PKT_RATE_LOW) {
- if (tp->coalesce_config.rx_max_coalesced_frames !=
- LOW_RXMAX_FRAMES) {
+ do_tx = (tp->tg3_flags & TG3_FLAG_ADAPTIVE_TX) != 0;
+ do_rx = (tp->tg3_flags & TG3_FLAG_ADAPTIVE_RX) != 0;
+ if (delta < tp->coalesce_config.pkt_rate_low) {
+ if (do_rx &&
+ tp->coalesce_config.rx_max_coalesced_frames !=
+ tp->coalesce_config.rx_max_coalesced_frames_low) {
tp->coalesce_config.rx_max_coalesced_frames =
LOW_RXMAX_FRAMES;
tp->coalesce_config.rx_coalesce_ticks =
LOW_RXCOL_TICKS;
new_vals = 1;
}
- } else if (delta < PKT_RATE_HIGH) {
- if (tp->coalesce_config.rx_max_coalesced_frames !=
- DEFAULT_RXMAX_FRAMES) {
+ if (do_tx &&
+ tp->coalesce_config.tx_max_coalesced_frames !=
+ tp->coalesce_config.tx_max_coalesced_frames_low) {
+ tp->coalesce_config.tx_max_coalesced_frames =
+ tp->coalesce_config.tx_max_coalesced_frames_low;
+ tp->coalesce_config.tx_coalesce_ticks =
+ tp->coalesce_config.tx_coalesce_ticks_low;
+ new_vals = 1;
+ }
+ } else if (delta < tp->coalesce_config.pkt_rate_high) {
+ if (do_rx &&
+ tp->coalesce_config.rx_max_coalesced_frames !=
+ tp->coalesce_config.rx_max_coalesced_frames_def) {
tp->coalesce_config.rx_max_coalesced_frames =
- DEFAULT_RXMAX_FRAMES;
+ tp->coalesce_config.rx_max_coalesced_frames_def;
tp->coalesce_config.rx_coalesce_ticks =
- DEFAULT_RXCOL_TICKS;
+ tp->coalesce_config.rx_coalesce_ticks_def;
+ new_vals = 1;
+ }
+ if (do_tx &&
+ tp->coalesce_config.tx_max_coalesced_frames !=
+ tp->coalesce_config.tx_max_coalesced_frames_def) {
+ tp->coalesce_config.tx_max_coalesced_frames =
+ tp->coalesce_config.tx_max_coalesced_frames_def;
+ tp->coalesce_config.tx_coalesce_ticks =
+ tp->coalesce_config.tx_coalesce_ticks_def;
new_vals = 1;
}
} else {
- if (tp->coalesce_config.rx_max_coalesced_frames !=
- HIGH_RXMAX_FRAMES) {
+ if (do_rx &&
+ tp->coalesce_config.rx_max_coalesced_frames !=
+ tp->coalesce_config.rx_max_coalesced_frames_high) {
tp->coalesce_config.rx_max_coalesced_frames =
- HIGH_RXMAX_FRAMES;
+ tp->coalesce_config.rx_max_coalesced_frames_high;
tp->coalesce_config.rx_coalesce_ticks =
- HIGH_RXCOL_TICKS;
+ tp->coalesce_config.rx_coalesce_ticks_high;
+ new_vals = 1;
+ }
+ if (do_tx &&
+ tp->coalesce_config.tx_max_coalesced_frames !=
+ tp->coalesce_config.tx_max_coalesced_frames_high) {
+ tp->coalesce_config.tx_max_coalesced_frames =
+ tp->coalesce_config.tx_max_coalesced_frames_high;
+ tp->coalesce_config.tx_coalesce_ticks =
+ tp->coalesce_config.tx_coalesce_ticks_high;
new_vals = 1;
}
}
if (new_vals) {
- tw32(HOSTCC_RXCOL_TICKS,
- tp->coalesce_config.rx_coalesce_ticks);
- tw32(HOSTCC_RXMAX_FRAMES,
- tp->coalesce_config.rx_max_coalesced_frames);
+ if (do_rx) {
+ tw32(HOSTCC_RXCOL_TICKS,
+ tp->coalesce_config.rx_coalesce_ticks);
+ tw32(HOSTCC_RXMAX_FRAMES,
+ tp->coalesce_config.rx_max_coalesced_frames);
+ }
+ if (do_tx) {
+ tw32(HOSTCC_TXCOL_TICKS,
+ tp->coalesce_config.tx_coalesce_ticks);
+ tw32(HOSTCC_TXMAX_FRAMES,
+ tp->coalesce_config.tx_max_coalesced_frames);
+ }
}
tp->last_rate_sample = jiffies;
@@ -1919,10 +1966,11 @@ static void tg3_interrupt_main_work(struct tg3 *tp)
did_pkts = 1;
}
- if (did_pkts) {
+ if (did_pkts &&
+ (tp->tg3_flags & (TG3_FLAG_ADAPTIVE_RX | TG3_FLAG_ADAPTIVE_TX))) {
unsigned long ticks = jiffies - tp->last_rate_sample;
- if (ticks >= RATE_SAMPLE_INTERVAL)
+ if (ticks >= tp->coalesce_config.rate_sample_jiffies)
tg3_rate_sample(tp, ticks);
}
}
@@ -2590,14 +2638,14 @@ static void tg3_init_rings(struct tg3 *tp)
}
/* Now allocate fresh SKBs for each rx ring. */
- for (i = 0; i < TG3_RX_RING_PENDING; i++) {
+ for (i = 0; i < tp->rx_pending; i++) {
if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD,
-1, i) < 0)
break;
}
#if TG3_MINI_RING_WORKS
- for (i = 0; i < TG3_RX_MINI_RING_PENDING; i++) {
+ for (i = 0; i < tp->rx_mini_pending; i++) {
if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_MINI,
-1, i) < 0)
break;
@@ -2605,7 +2653,7 @@ static void tg3_init_rings(struct tg3 *tp)
#endif
if (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE) {
- for (i = 0; i < TG3_RX_JUMBO_RING_PENDING; i++) {
+ for (i = 0; i < tp->rx_jumbo_pending; i++) {
if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO,
-1, i) < 0)
break;
@@ -3420,11 +3468,11 @@ static int tg3_reset_hw(struct tg3 *tp)
}
/* Setup replenish thresholds. */
- tw32(RCVBDI_STD_THRESH, TG3_RX_RING_PENDING / 8);
+ tw32(RCVBDI_STD_THRESH, tp->rx_pending / 8);
#if TG3_MINI_RING_WORKS
- tw32(RCVBDI_MINI_THRESH, TG3_RX_MINI_RING_PENDING / 8);
+ tw32(RCVBDI_MINI_THRESH, tp->rx_mini_pending / 8);
#endif
- tw32(RCVBDI_JUMBO_THRESH, TG3_RX_JUMBO_RING_PENDING / 8);
+ tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8);
/* Clear out send RCB ring in SRAM. */
for (i = NIC_SRAM_SEND_RCB; i < NIC_SRAM_RCV_RET_RCB; i += TG3_BDINFO_SIZE)
@@ -3462,17 +3510,17 @@ static int tg3_reset_hw(struct tg3 *tp)
BDINFO_FLAGS_MAXLEN_SHIFT),
0);
- tp->rx_std_ptr = TG3_RX_RING_PENDING;
+ tp->rx_std_ptr = tp->rx_pending;
tw32_mailbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
tp->rx_std_ptr);
#if TG3_MINI_RING_WORKS
- tp->rx_mini_ptr = TG3_RX_MINI_RING_PENDING;
+ tp->rx_mini_ptr = tp->rx_mini_pending;
tw32_mailbox(MAILBOX_RCV_MINI_PROD_IDX + TG3_64BIT_REG_LOW,
tp->rx_mini_ptr);
#endif
if (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE)
- tp->rx_jumbo_ptr = TG3_RX_JUMBO_RING_PENDING;
+ tp->rx_jumbo_ptr = tp->rx_jumbo_pending;
else
tp->rx_jumbo_ptr = 0;
tw32_mailbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
@@ -3608,6 +3656,9 @@ static int tg3_reset_hw(struct tg3 *tp)
udelay(10);
tw32(MAC_RX_MODE, tp->rx_mode);
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1)
+ tw32(MAC_SERDES_CFG, 0x616000);
+
err = tg3_setup_phy(tp);
if (err)
return err;
@@ -4050,6 +4101,8 @@ static int tg3_open(struct net_device *dev)
}
#endif
+static struct net_device_stats *tg3_get_stats(struct net_device *);
+
static int tg3_close(struct net_device *dev)
{
struct tg3 *tp = dev->priv;
@@ -4073,6 +4126,9 @@ static int tg3_close(struct net_device *dev)
free_irq(dev->irq, dev);
+ memcpy(&tp->net_stats_prev, tg3_get_stats(tp->dev),
+ sizeof(tp->net_stats_prev));
+
tg3_free_consistent(tp);
return 0;
@@ -4121,46 +4177,53 @@ static struct net_device_stats *tg3_get_stats(struct net_device *dev)
{
struct tg3 *tp = dev->priv;
struct net_device_stats *stats = &tp->net_stats;
+ struct net_device_stats *old_stats = &tp->net_stats_prev;
struct tg3_hw_stats *hw_stats = tp->hw_stats;
- /* XXX Fix this... this is wrong because
- * XXX it means every open/close we lose the stats.
- */
if (!hw_stats)
- return stats;
+ return old_stats;
- stats->rx_packets =
+ stats->rx_packets = old_stats->rx_packets +
get_stat64(&hw_stats->rx_ucast_packets) +
get_stat64(&hw_stats->rx_mcast_packets) +
get_stat64(&hw_stats->rx_bcast_packets);
- stats->tx_packets =
+ stats->tx_packets = old_stats->tx_packets +
get_stat64(&hw_stats->COS_out_packets[0]);
- stats->rx_bytes = get_stat64(&hw_stats->rx_octets);
- stats->tx_bytes = get_stat64(&hw_stats->tx_octets);
+ stats->rx_bytes = old_stats->rx_bytes +
+ get_stat64(&hw_stats->rx_octets);
+ stats->tx_bytes = old_stats->tx_bytes +
+ get_stat64(&hw_stats->tx_octets);
- stats->rx_errors = get_stat64(&hw_stats->rx_errors);
- stats->tx_errors =
+ stats->rx_errors = old_stats->rx_errors +
+ get_stat64(&hw_stats->rx_errors);
+ stats->tx_errors = old_stats->tx_errors +
get_stat64(&hw_stats->tx_errors) +
get_stat64(&hw_stats->tx_mac_errors) +
get_stat64(&hw_stats->tx_carrier_sense_errors) +
get_stat64(&hw_stats->tx_discards);
- stats->multicast = get_stat64(&hw_stats->rx_mcast_packets);
- stats->collisions = get_stat64(&hw_stats->tx_collisions);
+ stats->multicast = old_stats->multicast +
+ get_stat64(&hw_stats->rx_mcast_packets);
+ stats->collisions = old_stats->collisions +
+ get_stat64(&hw_stats->tx_collisions);
- stats->rx_length_errors =
+ stats->rx_length_errors = old_stats->rx_length_errors +
get_stat64(&hw_stats->rx_frame_too_long_errors) +
get_stat64(&hw_stats->rx_undersize_packets);
- stats->rx_over_errors = get_stat64(&hw_stats->rxbds_empty);
- stats->rx_frame_errors = get_stat64(&hw_stats->rx_align_errors);
- stats->tx_aborted_errors = get_stat64(&hw_stats->tx_discards);
- stats->tx_carrier_errors =
+ stats->rx_over_errors = old_stats->rx_over_errors +
+ get_stat64(&hw_stats->rxbds_empty);
+ stats->rx_frame_errors = old_stats->rx_frame_errors +
+ get_stat64(&hw_stats->rx_align_errors);
+ stats->tx_aborted_errors = old_stats->tx_aborted_errors +
+ get_stat64(&hw_stats->tx_discards);
+ stats->tx_carrier_errors = old_stats->tx_carrier_errors +
get_stat64(&hw_stats->tx_carrier_sense_errors);
- stats->rx_crc_errors = calc_crc_errors(tp);
+ stats->rx_crc_errors = old_stats->rx_crc_errors +
+ calc_crc_errors(tp);
return stats;
}
@@ -4255,16 +4318,18 @@ static void tg3_set_rx_mode(struct net_device *dev)
spin_unlock_irq(&tp->lock);
}
+#define TG3_REGDUMP_LEN (32 * 1024)
+
static u8 *tg3_get_regs(struct tg3 *tp)
{
- u8 *orig_p = kmalloc((32 * 1024), GFP_KERNEL);
+ u8 *orig_p = kmalloc(TG3_REGDUMP_LEN, GFP_KERNEL);
u8 *p;
int i;
if (orig_p == NULL)
return NULL;
- memset(orig_p, 0, (32 * 1024));
+ memset(orig_p, 0, TG3_REGDUMP_LEN);
spin_lock_irq(&tp->lock);
@@ -4320,6 +4385,177 @@ do { p = orig_p + (reg); \
return orig_p;
}
+static void tg3_to_ethtool_coal(struct tg3 *tp,
+ struct ethtool_coalesce *ecoal)
+{
+ ecoal->rx_coalesce_usecs =
+ tp->coalesce_config.rx_coalesce_ticks_def;
+ ecoal->rx_max_coalesced_frames =
+ tp->coalesce_config.rx_max_coalesced_frames_def;
+ ecoal->rx_coalesce_usecs_irq =
+ tp->coalesce_config.rx_coalesce_ticks_during_int_def;
+ ecoal->rx_max_coalesced_frames_irq =
+ tp->coalesce_config.rx_max_coalesced_frames_during_int_def;
+
+ ecoal->tx_coalesce_usecs =
+ tp->coalesce_config.tx_coalesce_ticks_def;
+ ecoal->tx_max_coalesced_frames =
+ tp->coalesce_config.tx_max_coalesced_frames_def;
+ ecoal->tx_coalesce_usecs_irq =
+ tp->coalesce_config.tx_coalesce_ticks_during_int_def;
+ ecoal->tx_max_coalesced_frames_irq =
+ tp->coalesce_config.tx_max_coalesced_frames_during_int_def;
+
+ ecoal->stats_block_coalesce_usecs =
+ tp->coalesce_config.stats_coalesce_ticks_def;
+
+ ecoal->use_adaptive_rx_coalesce =
+ (tp->tg3_flags & TG3_FLAG_ADAPTIVE_RX) != 0;
+ ecoal->use_adaptive_tx_coalesce =
+ (tp->tg3_flags & TG3_FLAG_ADAPTIVE_TX) != 0;
+
+ ecoal->pkt_rate_low =
+ tp->coalesce_config.pkt_rate_low;
+ ecoal->rx_coalesce_usecs_low =
+ tp->coalesce_config.rx_coalesce_ticks_low;
+ ecoal->rx_max_coalesced_frames_low =
+ tp->coalesce_config.rx_max_coalesced_frames_low;
+ ecoal->tx_coalesce_usecs_low =
+ tp->coalesce_config.tx_coalesce_ticks_low;
+ ecoal->tx_max_coalesced_frames_low =
+ tp->coalesce_config.tx_max_coalesced_frames_low;
+
+ ecoal->pkt_rate_high =
+ tp->coalesce_config.pkt_rate_high;
+ ecoal->rx_coalesce_usecs_high =
+ tp->coalesce_config.rx_coalesce_ticks_high;
+ ecoal->rx_max_coalesced_frames_high =
+ tp->coalesce_config.rx_max_coalesced_frames_high;
+ ecoal->tx_coalesce_usecs_high =
+ tp->coalesce_config.tx_coalesce_ticks_high;
+ ecoal->tx_max_coalesced_frames_high =
+ tp->coalesce_config.tx_max_coalesced_frames_high;
+
+ ecoal->rate_sample_interval =
+ tp->coalesce_config.rate_sample_jiffies / HZ;
+}
+
+static int tg3_from_ethtool_coal(struct tg3 *tp,
+ struct ethtool_coalesce *ecoal)
+{
+ /* Make sure we are not getting garbage. */
+ if ((ecoal->rx_coalesce_usecs == 0 &&
+ ecoal->rx_max_coalesced_frames == 0) ||
+ (ecoal->tx_coalesce_usecs == 0 &&
+ ecoal->tx_max_coalesced_frames == 0) ||
+ ecoal->stats_block_coalesce_usecs == 0)
+ return -EINVAL;
+ if (ecoal->use_adaptive_rx_coalesce ||
+ ecoal->use_adaptive_tx_coalesce) {
+ if (ecoal->pkt_rate_low > ecoal->pkt_rate_high)
+ return -EINVAL;
+ if (ecoal->rate_sample_interval == 0)
+ return -EINVAL;
+ if (ecoal->use_adaptive_rx_coalesce &&
+ ((ecoal->rx_coalesce_usecs_low == 0 &&
+ ecoal->rx_max_coalesced_frames_low == 0) ||
+ (ecoal->rx_coalesce_usecs_high == 0 &&
+ ecoal->rx_max_coalesced_frames_high == 0)))
+ return -EINVAL;
+ if (ecoal->use_adaptive_tx_coalesce &&
+ ((ecoal->tx_coalesce_usecs_low == 0 &&
+ ecoal->tx_max_coalesced_frames_low == 0) ||
+ (ecoal->tx_coalesce_usecs_high == 0 &&
+ ecoal->tx_max_coalesced_frames_high == 0)))
+ return -EINVAL;
+ }
+
+ /* Looks good, let it rip. */
+ spin_lock_irq(&tp->lock);
+ tp->coalesce_config.rx_coalesce_ticks =
+ tp->coalesce_config.rx_coalesce_ticks_def =
+ ecoal->rx_coalesce_usecs;
+ tp->coalesce_config.rx_max_coalesced_frames =
+ tp->coalesce_config.rx_max_coalesced_frames_def =
+ ecoal->rx_max_coalesced_frames;
+ tp->coalesce_config.rx_coalesce_ticks_during_int =
+ tp->coalesce_config.rx_coalesce_ticks_during_int_def =
+ ecoal->rx_coalesce_usecs_irq;
+ tp->coalesce_config.rx_max_coalesced_frames_during_int =
+ tp->coalesce_config.rx_max_coalesced_frames_during_int_def =
+ ecoal->rx_max_coalesced_frames_irq;
+ tp->coalesce_config.tx_coalesce_ticks =
+ tp->coalesce_config.tx_coalesce_ticks_def =
+ ecoal->tx_coalesce_usecs;
+ tp->coalesce_config.tx_max_coalesced_frames =
+ tp->coalesce_config.tx_max_coalesced_frames_def =
+ ecoal->tx_max_coalesced_frames;
+ tp->coalesce_config.tx_coalesce_ticks_during_int =
+ tp->coalesce_config.tx_coalesce_ticks_during_int_def =
+ ecoal->tx_coalesce_usecs_irq;
+ tp->coalesce_config.tx_max_coalesced_frames_during_int =
+ tp->coalesce_config.tx_max_coalesced_frames_during_int_def =
+ ecoal->tx_max_coalesced_frames_irq;
+ tp->coalesce_config.stats_coalesce_ticks =
+ tp->coalesce_config.stats_coalesce_ticks_def =
+ ecoal->stats_block_coalesce_usecs;
+
+ if (ecoal->use_adaptive_rx_coalesce)
+ tp->tg3_flags |= TG3_FLAG_ADAPTIVE_RX;
+ else
+ tp->tg3_flags &= ~TG3_FLAG_ADAPTIVE_RX;
+ if (ecoal->use_adaptive_tx_coalesce)
+ tp->tg3_flags |= TG3_FLAG_ADAPTIVE_TX;
+ else
+ tp->tg3_flags &= ~TG3_FLAG_ADAPTIVE_TX;
+
+ tp->coalesce_config.pkt_rate_low = ecoal->pkt_rate_low;
+ tp->coalesce_config.pkt_rate_high = ecoal->pkt_rate_high;
+ tp->coalesce_config.rate_sample_jiffies =
+ ecoal->rate_sample_interval * HZ;
+
+ tp->coalesce_config.rx_coalesce_ticks_low =
+ ecoal->rx_coalesce_usecs_low;
+ tp->coalesce_config.rx_max_coalesced_frames_low =
+ ecoal->rx_max_coalesced_frames_low;
+ tp->coalesce_config.tx_coalesce_ticks_low =
+ ecoal->tx_coalesce_usecs_low;
+ tp->coalesce_config.tx_max_coalesced_frames_low =
+ ecoal->tx_max_coalesced_frames_low;
+
+ tp->coalesce_config.rx_coalesce_ticks_high =
+ ecoal->rx_coalesce_usecs_high;
+ tp->coalesce_config.rx_max_coalesced_frames_high =
+ ecoal->rx_max_coalesced_frames_high;
+ tp->coalesce_config.tx_coalesce_ticks_high =
+ ecoal->tx_coalesce_usecs_high;
+ tp->coalesce_config.tx_max_coalesced_frames_high =
+ ecoal->tx_max_coalesced_frames_high;
+
+ tw32(HOSTCC_RXCOL_TICKS,
+ tp->coalesce_config.rx_coalesce_ticks_def);
+ tw32(HOSTCC_RXMAX_FRAMES,
+ tp->coalesce_config.rx_max_coalesced_frames_def);
+ tw32(HOSTCC_RXCOAL_TICK_INT,
+ tp->coalesce_config.rx_coalesce_ticks_during_int_def);
+ tw32(HOSTCC_RXCOAL_MAXF_INT,
+ tp->coalesce_config.rx_max_coalesced_frames_during_int_def);
+ tw32(HOSTCC_TXCOL_TICKS,
+ tp->coalesce_config.tx_coalesce_ticks_def);
+ tw32(HOSTCC_TXMAX_FRAMES,
+ tp->coalesce_config.tx_max_coalesced_frames_def);
+ tw32(HOSTCC_TXCOAL_TICK_INT,
+ tp->coalesce_config.tx_coalesce_ticks_during_int_def);
+ tw32(HOSTCC_TXCOAL_MAXF_INT,
+ tp->coalesce_config.tx_max_coalesced_frames_during_int_def);
+ tw32(HOSTCC_STAT_COAL_TICKS,
+ tp->coalesce_config.stats_coalesce_ticks_def);
+
+ spin_unlock_irq(&tp->lock);
+
+ return 0;
+}
+
static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
{
struct tg3 *tp = dev->priv;
@@ -4334,7 +4570,10 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
strcpy (info.driver, DRV_MODULE_NAME);
strcpy (info.version, DRV_MODULE_VERSION);
+ memset(&info.fw_version, 0, sizeof(info.fw_version));
strcpy (info.bus_info, pci_dev->slot_name);
+ info.eedump_len = 0;
+ info.regdump_len = TG3_REGDUMP_LEN;
if (copy_to_user (useraddr, &info, sizeof (info)))
return -EFAULT;
return 0;
@@ -4368,8 +4607,8 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
cmd.phy_address = PHY_ADDR;
cmd.transceiver = 0;
cmd.autoneg = tp->link_config.autoneg;
- cmd.maxtxpkt = tp->coalesce_config.tx_max_coalesced_frames;
- cmd.maxrxpkt = tp->coalesce_config.rx_max_coalesced_frames;
+ cmd.maxtxpkt = tp->coalesce_config.tx_max_coalesced_frames_def;
+ cmd.maxrxpkt = tp->coalesce_config.rx_max_coalesced_frames_def;
if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
return -EFAULT;
return 0;
@@ -4422,9 +4661,11 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
}
if (cmd.maxtxpkt || cmd.maxrxpkt) {
- tp->coalesce_config.tx_max_coalesced_frames =
+ tp->coalesce_config.tx_max_coalesced_frames_def =
+ tp->coalesce_config.tx_max_coalesced_frames =
cmd.maxtxpkt;
- tp->coalesce_config.rx_max_coalesced_frames =
+ tp->coalesce_config.rx_max_coalesced_frames_def =
+ tp->coalesce_config.rx_max_coalesced_frames =
cmd.maxrxpkt;
/* Coalescing config bits can be updated without
@@ -4448,8 +4689,8 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
if (copy_from_user(&regs, useraddr, sizeof(regs)))
return -EFAULT;
- if (regs.len > (32 * 1024))
- regs.len = (32 * 1024);
+ if (regs.len > TG3_REGDUMP_LEN)
+ regs.len = TG3_REGDUMP_LEN;
regs.version = 0;
if (copy_to_user(useraddr, &regs, sizeof(regs)))
return -EFAULT;
@@ -4530,6 +4771,196 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT;
}
+ case ETHTOOL_GCOALESCE: {
+ struct ethtool_coalesce ecoal = { ETHTOOL_GCOALESCE };
+
+ tg3_to_ethtool_coal(tp, &ecoal);
+ if (copy_to_user(useraddr, &ecoal, sizeof(ecoal)))
+ return -EFAULT;
+ return 0;
+ }
+ case ETHTOOL_SCOALESCE: {
+ struct ethtool_coalesce ecoal;
+
+ if (copy_from_user(&ecoal, useraddr, sizeof(ecoal)))
+ return -EINVAL;
+
+ return tg3_from_ethtool_coal(tp, &ecoal);
+ }
+ case ETHTOOL_GRINGPARAM: {
+ struct ethtool_ringparam ering = { ETHTOOL_GRINGPARAM };
+
+ ering.rx_max_pending = TG3_RX_RING_SIZE - 1;
+#if TG3_MINI_RING_WORKS
+ ering.rx_mini_max_pending = TG3_RX_MINI_RING_SIZE - 1;
+#else
+ ering.rx_mini_max_pending = 0;
+#endif
+ ering.rx_jumbo_max_pending = TG3_RX_JUMBO_RING_SIZE - 1;
+
+ ering.rx_pending = tp->rx_pending;
+#if TG3_MINI_RING_WORKS
+ ering.rx_mini_pending = tp->rx_mini_pending;
+#else
+ ering.rx_mini_pending = 0;
+#endif
+ ering.rx_jumbo_pending = tp->rx_jumbo_pending;
+ ering.tx_pending = tp->tx_pending;
+
+ if (copy_to_user(useraddr, &ering, sizeof(ering)))
+ return -EFAULT;
+ return 0;
+ }
+ case ETHTOOL_SRINGPARAM: {
+ struct ethtool_ringparam ering;
+
+ if (copy_from_user(&ering, useraddr, sizeof(ering)))
+ return -EFAULT;
+
+ if ((ering.rx_pending > TG3_RX_RING_SIZE - 1) ||
+#if TG3_MINI_RING_WORKS
+ (ering.rx_mini_pending > TG3_RX_MINI_RING_SIZE - 1) ||
+#endif
+ (ering.rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) ||
+ (ering.tx_pending > TG3_TX_RING_SIZE - 1))
+ return -EINVAL;
+
+ spin_lock_irq(&tp->lock);
+
+ tp->rx_pending = ering.rx_pending;
+#if TG3_MINI_RING_WORKS
+ tp->rx_mini_pending = ering.rx_mini_pending;
+#endif
+ tp->rx_jumbo_pending = ering.rx_jumbo_pending;
+ tp->tx_pending = ering.tx_pending;
+
+ tg3_halt(tp);
+ tg3_init_rings(tp);
+ tg3_init_hw(tp);
+ netif_wake_queue(tp->dev);
+ spin_unlock_irq(&tp->lock);
+
+ return 0;
+ }
+ case ETHTOOL_GPAUSEPARAM: {
+ struct ethtool_pauseparam epause = { ETHTOOL_GPAUSEPARAM };
+
+ epause.autoneg =
+ (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) != 0;
+ epause.rx_pause =
+ (tp->tg3_flags & TG3_FLAG_PAUSE_RX) != 0;
+ epause.tx_pause =
+ (tp->tg3_flags & TG3_FLAG_PAUSE_TX) != 0;
+ if (copy_to_user(useraddr, &epause, sizeof(epause)))
+ return -EFAULT;
+ return 0;
+ }
+ case ETHTOOL_SPAUSEPARAM: {
+ struct ethtool_pauseparam epause;
+
+ if (copy_from_user(&epause, useraddr, sizeof(epause)))
+ return -EFAULT;
+
+ spin_lock_irq(&tp->lock);
+ if (epause.autoneg)
+ tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
+ else
+ tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
+ if (epause.rx_pause)
+ tp->tg3_flags |= TG3_FLAG_PAUSE_RX;
+ else
+ tp->tg3_flags &= ~TG3_FLAG_PAUSE_RX;
+ if (epause.tx_pause)
+ tp->tg3_flags |= TG3_FLAG_PAUSE_TX;
+ else
+ tp->tg3_flags &= ~TG3_FLAG_PAUSE_TX;
+ tg3_halt(tp);
+ tg3_init_rings(tp);
+ tg3_init_hw(tp);
+ spin_unlock_irq(&tp->lock);
+
+ return 0;
+ }
+ case ETHTOOL_GRXCSUM: {
+ struct ethtool_value edata = { ETHTOOL_GRXCSUM };
+
+ edata.data =
+ (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0;
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ return 0;
+ }
+ case ETHTOOL_SRXCSUM: {
+ struct ethtool_value edata;
+
+ if (copy_from_user(&edata, useraddr, sizeof(edata)))
+ return -EFAULT;
+
+ if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) {
+ if (edata.data != 0)
+ return -EINVAL;
+ return 0;
+ }
+
+ spin_lock_irq(&tp->lock);
+ if (edata.data)
+ tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
+ else
+ tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
+ spin_unlock_irq(&tp->lock);
+
+ return 0;
+ }
+ case ETHTOOL_GTXCSUM: {
+ struct ethtool_value edata = { ETHTOOL_GTXCSUM };
+
+ edata.data =
+ (tp->dev->features & NETIF_F_IP_CSUM) != 0;
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ return 0;
+ }
+ case ETHTOOL_STXCSUM: {
+ struct ethtool_value edata;
+
+ if (copy_from_user(&edata, useraddr, sizeof(edata)))
+ return -EFAULT;
+
+ if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) {
+ if (edata.data != 0)
+ return -EINVAL;
+ return 0;
+ }
+
+ if (edata.data)
+ tp->dev->features |= NETIF_F_IP_CSUM;
+ else
+ tp->dev->features &= ~NETIF_F_IP_CSUM;
+
+ return 0;
+ }
+ case ETHTOOL_GSG: {
+ struct ethtool_value edata = { ETHTOOL_GSG };
+
+ edata.data =
+ (tp->dev->features & NETIF_F_SG) != 0;
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ return 0;
+ }
+ case ETHTOOL_SSG: {
+ struct ethtool_value edata;
+
+ if (copy_from_user(&edata, useraddr, sizeof(edata)))
+ return -EFAULT;
+
+ if (edata.data)
+ tp->dev->features |= NETIF_F_SG;
+ else
+ tp->dev->features &= ~NETIF_F_SG;
+
+ return 0;
+ }
};
return -EOPNOTSUPP;
@@ -5126,10 +5557,10 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
/* If not using tagged status, set the *_during_int
* coalesce default config values to zero.
*/
- tp->coalesce_config.rx_coalesce_ticks_during_int = 0;
- tp->coalesce_config.rx_max_coalesced_frames_during_int = 0;
- tp->coalesce_config.tx_coalesce_ticks_during_int = 0;
- tp->coalesce_config.tx_max_coalesced_frames_during_int = 0;
+ tp->coalesce_config.rx_coalesce_ticks_during_int_def = 0;
+ tp->coalesce_config.rx_max_coalesced_frames_during_int_def = 0;
+ tp->coalesce_config.tx_coalesce_ticks_during_int_def = 0;
+ tp->coalesce_config.tx_max_coalesced_frames_during_int_def = 0;
}
if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_AX &&
@@ -5566,20 +5997,57 @@ static void __devinit tg3_init_link_config(struct tg3 *tp)
static void __devinit tg3_init_coalesce_config(struct tg3 *tp)
{
- tp->coalesce_config.rx_coalesce_ticks = DEFAULT_RXCOL_TICKS;
- tp->coalesce_config.rx_max_coalesced_frames = DEFAULT_RXMAX_FRAMES;
- tp->coalesce_config.rx_coalesce_ticks_during_int =
+ tp->coalesce_config.rx_coalesce_ticks_def = DEFAULT_RXCOL_TICKS;
+ tp->coalesce_config.rx_max_coalesced_frames_def = DEFAULT_RXMAX_FRAMES;
+ tp->coalesce_config.rx_coalesce_ticks_during_int_def =
DEFAULT_RXCOAL_TICK_INT;
- tp->coalesce_config.rx_max_coalesced_frames_during_int =
+ tp->coalesce_config.rx_max_coalesced_frames_during_int_def =
DEFAULT_RXCOAL_MAXF_INT;
- tp->coalesce_config.tx_coalesce_ticks = DEFAULT_TXCOL_TICKS;
- tp->coalesce_config.tx_max_coalesced_frames = DEFAULT_TXMAX_FRAMES;
- tp->coalesce_config.tx_coalesce_ticks_during_int =
+ tp->coalesce_config.tx_coalesce_ticks_def = DEFAULT_TXCOL_TICKS;
+ tp->coalesce_config.tx_max_coalesced_frames_def = DEFAULT_TXMAX_FRAMES;
+ tp->coalesce_config.tx_coalesce_ticks_during_int_def =
DEFAULT_TXCOAL_TICK_INT;
- tp->coalesce_config.tx_max_coalesced_frames_during_int =
+ tp->coalesce_config.tx_max_coalesced_frames_during_int_def =
DEFAULT_TXCOAL_MAXF_INT;
- tp->coalesce_config.stats_coalesce_ticks =
+ tp->coalesce_config.stats_coalesce_ticks_def =
DEFAULT_STAT_COAL_TICKS;
+
+ tp->coalesce_config.rx_coalesce_ticks_low =
+ LOW_RXCOL_TICKS;
+ tp->coalesce_config.rx_max_coalesced_frames_low =
+ LOW_RXMAX_FRAMES;
+ tp->coalesce_config.tx_coalesce_ticks_low =
+ LOW_TXCOL_TICKS;
+ tp->coalesce_config.tx_max_coalesced_frames_low =
+ LOW_TXMAX_FRAMES;
+
+ tp->coalesce_config.rx_coalesce_ticks_high =
+ HIGH_RXCOL_TICKS;
+ tp->coalesce_config.rx_max_coalesced_frames_high =
+ HIGH_RXMAX_FRAMES;
+ tp->coalesce_config.tx_coalesce_ticks_high =
+ HIGH_TXCOL_TICKS;
+ tp->coalesce_config.tx_max_coalesced_frames_high =
+ HIGH_TXMAX_FRAMES;
+
+ /* Active == default */
+ tp->coalesce_config.rx_coalesce_ticks =
+ tp->coalesce_config.rx_coalesce_ticks_def;
+ tp->coalesce_config.rx_max_coalesced_frames =
+ tp->coalesce_config.rx_max_coalesced_frames_def;
+ tp->coalesce_config.tx_coalesce_ticks =
+ tp->coalesce_config.tx_coalesce_ticks_def;
+ tp->coalesce_config.tx_max_coalesced_frames =
+ tp->coalesce_config.tx_max_coalesced_frames_def;
+ tp->coalesce_config.stats_coalesce_ticks =
+ tp->coalesce_config.stats_coalesce_ticks_def;
+
+ tp->coalesce_config.rate_sample_jiffies = (1 * HZ);
+ tp->coalesce_config.pkt_rate_low = 22000;
+ tp->coalesce_config.pkt_rate_high = 61000;
+
+ tp->tg3_flags |= TG3_FLAG_ADAPTIVE_RX;
+ tp->tg3_flags &= ~(TG3_FLAG_ADAPTIVE_TX);
}
static void __devinit tg3_init_bufmgr_config(struct tg3 *tp)
@@ -5743,6 +6211,13 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tg3_init_bufmgr_config(tp);
+ tp->rx_pending = TG3_DEF_RX_RING_PENDING;
+#if TG3_MINI_RING_WORKS
+ tp->rx_mini_pending = TG3_DEF_RX_MINI_RING_PENDING;
+#endif
+ tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
+ tp->tx_pending = TG3_DEF_TX_RING_PENDING;
+
dev->open = tg3_open;
dev->stop = tg3_close;
dev->get_stats = tg3_get_stats;
@@ -5777,8 +6252,11 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
/* Tigon3 can do ipv4 only... and some chips have buggy
* checksumming.
*/
- if ((tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) == 0)
+ if ((tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) == 0) {
dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+ tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
+ } else
+ tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
err = register_netdev(dev);
if (err) {
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index bfd1a7daf834..5beda44b61c1 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1,4 +1,4 @@
-/* $Id: tg3.h,v 1.37.2.30 2002/03/05 10:08:39 davem Exp $
+/* $Id: tg3.h,v 1.37.2.32 2002/03/11 12:18:18 davem Exp $
* tg3.h: Definitions for Broadcom Tigon3 ethernet driver.
*
* Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com)
@@ -713,13 +713,17 @@
#define DEFAULT_RXCOL_TICKS 0x00000048
#define HIGH_RXCOL_TICKS 0x00000096
#define HOSTCC_TXCOL_TICKS 0x00003c0c
+#define LOW_TXCOL_TICKS 0x00000096
#define DEFAULT_TXCOL_TICKS 0x0000012c
+#define HIGH_TXCOL_TICKS 0x00000145
#define HOSTCC_RXMAX_FRAMES 0x00003c10
#define LOW_RXMAX_FRAMES 0x00000005
#define DEFAULT_RXMAX_FRAMES 0x00000008
#define HIGH_RXMAX_FRAMES 0x00000012
#define HOSTCC_TXMAX_FRAMES 0x00003c14
+#define LOW_TXMAX_FRAMES 0x00000035
#define DEFAULT_TXMAX_FRAMES 0x0000004b
+#define HIGH_TXMAX_FRAMES 0x00000052
#define HOSTCC_RXCOAL_TICK_INT 0x00003c18
#define DEFAULT_RXCOAL_TICK_INT 0x00000019
#define HOSTCC_TXCOAL_TICK_INT 0x00003c1c
@@ -1681,17 +1685,42 @@ struct tg3_link_config {
};
struct tg3_coalesce_config {
+ /* Current settings. */
u32 rx_coalesce_ticks;
u32 rx_max_coalesced_frames;
u32 rx_coalesce_ticks_during_int;
u32 rx_max_coalesced_frames_during_int;
-
u32 tx_coalesce_ticks;
u32 tx_max_coalesced_frames;
u32 tx_coalesce_ticks_during_int;
u32 tx_max_coalesced_frames_during_int;
-
u32 stats_coalesce_ticks;
+
+ /* Default settings. */
+ u32 rx_coalesce_ticks_def;
+ u32 rx_max_coalesced_frames_def;
+ u32 rx_coalesce_ticks_during_int_def;
+ u32 rx_max_coalesced_frames_during_int_def;
+ u32 tx_coalesce_ticks_def;
+ u32 tx_max_coalesced_frames_def;
+ u32 tx_coalesce_ticks_during_int_def;
+ u32 tx_max_coalesced_frames_during_int_def;
+ u32 stats_coalesce_ticks_def;
+
+ /* Adaptive RX/TX coalescing parameters. */
+ u32 rate_sample_jiffies;
+ u32 pkt_rate_low;
+ u32 pkt_rate_high;
+
+ u32 rx_coalesce_ticks_low;
+ u32 rx_max_coalesced_frames_low;
+ u32 tx_coalesce_ticks_low;
+ u32 tx_max_coalesced_frames_low;
+
+ u32 rx_coalesce_ticks_high;
+ u32 rx_max_coalesced_frames_high;
+ u32 tx_coalesce_ticks_high;
+ u32 tx_max_coalesced_frames_high;
};
struct tg3_bufmgr_config {
@@ -1720,6 +1749,7 @@ struct tg3 {
spinlock_t indirect_lock;
struct net_device_stats net_stats;
+ struct net_device_stats net_stats_prev;
unsigned long phy_crc_errors;
/* Adaptive coalescing engine. */
@@ -1731,9 +1761,11 @@ struct tg3 {
u32 tg3_flags;
#define TG3_FLAG_HOST_TXDS 0x00000001
#define TG3_FLAG_TXD_MBOX_HWBUG 0x00000002
-#define TG3_FLAG_BROKEN_CHECKSUMS 0x00000004
+#define TG3_FLAG_RX_CHECKSUMS 0x00000004
#define TG3_FLAG_USE_LINKCHG_REG 0x00000008
#define TG3_FLAG_USE_MI_INTERRUPT 0x00000010
+#define TG3_FLAG_ADAPTIVE_RX 0x00000020
+#define TG3_FLAG_ADAPTIVE_TX 0x00000040
#define TG3_FLAG_PHY_RESET_ON_INIT 0x00000100
#define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200
#define TG3_FLAG_TAGGED_IRQ_STATUS 0x00000400
@@ -1751,6 +1783,10 @@ struct tg3 {
#define TG3_FLAG_AUTONEG_DISABLE 0x00400000
#define TG3_FLAG_JUMBO_ENABLE 0x00800000
#define TG3_FLAG_10_100_ONLY 0x01000000
+#define TG3_FLAG_PAUSE_AUTONEG 0x02000000
+#define TG3_FLAG_PAUSE_RX 0x04000000
+#define TG3_FLAG_PAUSE_TX 0x08000000
+#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000
#define TG3_FLAG_INIT_COMPLETE 0x80000000
u32 msg_enable;
@@ -1764,6 +1800,13 @@ struct tg3 {
struct tg3_coalesce_config coalesce_config;
struct tg3_bufmgr_config bufmgr_config;
+ u32 rx_pending;
+#if TG3_MINI_RING_WORKS
+ u32 rx_mini_pending;
+#endif
+ u32 rx_jumbo_pending;
+ u32 tx_pending;
+
/* cache h/w values, often passed straight to h/w */
u32 rx_mode;
u32 tx_mode;