summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/e1000
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-12-09 14:19:03 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-01-10 09:53:34 +0100
commit75b706fde4cbf82bcd41a1cec319778aa0f8eb2d (patch)
treeea39a351a1f6337b5a5dd6036314693adef5ffe6 /freebsd/sys/dev/e1000
parentVMSTAT(8): Port to RTEMS (diff)
downloadrtems-libbsd-75b706fde4cbf82bcd41a1cec319778aa0f8eb2d.tar.bz2
Update to FreeBSD head 2016-12-10
Git mirror commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c.
Diffstat (limited to 'freebsd/sys/dev/e1000')
-rw-r--r--freebsd/sys/dev/e1000/if_em.c44
-rw-r--r--freebsd/sys/dev/e1000/if_igb.c19
-rw-r--r--freebsd/sys/dev/e1000/if_lem.c175
3 files changed, 54 insertions, 184 deletions
diff --git a/freebsd/sys/dev/e1000/if_em.c b/freebsd/sys/dev/e1000/if_em.c
index fa34dd62..d8c1e5a6 100644
--- a/freebsd/sys/dev/e1000/if_em.c
+++ b/freebsd/sys/dev/e1000/if_em.c
@@ -367,16 +367,10 @@ MODULE_DEPEND(em, netmap, 1, 1, 1);
#define EM_TICKS_TO_USECS(ticks) ((1024 * (ticks) + 500) / 1000)
#define EM_USECS_TO_TICKS(usecs) ((1000 * (usecs) + 512) / 1024)
-#define M_TSO_LEN 66
#define MAX_INTS_PER_SEC 8000
#define DEFAULT_ITR (1000000000/(MAX_INTS_PER_SEC * 256))
-/* Allow common code without TSO */
-#ifndef CSUM_TSO
-#define CSUM_TSO 0
-#endif
-
#define TSO_WORKAROUND 4
static SYSCTL_NODE(_hw, OID_AUTO, em, CTLFLAG_RD, 0, "EM driver parameters");
@@ -1399,15 +1393,9 @@ em_init_locked(struct adapter *adapter)
if_clearhwassist(ifp);
if (if_getcapenable(ifp) & IFCAP_TXCSUM)
if_sethwassistbits(ifp, CSUM_TCP | CSUM_UDP, 0);
- /*
- ** There have proven to be problems with TSO when not
- ** at full gigabit speed, so disable the assist automatically
- ** when at lower speeds. -jfv
- */
- if (if_getcapenable(ifp) & IFCAP_TSO4) {
- if (adapter->link_speed == SPEED_1000)
- if_sethwassistbits(ifp, CSUM_TSO, 0);
- }
+
+ if (if_getcapenable(ifp) & IFCAP_TSO4)
+ if_sethwassistbits(ifp, CSUM_TSO, 0);
/* Configure for OS presence */
em_init_manageability(adapter);
@@ -2415,6 +2403,18 @@ em_update_link_status(struct adapter *adapter)
if (link_check && (adapter->link_active == 0)) {
e1000_get_speed_and_duplex(hw, &adapter->link_speed,
&adapter->link_duplex);
+ /*
+ ** There have proven to be problems with TSO when not
+ ** at full gigabit speed, so disable the assist automatically
+ ** when at lower speeds. -jfv
+ */
+ if (adapter->link_speed != SPEED_1000) {
+ if_sethwassistbits(ifp, 0, CSUM_TSO);
+ if_setcapenablebit(ifp, 0, IFCAP_TSO4);
+ if_setcapabilitiesbit(ifp, 0, IFCAP_TSO4);
+
+ }
+
/* Check if we must disable SPEED_MODE bit on PCI-E */
if ((adapter->link_speed != SPEED_1000) &&
((hw->mac.type == e1000_82571) ||
@@ -5276,6 +5276,8 @@ em_get_wakeup(device_t dev)
case e1000_ich10lan:
case e1000_pchlan:
case e1000_pch2lan:
+ case e1000_pch_lpt:
+ case e1000_pch_spt:
apme_mask = E1000_WUC_APME;
adapter->has_amt = TRUE;
eeprom_data = E1000_READ_REG(&adapter->hw, E1000_WUC);
@@ -5324,7 +5326,7 @@ em_enable_wakeup(device_t dev)
{
struct adapter *adapter = device_get_softc(dev);
if_t ifp = adapter->ifp;
- u32 pmc, ctrl, ctrl_ext, rctl;
+ u32 pmc, ctrl, ctrl_ext, rctl, wuc;
u16 status;
if ((pci_find_cap(dev, PCIY_PMG, &pmc) != 0))
@@ -5334,7 +5336,9 @@ em_enable_wakeup(device_t dev)
ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3);
E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
- E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN);
+ wuc = E1000_READ_REG(&adapter->hw, E1000_WUC);
+ wuc |= E1000_WUC_PME_EN;
+ E1000_WRITE_REG(&adapter->hw, E1000_WUC, wuc);
if ((adapter->hw.mac.type == e1000_ich8lan) ||
(adapter->hw.mac.type == e1000_pchlan) ||
@@ -5365,8 +5369,10 @@ em_enable_wakeup(device_t dev)
E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
}
- if ((adapter->hw.mac.type == e1000_pchlan) ||
- (adapter->hw.mac.type == e1000_pch2lan)) {
+ if ((adapter->hw.mac.type == e1000_pchlan) ||
+ (adapter->hw.mac.type == e1000_pch2lan) ||
+ (adapter->hw.mac.type == e1000_pch_lpt) ||
+ (adapter->hw.mac.type == e1000_pch_spt)) {
if (em_enable_phy_wakeup(adapter))
return;
} else {
diff --git a/freebsd/sys/dev/e1000/if_igb.c b/freebsd/sys/dev/e1000/if_igb.c
index d683b85f..2e9c7259 100644
--- a/freebsd/sys/dev/e1000/if_igb.c
+++ b/freebsd/sys/dev/e1000/if_igb.c
@@ -592,11 +592,20 @@ igb_attach(device_t dev)
error = EIO;
goto err_late;
}
- /* Check its sanity */
- if (!igb_is_valid_ether_addr(adapter->hw.mac.addr)) {
- device_printf(dev, "Invalid MAC address\n");
- error = EIO;
- goto err_late;
+
+ /* Check its sanity */
+ if (!igb_is_valid_ether_addr(adapter->hw.mac.addr)) {
+ if (adapter->vf_ifp) {
+ u8 addr[ETHER_ADDR_LEN];
+ arc4rand(&addr, sizeof(addr), 0);
+ addr[0] &= 0xFE;
+ addr[0] |= 0x02;
+ bcopy(addr, adapter->hw.mac.addr, sizeof(addr));
+ } else {
+ device_printf(dev, "Invalid MAC address\n");
+ error = EIO;
+ goto err_late;
+ }
}
/* Setup OS specific network interface */
diff --git a/freebsd/sys/dev/e1000/if_lem.c b/freebsd/sys/dev/e1000/if_lem.c
index c46c3728..b3da1bdd 100644
--- a/freebsd/sys/dev/e1000/if_lem.c
+++ b/freebsd/sys/dev/e1000/if_lem.c
@@ -41,7 +41,6 @@
*/
// #define BATCH_DISPATCH
// #define NIC_SEND_COMBINING
-// #define NIC_PARAVIRT /* enable virtio-like synchronization */
#include <rtems/bsd/local/opt_inet.h>
#include <rtems/bsd/local/opt_inet6.h>
@@ -488,10 +487,6 @@ lem_attach(device_t dev)
lem_add_rx_process_limit(adapter, "batch_enable",
"driver rx batch", &adapter->batch_enable, 0);
#endif /* BATCH_DISPATCH */
-#ifdef NIC_PARAVIRT
- lem_add_rx_process_limit(adapter, "rx_retries",
- "driver rx retries", &adapter->rx_retries, 0);
-#endif /* NIC_PARAVIRT */
/* Sysctl for setting the interface flow control */
lem_set_flow_cntrl(adapter, "flow_control",
@@ -550,51 +545,16 @@ lem_attach(device_t dev)
*/
adapter->hw.mac.report_tx_early = 1;
-#ifdef NIC_PARAVIRT
- device_printf(dev, "driver supports paravirt, subdev 0x%x\n",
- adapter->hw.subsystem_device_id);
- if (adapter->hw.subsystem_device_id == E1000_PARA_SUBDEV) {
- uint64_t bus_addr;
-
- device_printf(dev, "paravirt support on dev %p\n", adapter);
- tsize = 4096; // XXX one page for the csb
- if (lem_dma_malloc(adapter, tsize, &adapter->csb_mem, BUS_DMA_NOWAIT)) {
- device_printf(dev, "Unable to allocate csb memory\n");
- error = ENOMEM;
- goto err_csb;
- }
- /* Setup the Base of the CSB */
- adapter->csb = (struct paravirt_csb *)adapter->csb_mem.dma_vaddr;
- /* force the first kick */
- adapter->csb->host_need_txkick = 1; /* txring empty */
- adapter->csb->guest_need_rxkick = 1; /* no rx packets */
- bus_addr = adapter->csb_mem.dma_paddr;
- lem_add_rx_process_limit(adapter, "csb_on",
- "enable paravirt.", &adapter->csb->guest_csb_on, 0);
- lem_add_rx_process_limit(adapter, "txc_lim",
- "txc_lim", &adapter->csb->host_txcycles_lim, 1);
-
- /* some stats */
-#define PA_SC(name, var, val) \
- lem_add_rx_process_limit(adapter, name, name, var, val)
- PA_SC("host_need_txkick",&adapter->csb->host_need_txkick, 1);
- PA_SC("host_rxkick_at",&adapter->csb->host_rxkick_at, ~0);
- PA_SC("guest_need_txkick",&adapter->csb->guest_need_txkick, 0);
- PA_SC("guest_need_rxkick",&adapter->csb->guest_need_rxkick, 1);
- PA_SC("tdt_reg_count",&adapter->tdt_reg_count, 0);
- PA_SC("tdt_csb_count",&adapter->tdt_csb_count, 0);
- PA_SC("tdt_int_count",&adapter->tdt_int_count, 0);
- PA_SC("guest_need_kick_count",&adapter->guest_need_kick_count, 0);
- /* tell the host where the block is */
- E1000_WRITE_REG(&adapter->hw, E1000_CSBAH,
- (u32)(bus_addr >> 32));
- E1000_WRITE_REG(&adapter->hw, E1000_CSBAL,
- (u32)bus_addr);
- }
-#endif /* NIC_PARAVIRT */
-
- tsize = roundup2(adapter->num_tx_desc * sizeof(struct e1000_tx_desc),
- EM_DBA_ALIGN);
+ /*
+ * It seems that the descriptor DMA engine on some PCI cards
+ * fetches memory past the end of the last descriptor in the
+ * ring. These reads are problematic when VT-d (DMAR) busdma
+ * is used. Allocate the scratch space to avoid getting
+ * faults from DMAR, by requesting scratch memory for one more
+ * descriptor.
+ */
+ tsize = roundup2((adapter->num_tx_desc + 1) *
+ sizeof(struct e1000_tx_desc), EM_DBA_ALIGN);
/* Allocate Transmit Descriptor ring */
if (lem_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) {
@@ -605,8 +565,11 @@ lem_attach(device_t dev)
adapter->tx_desc_base =
(struct e1000_tx_desc *)adapter->txdma.dma_vaddr;
- rsize = roundup2(adapter->num_rx_desc * sizeof(struct e1000_rx_desc),
- EM_DBA_ALIGN);
+ /*
+ * See comment above txdma allocation for rationale behind +1.
+ */
+ rsize = roundup2((adapter->num_rx_desc + 1) *
+ sizeof(struct e1000_rx_desc), EM_DBA_ALIGN);
/* Allocate Receive Descriptor ring */
if (lem_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) {
@@ -751,11 +714,6 @@ err_hw_init:
err_rx_desc:
lem_dma_free(adapter, &adapter->txdma);
err_tx_desc:
-#ifdef NIC_PARAVIRT
- lem_dma_free(adapter, &adapter->csb_mem);
-err_csb:
-#endif /* NIC_PARAVIRT */
-
err_pci:
if (adapter->ifp != (void *)NULL)
if_free(adapter->ifp);
@@ -843,12 +801,6 @@ lem_detach(device_t dev)
adapter->rx_desc_base = NULL;
}
-#ifdef NIC_PARAVIRT
- if (adapter->csb) {
- lem_dma_free(adapter, &adapter->csb_mem);
- adapter->csb = NULL;
- }
-#endif /* NIC_PARAVIRT */
lem_release_hw_control(adapter);
free(adapter->mta, M_DEVBUF);
EM_TX_LOCK_DESTROY(adapter);
@@ -958,16 +910,6 @@ lem_start_locked(if_t ifp)
}
if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD)
if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0);
-#ifdef NIC_PARAVIRT
- if (if_getdrvflags(ifp) & IFF_DRV_OACTIVE && adapter->csb &&
- adapter->csb->guest_csb_on &&
- !(adapter->csb->guest_need_txkick & 1)) {
- adapter->csb->guest_need_txkick = 1;
- adapter->guest_need_kick_count++;
- // XXX memory barrier
- lem_txeof(adapter); // XXX possibly clear IFF_DRV_OACTIVE
- }
-#endif /* NIC_PARAVIRT */
return;
}
@@ -1815,24 +1757,6 @@ lem_xmit(struct adapter *adapter, struct mbuf **m_headp)
bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-#ifdef NIC_PARAVIRT
- if (adapter->csb) {
- adapter->csb->guest_tdt = i;
- /* XXX memory barrier ? */
- if (adapter->csb->guest_csb_on &&
- !(adapter->csb->host_need_txkick & 1)) {
- /* XXX maybe useless
- * clean the ring. maybe do it before ?
- * maybe a little bit of histeresys ?
- */
- if (adapter->num_tx_desc_avail <= 64) {// XXX
- lem_txeof(adapter);
- }
- return (0);
- }
- }
-#endif /* NIC_PARAVIRT */
-
#ifdef NIC_SEND_COMBINING
if (adapter->sc_enable) {
if (adapter->shadow_tdt & MIT_PENDING_INT) {
@@ -2088,20 +2012,6 @@ lem_local_timer(void *arg)
lem_smartspeed(adapter);
-#ifdef NIC_PARAVIRT
- /* recover space if needed */
- if (adapter->csb && adapter->csb->guest_csb_on &&
- (adapter->watchdog_check == TRUE) &&
- (ticks - adapter->watchdog_time > EM_WATCHDOG) &&
- (adapter->num_tx_desc_avail != adapter->num_tx_desc) ) {
- lem_txeof(adapter);
- /*
- * lem_txeof() normally (except when space in the queue
- * runs low XXX) cleans watchdog_check so that
- * we do not hung.
- */
- }
-#endif /* NIC_PARAVIRT */
/*
* We check the watchdog: the time since
* the last TX descriptor was cleaned.
@@ -3178,12 +3088,6 @@ lem_txeof(struct adapter *adapter)
*/
if (adapter->num_tx_desc_avail > EM_TX_CLEANUP_THRESHOLD) {
if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE);
-#ifdef NIC_PARAVIRT
- if (adapter->csb) { // XXX also csb_on ?
- adapter->csb->guest_need_txkick = 2; /* acked */
- // XXX memory barrier
- }
-#endif /* NIC_PARAVIRT */
if (adapter->num_tx_desc_avail == adapter->num_tx_desc) {
adapter->watchdog_check = FALSE;
return;
@@ -3572,15 +3476,6 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
#ifdef BATCH_DISPATCH
struct mbuf *mh = NULL, *mt = NULL;
#endif /* BATCH_DISPATCH */
-#ifdef NIC_PARAVIRT
- int retries = 0;
- struct paravirt_csb* csb = adapter->csb;
- int csb_mode = csb && csb->guest_csb_on;
-
- //ND("clear guest_rxkick at %d", adapter->next_rx_desc_to_check);
- if (csb_mode && csb->guest_need_rxkick)
- csb->guest_need_rxkick = 0;
-#endif /* NIC_PARAVIRT */
EM_RX_LOCK(adapter);
#ifdef BATCH_DISPATCH
@@ -3598,45 +3493,20 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
}
#endif /* DEV_NETMAP */
-#if 1 // XXX optimization ?
if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
if (done != NULL)
*done = rx_sent;
EM_RX_UNLOCK(adapter);
return (FALSE);
}
-#endif /* 0 */
while (count != 0 && if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
struct mbuf *m = NULL;
status = current_desc->status;
if ((status & E1000_RXD_STAT_DD) == 0) {
-#ifdef NIC_PARAVIRT
- if (csb_mode) {
- /* buffer not ready yet. Retry a few times before giving up */
- if (++retries <= adapter->rx_retries) {
- continue;
- }
- if (csb->guest_need_rxkick == 0) {
- // ND("set guest_rxkick at %d", adapter->next_rx_desc_to_check);
- csb->guest_need_rxkick = 1;
- // XXX memory barrier, status volatile ?
- continue; /* double check */
- }
- }
- /* no buffer ready, give up */
-#endif /* NIC_PARAVIRT */
break;
}
-#ifdef NIC_PARAVIRT
- if (csb_mode) {
- if (csb->guest_need_rxkick)
- // ND("clear again guest_rxkick at %d", adapter->next_rx_desc_to_check);
- csb->guest_need_rxkick = 0;
- retries = 0;
- }
-#endif /* NIC_PARAVIRT */
mp = adapter->rx_buffer_area[i].m_head;
/*
@@ -3761,18 +3631,6 @@ discard:
bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-#ifdef NIC_PARAVIRT
- if (csb_mode) {
- /* the buffer at i has been already replaced by lem_get_buf()
- * so it is safe to set guest_rdt = i and possibly send a kick.
- * XXX see if we can optimize it later.
- */
- csb->guest_rdt = i;
- // XXX memory barrier
- if (i == csb->host_rxkick_at)
- E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
- }
-#endif /* NIC_PARAVIRT */
/* Advance our pointers to the next descriptor. */
if (++i == adapter->num_rx_desc)
i = 0;
@@ -3819,9 +3677,6 @@ discard:
/* Advance the E1000's Receive Queue #0 "Tail Pointer". */
if (--i < 0)
i = adapter->num_rx_desc - 1;
-#ifdef NIC_PARAVIRT
- if (!csb_mode) /* filter out writes */
-#endif /* NIC_PARAVIRT */
E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
if (done != NULL)
*done = rx_sent;