Date: Mon, 1 Jun 2015 18:15:50 +0000 (UTC) From: Sean Bruno <sbruno@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r283890 - projects/em_mq/sys/dev/e1000 Message-ID: <201506011815.t51IFo1f027612@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: sbruno Date: Mon Jun 1 18:15:50 2015 New Revision: 283890 URL: https://svnweb.freebsd.org/changeset/base/283890 Log: Handle Intel Errata notice 12. Reading the ICR can lead to a case where the driver would process a link status or other status and ignore a simultaneous interrupt for an incoming packet. In the msi link handler assume that we should schedule tx/rx processing by setting the ICS to generate a soft interrupt for tx/rx processing to ensure that this race doesn't cause missed packets. Handle Intel Errata notice 3. Always set TARC bit 26. Handle Intel Errata regarding multiqueue behavavior. Always set TARC bits to enable compensation mode of 1/1 for the 2 queues. Always set TARC bits 23, 24 & 25 in multiqueue operation. Add new DB command for debugging to fully reset the adapter when testing. Thanks to Intel for their continuing support of FreeBSD. Submitted by: jfv and erj Modified: projects/em_mq/sys/dev/e1000/if_em.c projects/em_mq/sys/dev/e1000/if_em.h Modified: projects/em_mq/sys/dev/e1000/if_em.c ============================================================================== --- projects/em_mq/sys/dev/e1000/if_em.c Mon Jun 1 18:15:45 2015 (r283889) +++ projects/em_mq/sys/dev/e1000/if_em.c Mon Jun 1 18:15:50 2015 (r283890) @@ -1660,6 +1660,16 @@ em_msix_link(void *arg) } else E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_LINK | E1000_IMS_LSC); + /* + ** Because we must read the ICR for this interrupt + ** it may clear other causes using autoclear, for + ** this reason we simply create a soft interrupt + ** for all these vectors. + */ + if (reg_icr) { + E1000_WRITE_REG(&adapter->hw, + E1000_ICS, adapter->ims); + } return; } @@ -2365,7 +2375,7 @@ em_update_link_status(struct adapter *ad (hw->mac.type == e1000_82572))) { int tarc0; tarc0 = E1000_READ_REG(hw, E1000_TARC(0)); - tarc0 &= ~SPEED_MODE_BIT; + tarc0 &= ~TARC_SPEED_MODE_BIT; E1000_WRITE_REG(hw, E1000_TARC(0), tarc0); } if (bootverbose) @@ -2603,6 +2613,7 @@ em_allocate_msix(struct adapter *adapter ** NOTHING to do with the MSIX vector */ rxr->ims = 1 << (20 + i); + adapter->ims |= rxr->ims; adapter->ivars |= (8 | rxr->msix) << (i * 4); em_last_bind_cpu = CPU_NEXT(em_last_bind_cpu); @@ -2647,6 +2658,7 @@ em_allocate_msix(struct adapter *adapter ** NOTHING to do with the MSIX vector */ txr->ims = 1 << (22 + i); + adapter->ims |= txr->ims; adapter->ivars |= (8 | txr->msix) << (8 + (i * 4)); em_last_bind_cpu = CPU_NEXT(em_last_bind_cpu); @@ -3538,15 +3550,25 @@ em_initialize_transmit_unit(struct adapt if ((adapter->hw.mac.type == e1000_82571) || (adapter->hw.mac.type == e1000_82572)) { tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(0)); - tarc |= SPEED_MODE_BIT; + tarc |= TARC_SPEED_MODE_BIT; E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc); } else if (adapter->hw.mac.type == e1000_80003es2lan) { + /* errata: program both queues to unweighted RR */ tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(0)); tarc |= 1; E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc); tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(1)); tarc |= 1; E1000_WRITE_REG(&adapter->hw, E1000_TARC(1), tarc); + } else if (adapter->hw.mac.type == e1000_82574) { + tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(0)); + tarc |= TARC_ERRATA_BIT; + if ( adapter->num_queues > 1) { + tarc |= (TARC_COMPENSATION_MODE | TARC_MQ_FIX); + E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc); + E1000_WRITE_REG(&adapter->hw, E1000_TARC(1), tarc); + } else + E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc); } adapter->txd_cmd = E1000_TXD_CMD_IFCS; @@ -5970,6 +5992,23 @@ em_enable_vectors_82574(struct adapter * #endif #ifdef DDB +DB_COMMAND(em_reset_dev, em_ddb_reset_dev) +{ + devclass_t dc; + int max_em; + + dc = devclass_find("em"); + max_em = devclass_get_maxunit(dc); + + for (int index = 0; index < (max_em - 1); index++) { + device_t dev; + dev = devclass_get_device(dc, index); + if (device_get_driver(dev) == &em_driver) { + struct adapter *adapter = device_get_softc(dev); + em_init_locked(adapter); + } + } +} DB_COMMAND(em_dump_queue, em_ddb_dump_queue) { devclass_t dc; Modified: projects/em_mq/sys/dev/e1000/if_em.h ============================================================================== --- projects/em_mq/sys/dev/e1000/if_em.h Mon Jun 1 18:15:45 2015 (r283889) +++ projects/em_mq/sys/dev/e1000/if_em.h Mon Jun 1 18:15:50 2015 (r283890) @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2011, Intel Corporation + Copyright (c) 2001-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -215,7 +215,15 @@ */ #define EM_DBA_ALIGN 128 -#define SPEED_MODE_BIT (1<<21) /* On PCI-E MACs only */ +/* + * See Intel 82574 Driver Programming Interface Manual, Section 10.2.6.9 + */ +#define TARC_COMPENSATION_MODE (1 << 7) /* Compensation Mode */ +#define TARC_SPEED_MODE_BIT (1 << 21) /* On PCI-E MACs only */ +#define TARC_MQ_FIX (1 << 23) | \ + (1 << 24) | \ + (1 << 25) /* Handle errata in MQ mode */ +#define TARC_ERRATA_BIT (1 << 26) /* Note from errata on 82574 */ /* PCI Config defines */ #define EM_BAR_TYPE(v) ((v) & EM_BAR_TYPE_MASK)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506011815.t51IFo1f027612>