summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjfv <jfv@FreeBSD.org>2011-04-01 18:48:31 +0000
committerjfv <jfv@FreeBSD.org>2011-04-01 18:48:31 +0000
commit47692eab3cde195383bbb502e46b1f8dce0f5508 (patch)
treef94c971edad9b3de0fd34dc5b919e46b31e1233f
parenta5be52d8024f41fc3cdd6c5fdb1ca746a0e9028e (diff)
downloadFreeBSD-src-47692eab3cde195383bbb502e46b1f8dce0f5508.zip
FreeBSD-src-47692eab3cde195383bbb502e46b1f8dce0f5508.tar.gz
Change the refresh_mbuf logic slightly, add an inline
to calculate the outstanding descriptors that need to be refreshed at any time, and use THAT in rxeof to determine if refreshing needs to be done. Also change the local_timer to simply fire off the appropriate interrupt rather than schedule a tasklet, its simpler. MFC in two weeks
-rw-r--r--sys/dev/e1000/if_em.c22
-rw-r--r--sys/dev/e1000/if_em.h18
2 files changed, 30 insertions, 10 deletions
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index c119144..6dcd90d 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2010, Intel Corporation
+ Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -93,7 +93,7 @@ int em_display_debug_stats = 0;
/*********************************************************************
* Driver version:
*********************************************************************/
-char em_driver_version[] = "7.2.2";
+char em_driver_version[] = "7.2.3";
/*********************************************************************
* PCI Device ID Table
@@ -2182,6 +2182,7 @@ em_local_timer(void *arg)
struct ifnet *ifp = adapter->ifp;
struct tx_ring *txr = adapter->tx_rings;
struct rx_ring *rxr = adapter->rx_rings;
+ u32 trigger;
EM_CORE_LOCK_ASSERT(adapter);
@@ -2193,12 +2194,11 @@ em_local_timer(void *arg)
e1000_get_laa_state_82571(&adapter->hw))
e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
- /* trigger tq to refill rx ring queue if it is empty */
- for (int i = 0; i < adapter->num_queues; i++, rxr++) {
- if (rxr->next_to_check == rxr->next_to_refresh) {
- taskqueue_enqueue(rxr->tq, &rxr->rx_task);
- }
- }
+ /* Mask to use in the irq trigger */
+ if (adapter->msix_mem)
+ trigger = rxr->ims; /* RX for 82574 */
+ else
+ trigger = E1000_ICS_RXDMT0;
/*
** Don't do TX watchdog check if we've been paused
@@ -2217,6 +2217,10 @@ em_local_timer(void *arg)
goto hung;
out:
callout_reset(&adapter->timer, hz, em_local_timer, adapter);
+#ifndef DEVICE_POLLING
+ /* Trigger an RX interrupt to guarantee mbuf refresh */
+ E1000_WRITE_REG(&adapter->hw, E1000_ICS, trigger);
+#endif
return;
hung:
/* Looks like we're hung */
@@ -4327,7 +4331,7 @@ next_desc:
}
/* Catch any remaining refresh work */
- if (processed != 0 || i == rxr->next_to_refresh)
+ if (e1000_rx_unrefreshed(rxr))
em_refresh_mbufs(rxr, i);
rxr->next_to_check = i;
diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h
index d27a53a..e25904e 100644
--- a/sys/dev/e1000/if_em.h
+++ b/sys/dev/e1000/if_em.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2010, Intel Corporation
+ Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -463,6 +463,22 @@ struct em_buffer {
bus_dmamap_t map; /* bus_dma map for packet */
};
+
+/*
+** Find the number of unrefreshed RX descriptors
+*/
+static inline u16
+e1000_rx_unrefreshed(struct rx_ring *rxr)
+{
+ struct adapter *adapter = rxr->adapter;
+
+ if (rxr->next_to_check > rxr->next_to_refresh)
+ return (rxr->next_to_check - rxr->next_to_refresh - 1);
+ else
+ return ((adapter->num_rx_desc + rxr->next_to_check) -
+ rxr->next_to_refresh - 1);
+}
+
#define EM_CORE_LOCK_INIT(_sc, _name) \
mtx_init(&(_sc)->core_mtx, _name, "EM Core Lock", MTX_DEF)
#define EM_TX_LOCK_INIT(_sc, _name) \
OpenPOWER on IntegriCloud