summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/ixgbe/LICENSE6
-rw-r--r--sys/dev/pci/ixgbe/ixgbe.c810
-rw-r--r--sys/dev/pci/ixgbe/ixgbe.h65
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_82598.c64
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_82598.h2
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_82599.c385
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_82599.h11
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_api.c111
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_api.h10
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_common.c278
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_common.h27
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_mbx.h18
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_netbsd.h4
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_osdep.h9
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_phy.c59
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_phy.h26
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_type.h48
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_vf.c129
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_vf.h15
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_x540.c12
-rw-r--r--sys/dev/pci/ixgbe/ixgbe_x540.h6
-rw-r--r--sys/dev/pci/ixgbe/ixv.c43
22 files changed, 1420 insertions, 718 deletions
diff --git a/sys/dev/pci/ixgbe/LICENSE b/sys/dev/pci/ixgbe/LICENSE
index 07ec728209e..451e59cd9d3 100644
--- a/sys/dev/pci/ixgbe/LICENSE
+++ b/sys/dev/pci/ixgbe/LICENSE
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2010, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,5 +30,5 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: src/sys/dev/ixgbe/LICENSE,v 1.4 2010/03/27 00:21:40 jfv Exp $*/
-/*$NetBSD: LICENSE,v 1.1 2011/08/12 21:55:28 dyoung Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/LICENSE 247822 2013-03-04 23:07:40Z jfv $*/
+/*$NetBSD: LICENSE,v 1.2 2015/04/24 07:00:51 msaitoh Exp $*/
diff --git a/sys/dev/pci/ixgbe/ixgbe.c b/sys/dev/pci/ixgbe/ixgbe.c
index 0e26aed8f82..8a58a9edd12 100644
--- a/sys/dev/pci/ixgbe/ixgbe.c
+++ b/sys/dev/pci/ixgbe/ixgbe.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -58,8 +58,8 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-/*$FreeBSD: head/sys/dev/ixgbe/ixgbe.c 243716 2012-11-30 22:33:21Z jfv $*/
-/*$NetBSD: ixgbe.c,v 1.27 2015/04/14 07:41:52 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe.c 250108 2013-04-30 16:18:29Z luigi $*/
+/*$NetBSD: ixgbe.c,v 1.28 2015/04/24 07:00:51 msaitoh Exp $*/
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -74,7 +74,7 @@ int ixgbe_display_debug_stats = 0;
/*********************************************************************
* Driver version
*********************************************************************/
-char ixgbe_driver_version[] = "2.5.0 - 2";
+char ixgbe_driver_version[] = "2.5.8 - HEAD";
/*********************************************************************
* PCI Device ID Table
@@ -111,7 +111,6 @@ static ixgbe_vendor_info_t ixgbe_vendor_info_array[] =
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_FCOE, 0, 0, 0},
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599EN_SFP, 0, 0, 0},
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_SF_QP, 0, 0, 0},
- {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540T1, 0, 0, 0},
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540T, 0, 0, 0},
/* required last entry */
{0, 0, 0, 0, 0}
@@ -134,15 +133,15 @@ static int ixgbe_detach(device_t, int);
#if 0
static int ixgbe_shutdown(device_t);
#endif
-#if __FreeBSD_version >= 800000
+#if IXGBE_LEGACY_TX
+static void ixgbe_start(struct ifnet *);
+static void ixgbe_start_locked(struct tx_ring *, struct ifnet *);
+#else
static int ixgbe_mq_start(struct ifnet *, struct mbuf *);
static int ixgbe_mq_start_locked(struct ifnet *,
struct tx_ring *, struct mbuf *);
static void ixgbe_qflush(struct ifnet *);
-static void ixgbe_deferred_mq_start(void *, int);
-#else
-static void ixgbe_start(struct ifnet *);
-static void ixgbe_start_locked(struct tx_ring *, struct ifnet *);
+static void ixgbe_deferred_mq_start(void *);
#endif
static int ixgbe_ioctl(struct ifnet *, u_long, void *);
static void ixgbe_ifstop(struct ifnet *, int);
@@ -184,7 +183,7 @@ static void ixgbe_enable_intr(struct adapter *);
static void ixgbe_disable_intr(struct adapter *);
static void ixgbe_update_stats_counters(struct adapter *);
static bool ixgbe_txeof(struct tx_ring *);
-static bool ixgbe_rxeof(struct ix_queue *, int);
+static bool ixgbe_rxeof(struct ix_queue *);
static void ixgbe_rx_checksum(u32, struct mbuf *, u32,
struct ixgbe_hw_stats *);
static void ixgbe_set_promisc(struct adapter *);
@@ -198,10 +197,10 @@ static int ixgbe_set_thermal_test(SYSCTLFN_PROTO);
static int ixgbe_dma_malloc(struct adapter *, bus_size_t,
struct ixgbe_dma_alloc *, int);
static void ixgbe_dma_free(struct adapter *, struct ixgbe_dma_alloc *);
-static void ixgbe_add_rx_process_limit(struct adapter *, const char *,
- const char *, int *, int);
-static u32 ixgbe_tx_ctx_setup(struct tx_ring *, struct mbuf *);
-static bool ixgbe_tso_setup(struct tx_ring *, struct mbuf *, u32 *, u32 *);
+static int ixgbe_tx_ctx_setup(struct tx_ring *,
+ struct mbuf *, u32 *, u32 *);
+static int ixgbe_tso_setup(struct tx_ring *,
+ struct mbuf *, u32 *, u32 *);
static void ixgbe_set_ivar(struct adapter *, u8, u8, s8);
static void ixgbe_configure_ivars(struct adapter *);
static u8 * ixgbe_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
@@ -285,6 +284,10 @@ TUNABLE_INT("hw.ixgbe.max_interrupt_rate", &ixgbe_max_interrupt_rate);
static int ixgbe_rx_process_limit = 256;
TUNABLE_INT("hw.ixgbe.rx_process_limit", &ixgbe_rx_process_limit);
+/* How many packets txeof tries to clean at a time */
+static int ixgbe_tx_process_limit = 256;
+TUNABLE_INT("hw.ixgbe.tx_process_limit", &ixgbe_tx_process_limit);
+
/*
** Smart speed setting, default to on
** this only works as a compile option
@@ -641,11 +644,6 @@ ixgbe_attach(device_t parent, device_t dev, void *aux)
if (ixgbe_setup_interface(dev, adapter) != 0)
goto err_late;
- /* Sysctl for limiting the amount of work done in software interrupts */
- ixgbe_add_rx_process_limit(adapter, "rx_processing_limit",
- "max number of rx packets to process", &adapter->rx_process_limit,
- ixgbe_rx_process_limit);
-
/* Initialize statistics */
ixgbe_update_stats_counters(adapter);
@@ -668,6 +666,9 @@ ixgbe_attach(device_t parent, device_t dev, void *aux)
"PCIE, or x4 PCIE 2 slot is required.\n");
}
+ /* Set an initial default flow control value */
+ adapter->fc = ixgbe_fc_full;
+
/* let hardware know driver is loaded */
ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
ctrl_ext |= IXGBE_CTRL_EXT_DRV_LOAD;
@@ -730,7 +731,7 @@ ixgbe_detach(device_t dev, int flags)
IXGBE_CORE_UNLOCK(adapter);
for (int i = 0; i < adapter->num_queues; i++, que++, txr++) {
-#if __FreeBSD_version >= 800000
+#ifndef IXGBE_LEGACY_TX
softint_disestablish(txr->txq_si);
#endif
softint_disestablish(que->que_si);
@@ -775,13 +776,13 @@ ixgbe_detach(device_t dev, int flags)
evcnt_detach(&adapter->enomem_tx_dma_setup);
evcnt_detach(&adapter->watchdog_events);
evcnt_detach(&adapter->tso_err);
- evcnt_detach(&adapter->tso_tx);
evcnt_detach(&adapter->link_irq);
txr = adapter->tx_rings;
for (int i = 0; i < adapter->num_queues; i++, rxr++, txr++) {
evcnt_detach(&txr->no_desc_avail);
evcnt_detach(&txr->total_packets);
+ evcnt_detach(&txr->tso_tx);
if (i < __arraycount(adapter->stats.mpc)) {
evcnt_detach(&adapter->stats.mpc[i]);
@@ -859,17 +860,6 @@ ixgbe_detach(device_t dev, int flags)
evcnt_detach(&stats->ptc1023);
evcnt_detach(&stats->ptc1522);
- /* FC Stats */
- evcnt_detach(&stats->fccrc);
- evcnt_detach(&stats->fclast);
- if (adapter->hw.mac.type != ixgbe_mac_82598EB) {
- evcnt_detach(&stats->fcoerpdc);
- evcnt_detach(&stats->fcoeprc);
- evcnt_detach(&stats->fcoeptc);
- evcnt_detach(&stats->fcoedwrc);
- evcnt_detach(&stats->fcoedwtc);
- }
-
ixgbe_free_transmit_structures(adapter);
ixgbe_free_receive_structures(adapter);
free(adapter->mta, M_DEVBUF);
@@ -897,7 +887,7 @@ ixgbe_shutdown(device_t dev)
#endif
-#if __FreeBSD_version < 800000
+#ifdef IXGBE_LEGACY_TX
/*********************************************************************
* Transmit entry point
*
@@ -937,7 +927,7 @@ ixgbe_start_locked(struct tx_ring *txr, struct ifnet * ifp)
if (rc == EFBIG) {
struct mbuf *mtmp;
- if ((mtmp = m_defrag(m_head, M_DONTWAIT)) != NULL) {
+ if ((mtmp = m_defrag(m_head, M_NOWAIT)) != NULL) {
m_head = mtmp;
rc = ixgbe_xmit(txr, m_head);
if (rc != 0)
@@ -980,7 +970,8 @@ ixgbe_start(struct ifnet *ifp)
return;
}
-#else
+#else /* ! IXGBE_LEGACY_TX */
+
/*
** Multiqueue Transmit driver
**
@@ -997,7 +988,7 @@ ixgbe_mq_start(struct ifnet *ifp, struct mbuf *m)
if ((m->m_flags & M_FLOWID) != 0)
i = m->m_pkthdr.flowid % adapter->num_queues;
else
- i = curcpu % adapter->num_queues;
+ i = cpu_index(curcpu()) % adapter->num_queues;
txr = &adapter->tx_rings[i];
que = &adapter->queues[i];
@@ -1028,22 +1019,24 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
}
enqueued = 0;
- if (m == NULL) {
- next = drbr_dequeue(ifp, txr->br);
- } else if (drbr_needs_enqueue(ifp, txr->br)) {
- if ((err = drbr_enqueue(ifp, txr->br, m)) != 0)
+ if (m != NULL) {
+ err = drbr_enqueue(ifp, txr->br, m);
+ if (err) {
return (err);
- next = drbr_dequeue(ifp, txr->br);
- } else
- next = m;
+ }
+ }
/* Process the queue */
- while (next != NULL) {
+ while ((next = drbr_peek(ifp, txr->br)) != NULL) {
if ((err = ixgbe_xmit(txr, &next)) != 0) {
- if (next != NULL)
- err = drbr_enqueue(ifp, txr->br, next);
+ if (next == NULL) {
+ drbr_advance(ifp, txr->br);
+ } else {
+ drbr_putback(ifp, txr->br, next);
+ }
break;
}
+ drbr_advance(ifp, txr->br);
enqueued++;
/* Send a copy of the frame to the BPF listener */
bpf_mtap(ifp, next);
@@ -1051,7 +1044,6 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
break;
if (txr->tx_avail < IXGBE_TX_OP_THRESHOLD)
ixgbe_txeof(txr);
- next = drbr_dequeue(ifp, txr->br);
}
if (enqueued > 0) {
@@ -1070,7 +1062,7 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
* Called from a taskqueue to drain queued transmit packets.
*/
static void
-ixgbe_deferred_mq_start(void *arg, int pending)
+ixgbe_deferred_mq_start(void *arg)
{
struct tx_ring *txr = arg;
struct adapter *adapter = txr->adapter;
@@ -1100,7 +1092,7 @@ ixgbe_qflush(struct ifnet *ifp)
}
if_qflush(ifp);
}
-#endif /* __FreeBSD_version >= 800000 */
+#endif /* IXGBE_LEGACY_TX */
static int
ixgbe_ifflags_cb(struct ethercom *ec)
@@ -1140,6 +1132,7 @@ static int
ixgbe_ioctl(struct ifnet * ifp, u_long command, void *data)
{
struct adapter *adapter = ifp->if_softc;
+ struct ixgbe_hw *hw = &adapter->hw;
struct ifcapreq *ifcr = data;
struct ifreq *ifr = data;
int error = 0;
@@ -1174,6 +1167,22 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, void *data)
case SIOCSIFMEDIA:
case SIOCGIFMEDIA:
return ifmedia_ioctl(ifp, ifr, &adapter->media, command);
+ case SIOCGI2C:
+ {
+ struct ixgbe_i2c_req i2c;
+ IOCTL_DEBUGOUT("ioctl: SIOCGI2C (Get I2C Data)");
+ error = copyin(ifr->ifr_data, &i2c, sizeof(i2c));
+ if (error)
+ break;
+ if ((i2c.dev_addr != 0xA0) || (i2c.dev_addr != 0xA2)){
+ error = EINVAL;
+ break;
+ }
+ hw->phy.ops.read_i2c_byte(hw, i2c.offset,
+ i2c.dev_addr, i2c.data);
+ error = copyout(&i2c, ifr->ifr_data, sizeof(i2c));
+ break;
+ }
case SIOCSIFCAP:
/* Layer-4 Rx checksum offload has to be turned on and
* off as a unit.
@@ -1208,6 +1217,8 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, void *data)
}
return 0;
}
+
+ return error;
}
/*********************************************************************
@@ -1466,7 +1477,7 @@ ixgbe_init_locked(struct adapter *adapter)
tmp = IXGBE_LOW_DV(frame);
hw->fc.low_water[0] = IXGBE_BT2KB(tmp);
- adapter->fc = hw->fc.requested_mode = ixgbe_fc_full;
+ hw->fc.requested_mode = adapter->fc;
hw->fc.pause_time = IXGBE_FC_PAUSE;
hw->fc.send_xon = TRUE;
}
@@ -1569,10 +1580,10 @@ ixgbe_handle_que(void *context)
adapter->handleq.ev_count++;
if (ifp->if_flags & IFF_RUNNING) {
- more = ixgbe_rxeof(que, adapter->rx_process_limit);
+ more = ixgbe_rxeof(que);
IXGBE_TX_LOCK(txr);
ixgbe_txeof(txr);
-#if __FreeBSD_version >= 800000
+#ifndef IXGBE_LEGACY_TX
if (!drbr_empty(ifp, txr->br))
ixgbe_mq_start_locked(ifp, txr, NULL);
#else
@@ -1622,7 +1633,7 @@ ixgbe_legacy_irq(void *arg)
}
if ((ifp->if_flags & IFF_RUNNING) != 0) {
- more_rx = ixgbe_rxeof(que, adapter->rx_process_limit);
+ more_rx = ixgbe_rxeof(que);
IXGBE_TX_LOCK(txr);
do {
@@ -1676,7 +1687,7 @@ ixgbe_msix_que(void *arg)
ixgbe_disable_queue(adapter, que->msix);
++que->irqs;
- more_rx = ixgbe_rxeof(que, adapter->rx_process_limit);
+ more_rx = ixgbe_rxeof(que);
IXGBE_TX_LOCK(txr);
more_tx = ixgbe_txeof(txr);
@@ -1685,7 +1696,7 @@ ixgbe_msix_que(void *arg)
** has anything queued the task gets
** scheduled to handle it.
*/
-#if __FreeBSD_version < 800000
+#ifdef IXGBE_LEGACY_TX
if (!IFQ_IS_EMPTY(&adapter->ifp->if_snd))
#else
if (!drbr_empty(adapter->ifp, txr->br))
@@ -1808,11 +1819,11 @@ ixgbe_msix_link(void *arg)
/* Check for over temp condition */
if ((hw->mac.type == ixgbe_mac_X540) &&
- (reg_eicr & IXGBE_EICR_GPI_SDP0)) {
+ (reg_eicr & IXGBE_EICR_TS)) {
device_printf(adapter->dev, "\nCRITICAL: OVER TEMP!! "
"PHY IS SHUT DOWN!!\n");
device_printf(adapter->dev, "System shutdown required\n");
- IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0);
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_TS);
}
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
@@ -1852,7 +1863,7 @@ ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr)
ifmr->ifm_active |= IFM_100_TX | IFM_FDX;
break;
case IXGBE_LINK_SPEED_1GB_FULL:
- ifmr->ifm_active |= adapter->optics | IFM_FDX;
+ ifmr->ifm_active |= IFM_1000_SX | IFM_FDX;
break;
case IXGBE_LINK_SPEED_10GB_FULL:
ifmr->ifm_active |= adapter->optics | IFM_FDX;
@@ -1913,9 +1924,8 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf *m_head)
struct adapter *adapter = txr->adapter;
struct ethercom *ec = &adapter->osdep.ec;
u32 olinfo_status = 0, cmd_type_len;
- u32 paylen = 0;
int i, j, error;
- int first, last = 0;
+ int first;
bus_dmamap_t map;
struct ixgbe_tx_buf *txbuf;
union ixgbe_adv_tx_desc *txd = NULL;
@@ -1942,24 +1952,31 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf *m_head)
error = bus_dmamap_load_mbuf(txr->txtag->dt_dmat, map,
m_head, BUS_DMA_NOWAIT);
- switch (error) {
- case EAGAIN:
- adapter->eagain_tx_dma_setup.ev_count++;
- return EAGAIN;
- case ENOMEM:
- adapter->enomem_tx_dma_setup.ev_count++;
- return EAGAIN;
- case EFBIG:
- adapter->efbig_tx_dma_setup.ev_count++;
- return error;
- case EINVAL:
- adapter->einval_tx_dma_setup.ev_count++;
- return error;
- default:
- adapter->other_tx_dma_setup.ev_count++;
- return error;
- case 0:
- break;
+ if (__predict_false(error)) {
+
+ switch (error) {
+ case EAGAIN:
+ adapter->eagain_tx_dma_setup.ev_count++;
+ return EAGAIN;
+ case ENOMEM:
+ adapter->enomem_tx_dma_setup.ev_count++;
+ return EAGAIN;
+ case EFBIG:
+ /*
+ * XXX Try it again?
+ * do m_defrag() and retry bus_dmamap_load_mbuf().
+ */
+ adapter->efbig_tx_dma_setup.ev_count++;
+ return error;
+ case EINVAL:
+ adapter->einval_tx_dma_setup.ev_count++;
+ return error;
+ default:
+ adapter->other_tx_dma_setup.ev_count++;
+ return error;
+ case 0:
+ break;
+ }
}
/* Make certain there are enough descriptors */
@@ -1971,28 +1988,12 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf *m_head)
/*
** Set up the appropriate offload context
- ** this becomes the first descriptor of
- ** a packet.
+ ** this will consume the first descriptor
*/
- if (m_head->m_pkthdr.csum_flags & (M_CSUM_TSOv4|M_CSUM_TSOv6)) {
- if (ixgbe_tso_setup(txr, m_head, &paylen, &olinfo_status)) {
- cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
- olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8;
- olinfo_status |= paylen << IXGBE_ADVTXD_PAYLEN_SHIFT;
- ++adapter->tso_tx.ev_count;
- } else {
- ++adapter->tso_err.ev_count;
- /* XXX unload DMA map! --dyoung */
- return ENXIO;
- }
- } else
- olinfo_status |= ixgbe_tx_ctx_setup(txr, m_head);
-
-#ifdef IXGBE_IEEE1588
- /* This is changing soon to an mtag detection */
- if (we detect this mbuf has a TSTAMP mtag)
- cmd_type_len |= IXGBE_ADVTXD_MAC_TSTAMP;
-#endif
+ error = ixgbe_tx_ctx_setup(txr, m_head, &cmd_type_len, &olinfo_status);
+ if (__predict_false(error)) {
+ return (error);
+ }
#ifdef IXGBE_FDIR
/* Do the flow director magic */
@@ -2004,10 +2005,6 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf *m_head)
}
}
#endif
- /* Record payload length */
- if (paylen == 0)
- olinfo_status |= m_head->m_pkthdr.len <<
- IXGBE_ADVTXD_PAYLEN_SHIFT;
i = txr->next_avail_desc;
for (j = 0; j < map->dm_nsegs; j++) {
@@ -2023,13 +2020,9 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf *m_head)
txd->read.cmd_type_len = htole32(txr->txd_cmd |
cmd_type_len |seglen);
txd->read.olinfo_status = htole32(olinfo_status);
- last = i; /* descriptor that will get completion IRQ */
- if (++i == adapter->num_tx_desc)
+ if (++i == txr->num_desc)
i = 0;
-
- txbuf->m_head = NULL;
- txbuf->eop_index = -1;
}
txd->read.cmd_type_len |=
@@ -2038,15 +2031,20 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf *m_head)
txr->next_avail_desc = i;
txbuf->m_head = m_head;
- /* Swap the dma map between the first and last descriptor */
+ /*
+ ** Here we swap the map so the last descriptor,
+ ** which gets the completion interrupt has the
+ ** real map, and the first descriptor gets the
+ ** unused map from this descriptor.
+ */
txr->tx_buffers[first].map = txbuf->map;
txbuf->map = map;
bus_dmamap_sync(txr->txtag->dt_dmat, map, 0, m_head->m_pkthdr.len,
BUS_DMASYNC_PREWRITE);
- /* Set the index of the descriptor that will be marked done */
+ /* Set the EOP descriptor that will be marked done */
txbuf = &txr->tx_buffers[first];
- txbuf->eop_index = last;
+ txbuf->eop = txd;
ixgbe_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
@@ -2063,12 +2061,28 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf *m_head)
static void
ixgbe_set_promisc(struct adapter *adapter)
{
+ struct ether_multi *enm;
+ struct ether_multistep step;
u_int32_t reg_rctl;
+ struct ethercom *ec = &adapter->osdep.ec;
struct ifnet *ifp = adapter->ifp;
+ int mcnt = 0;
reg_rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
reg_rctl &= (~IXGBE_FCTRL_UPE);
- reg_rctl &= (~IXGBE_FCTRL_MPE);
+ if (ifp->if_flags & IFF_ALLMULTI)
+ mcnt = MAX_NUM_MULTICAST_ADDRESSES;
+ else {
+ ETHER_FIRST_MULTI(step, ec, enm);
+ while (enm != NULL) {
+ if (mcnt == MAX_NUM_MULTICAST_ADDRESSES)
+ break;
+ mcnt++;
+ ETHER_NEXT_MULTI(step, enm);
+ }
+ }
+ if (mcnt < MAX_NUM_MULTICAST_ADDRESSES)
+ reg_rctl &= (~IXGBE_FCTRL_MPE);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_rctl);
if (ifp->if_flags & IFF_PROMISC) {
@@ -2109,24 +2123,13 @@ ixgbe_set_multi(struct adapter *adapter)
bzero(mta, sizeof(u8) * IXGBE_ETH_LENGTH_OF_ADDRESS *
MAX_NUM_MULTICAST_ADDRESSES);
- fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
- fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
- if (ifp->if_flags & IFF_PROMISC)
- fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
- else if (ifp->if_flags & IFF_ALLMULTI) {
- fctrl |= IXGBE_FCTRL_MPE;
- fctrl &= ~IXGBE_FCTRL_UPE;
- } else
- fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
-
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl);
-
+ ifp->if_flags &= ~IFF_ALLMULTI;
ETHER_FIRST_MULTI(step, ec, enm);
while (enm != NULL) {
- if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
- ETHER_ADDR_LEN) != 0) {
- fctrl |= IXGBE_FCTRL_MPE;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl);
+ if ((mcnt == MAX_NUM_MULTICAST_ADDRESSES) ||
+ (memcmp(enm->enm_addrlo, enm->enm_addrhi,
+ ETHER_ADDR_LEN) != 0)) {
+ ifp->if_flags |= IFF_ALLMULTI;
break;
}
bcopy(enm->enm_addrlo,
@@ -2136,9 +2139,21 @@ ixgbe_set_multi(struct adapter *adapter)
ETHER_NEXT_MULTI(step, enm);
}
- update_ptr = mta;
- ixgbe_update_mc_addr_list(&adapter->hw,
- update_ptr, mcnt, ixgbe_mc_array_itr, TRUE);
+ fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
+ fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
+ if (ifp->if_flags & IFF_PROMISC)
+ fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
+ else if (ifp->if_flags & IFF_ALLMULTI) {
+ fctrl |= IXGBE_FCTRL_MPE;
+ }
+
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl);
+
+ if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) {
+ update_ptr = mta;
+ ixgbe_update_mc_addr_list(&adapter->hw,
+ update_ptr, mcnt, ixgbe_mc_array_itr, TRUE);
+ }
return;
}
@@ -2372,7 +2387,7 @@ ixgbe_setup_optics(struct adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
int layer;
-
+
layer = ixgbe_get_supported_physical_layer(hw);
if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T) {
@@ -2425,14 +2440,14 @@ ixgbe_setup_optics(struct adapter *adapter)
static int
ixgbe_allocate_legacy(struct adapter *adapter, const struct pci_attach_args *pa)
{
- device_t dev = adapter->dev;
+ device_t dev = adapter->dev;
struct ix_queue *que = adapter->queues;
-#if __FreeBSD_version >= 800000
+#ifndef IXGBE_LEGACY_TX
struct tx_ring *txr = adapter->tx_rings;
#endif
char intrbuf[PCI_INTRSTR_LEN];
#if 0
- int rid = 0;
+ int rid = 0;
/* MSI RID at 1 */
if (adapter->msix == 1)
@@ -2453,7 +2468,7 @@ ixgbe_allocate_legacy(struct adapter *adapter, const struct pci_attach_args *pa)
* Try allocating a fast interrupt and the associated deferred
* processing contexts.
*/
-#if __FreeBSD_version >= 800000
+#ifndef IXGBE_LEGACY_TX
txr->txq_si = softint_establish(SOFTINT_NET, ixgbe_deferred_mq_start,
txr);
#endif
@@ -2550,7 +2565,7 @@ ixgbe_allocate_msix(struct adapter *adapter, const struct pci_attach_args *pa)
if (adapter->num_queues > 1)
bus_bind_intr(dev, que->res, i);
-#if __FreeBSD_version >= 800000
+#ifndef IXGBE_LEGACY_TX
txr->txq_si = softint_establish(SOFTINT_NET,
ixgbe_deferred_mq_start, txr);
#endif
@@ -2818,7 +2833,7 @@ ixgbe_setup_interface(device_t dev, struct adapter *adapter)
ifp->if_softc = adapter;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = ixgbe_ioctl;
-#if __FreeBSD_version >= 800000
+#ifndef IXGBE_LEGACY_TX
ifp->if_transmit = ixgbe_mq_start;
ifp->if_qflush = ixgbe_qflush;
#else
@@ -2903,7 +2918,7 @@ ixgbe_config_link(struct adapter *adapter)
kpreempt_enable();
} else {
if (hw->mac.ops.check_link)
- err = ixgbe_check_link(hw, &autoneg,
+ err = ixgbe_check_link(hw, &adapter->link_speed,
&adapter->link_up, FALSE);
if (err)
goto out;
@@ -2916,8 +2931,8 @@ ixgbe_config_link(struct adapter *adapter)
if (err)
goto out;
if (hw->mac.ops.setup_link)
- err = hw->mac.ops.setup_link(hw, autoneg,
- negotiate, adapter->link_up);
+ err = hw->mac.ops.setup_link(hw,
+ autoneg, adapter->link_up);
}
out:
return;
@@ -3065,6 +3080,7 @@ ixgbe_allocate_queues(struct adapter *adapter)
txr = &adapter->tx_rings[i];
txr->adapter = adapter;
txr->me = i;
+ txr->num_desc = adapter->num_tx_desc;
/* Initialize the TX side lock */
snprintf(txr->mtx_name, sizeof(txr->mtx_name), "%s:tx(%d)",
@@ -3088,7 +3104,7 @@ ixgbe_allocate_queues(struct adapter *adapter)
error = ENOMEM;
goto err_tx_desc;
}
-#if __FreeBSD_version >= 800000
+#ifndef IXGBE_LEGACY_TX
/* Allocate a buf ring */
txr->br = buf_ring_alloc(IXGBE_BR_SIZE, M_DEVBUF,
M_WAITOK, &txr->tx_mtx);
@@ -3111,6 +3127,7 @@ ixgbe_allocate_queues(struct adapter *adapter)
/* Set up some basics */
rxr->adapter = adapter;
rxr->me = i;
+ rxr->num_desc = adapter->num_rx_desc;
/* Initialize the RX side lock */
snprintf(rxr->mtx_name, sizeof(rxr->mtx_name), "%s:rx(%d)",
@@ -3251,7 +3268,7 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr)
/* Free any existing tx buffers. */
txbuf = txr->tx_buffers;
- for (i = 0; i < adapter->num_tx_desc; i++, txbuf++) {
+ for (i = 0; i < txr->num_desc; i++, txbuf++) {
if (txbuf->m_head != NULL) {
bus_dmamap_sync(txr->txtag->dt_dmat, txbuf->map,
0, txbuf->m_head->m_pkthdr.len,
@@ -3276,8 +3293,8 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr)
netmap_load_map(txr->txtag, txbuf->map, NMB(slot + si));
}
#endif /* DEV_NETMAP */
- /* Clear the EOP index */
- txbuf->eop_index = -1;
+ /* Clear the EOP descriptor pointer */
+ txbuf->eop = NULL;
}
#ifdef IXGBE_FDIR
@@ -3331,7 +3348,7 @@ ixgbe_initialize_transmit_units(struct adapter *adapter)
(tdba & 0x00000000ffffffffULL));
IXGBE_WRITE_REG(hw, IXGBE_TDBAH(i), (tdba >> 32));
IXGBE_WRITE_REG(hw, IXGBE_TDLEN(i),
- adapter->num_tx_desc * sizeof(struct ixgbe_legacy_tx_desc));
+ adapter->num_tx_desc * sizeof(union ixgbe_adv_tx_desc));
/* Setup the HW Tx Head and Tail descriptor pointers */
IXGBE_WRITE_REG(hw, IXGBE_TDH(i), 0);
@@ -3341,6 +3358,9 @@ ixgbe_initialize_transmit_units(struct adapter *adapter)
txr->txd_cmd = IXGBE_TXD_CMD_IFCS;
txr->queue_status = IXGBE_QUEUE_IDLE;
+ /* Set the processing limit */
+ txr->process_limit = ixgbe_tx_process_limit;
+
/* Disable Head Writeback */
switch (hw->mac.type) {
case ixgbe_mac_82598EB:
@@ -3438,7 +3458,7 @@ ixgbe_free_transmit_buffers(struct tx_ring *txr)
tx_buffer->map = NULL;
}
}
-#if __FreeBSD_version >= 800000
+#ifndef IXGBE_LEGACY_TX
if (txr->br != NULL)
buf_ring_free(txr->br, M_DEVBUF);
#endif
@@ -3455,42 +3475,51 @@ ixgbe_free_transmit_buffers(struct tx_ring *txr)
/*********************************************************************
*
- * Advanced Context Descriptor setup for VLAN or L4 CSUM
+ * Advanced Context Descriptor setup for VLAN, CSUM or TSO
*
**********************************************************************/
-static u32
-ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp)
+static int
+ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp,
+ u32 *cmd_type_len, u32 *olinfo_status)
{
struct m_tag *mtag;
struct adapter *adapter = txr->adapter;
struct ethercom *ec = &adapter->osdep.ec;
struct ixgbe_adv_tx_context_desc *TXD;
- struct ixgbe_tx_buf *tx_buffer;
- u32 olinfo = 0, vlan_macip_lens = 0, type_tucmd_mlhl = 0;
struct ether_vlan_header *eh;
struct ip ip;
struct ip6_hdr ip6;
- int ehdrlen, ip_hlen = 0;
+ u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0;
+ int ehdrlen, ip_hlen = 0;
u16 etype;
u8 ipproto __diagused = 0;
- bool offload;
- int ctxd = txr->next_avail_desc;
- u16 vtag = 0;
+ int offload = TRUE;
+ int ctxd = txr->next_avail_desc;
+ u16 vtag = 0;
+
+ /* First check if TSO is to be used */
+ if (mp->m_pkthdr.csum_flags & (M_CSUM_TSOv4|M_CSUM_TSOv6))
+ return (ixgbe_tso_setup(txr, mp, cmd_type_len, olinfo_status));
- offload = ((mp->m_pkthdr.csum_flags & M_CSUM_OFFLOAD) != 0);
+ if ((mp->m_pkthdr.csum_flags & M_CSUM_OFFLOAD) == 0)
+ offload = FALSE;
- tx_buffer = &txr->tx_buffers[ctxd];
+ /* Indicate the whole packet as payload when not doing TSO */
+ *olinfo_status |= mp->m_pkthdr.len << IXGBE_ADVTXD_PAYLEN_SHIFT;
+
+ /* Now ready a context descriptor */
TXD = (struct ixgbe_adv_tx_context_desc *) &txr->tx_base[ctxd];
/*
** In advanced descriptors the vlan tag must
- ** be placed into the descriptor itself.
+ ** be placed into the context descriptor. Hence
+ ** we need to make one even if not doing offloads.
*/
if ((mtag = VLAN_OUTPUT_TAG(ec, mp)) != NULL) {
vtag = htole16(VLAN_TAG_VALUE(mtag) & 0xffff);
vlan_macip_lens |= (vtag << IXGBE_ADVTXD_VLAN_SHIFT);
- } else if (!offload)
+ } else if (offload == FALSE) /* ... no offload to do */
return 0;
/*
@@ -3538,37 +3567,34 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp)
}
if ((mp->m_pkthdr.csum_flags & M_CSUM_IPv4) != 0)
- olinfo |= IXGBE_TXD_POPTS_IXSM << 8;
+ *olinfo_status |= IXGBE_TXD_POPTS_IXSM << 8;
vlan_macip_lens |= ip_hlen;
type_tucmd_mlhl |= IXGBE_ADVTXD_DCMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT;
if (mp->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_TCPv6)) {
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP;
- olinfo |= IXGBE_TXD_POPTS_TXSM << 8;
+ *olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8;
KASSERT(ipproto == IPPROTO_TCP);
} else if (mp->m_pkthdr.csum_flags & (M_CSUM_UDPv4|M_CSUM_UDPv6)) {
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_UDP;
- olinfo |= IXGBE_TXD_POPTS_TXSM << 8;
+ *olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8;
KASSERT(ipproto == IPPROTO_UDP);
}
/* Now copy bits into descriptor */
- TXD->vlan_macip_lens |= htole32(vlan_macip_lens);
- TXD->type_tucmd_mlhl |= htole32(type_tucmd_mlhl);
+ TXD->vlan_macip_lens = htole32(vlan_macip_lens);
+ TXD->type_tucmd_mlhl = htole32(type_tucmd_mlhl);
TXD->seqnum_seed = htole32(0);
TXD->mss_l4len_idx = htole32(0);
- tx_buffer->m_head = NULL;
- tx_buffer->eop_index = -1;
-
/* We've consumed the first desc, adjust counters */
- if (++ctxd == adapter->num_tx_desc)
+ if (++ctxd == txr->num_desc)
ctxd = 0;
txr->next_avail_desc = ctxd;
--txr->tx_avail;
- return olinfo;
+ return 0;
}
/**********************************************************************
@@ -3577,17 +3603,16 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp)
* adapters using advanced tx descriptors
*
**********************************************************************/
-static bool
-ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen,
- u32 *olinfo_status)
+static int
+ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp,
+ u32 *cmd_type_len, u32 *olinfo_status)
{
struct m_tag *mtag;
struct adapter *adapter = txr->adapter;
struct ethercom *ec = &adapter->osdep.ec;
struct ixgbe_adv_tx_context_desc *TXD;
- struct ixgbe_tx_buf *tx_buffer;
u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0;
- u32 mss_l4len_idx = 0, len;
+ u32 mss_l4len_idx = 0, paylen;
u16 vtag = 0, eh_type;
int ctxd, ehdrlen, ip_hlen, tcp_hlen;
struct ether_vlan_header *eh;
@@ -3613,18 +3638,15 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen,
eh_type = eh->evl_encap_proto;
}
- /* Ensure we have at least the IP+TCP header in the first mbuf. */
- len = ehdrlen + sizeof(struct tcphdr);
switch (ntohs(eh_type)) {
#ifdef INET6
case ETHERTYPE_IPV6:
- if (mp->m_len < len + sizeof(struct ip6_hdr))
- return FALSE;
ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
/* XXX-BZ For now we do not pretend to support ext. hdrs. */
if (ip6->ip6_nxt != IPPROTO_TCP)
- return FALSE;
+ return (ENXIO);
ip_hlen = sizeof(struct ip6_hdr);
+ ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
th = (struct tcphdr *)((char *)ip6 + ip_hlen);
th->th_sum = in6_cksum_phdr(&ip6->ip6_src,
&ip6->ip6_dst, 0, htonl(IPPROTO_TCP));
@@ -3633,11 +3655,9 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen,
#endif
#ifdef INET
case ETHERTYPE_IP:
- if (mp->m_len < len + sizeof(struct ip))
- return FALSE;
ip = (struct ip *)(mp->m_data + ehdrlen);
if (ip->ip_p != IPPROTO_TCP)
- return FALSE;
+ return (ENXIO);
ip->ip_sum = 0;
ip_hlen = ip->ip_hl << 2;
th = (struct tcphdr *)((char *)ip + ip_hlen);
@@ -3655,13 +3675,12 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen,
}
ctxd = txr->next_avail_desc;
- tx_buffer = &txr->tx_buffers[ctxd];
TXD = (struct ixgbe_adv_tx_context_desc *) &txr->tx_base[ctxd];
tcp_hlen = th->th_off << 2;
/* This is used in the transmit desc in encap */
- *paylen = mp->m_pkthdr.len - ehdrlen - ip_hlen - tcp_hlen;
+ paylen = mp->m_pkthdr.len - ehdrlen - ip_hlen - tcp_hlen;
/* VLAN MACLEN IPLEN */
if ((mtag = VLAN_OUTPUT_TAG(ec, mp)) != NULL) {
@@ -3671,12 +3690,12 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen,
vlan_macip_lens |= ehdrlen << IXGBE_ADVTXD_MACLEN_SHIFT;
vlan_macip_lens |= ip_hlen;
- TXD->vlan_macip_lens |= htole32(vlan_macip_lens);
+ TXD->vlan_macip_lens = htole32(vlan_macip_lens);
/* ADV DTYPE TUCMD */
type_tucmd_mlhl |= IXGBE_ADVTXD_DCMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT;
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP;
- TXD->type_tucmd_mlhl |= htole32(type_tucmd_mlhl);
+ TXD->type_tucmd_mlhl = htole32(type_tucmd_mlhl);
/* MSS L4LEN IDX */
mss_l4len_idx |= (mp->m_pkthdr.segsz << IXGBE_ADVTXD_MSS_SHIFT);
@@ -3684,15 +3703,17 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen,
TXD->mss_l4len_idx = htole32(mss_l4len_idx);
TXD->seqnum_seed = htole32(0);
- tx_buffer->m_head = NULL;
- tx_buffer->eop_index = -1;
- if (++ctxd == adapter->num_tx_desc)
+ if (++ctxd == txr->num_desc)
ctxd = 0;
txr->tx_avail--;
txr->next_avail_desc = ctxd;
- return TRUE;
+ *cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
+ *olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8;
+ *olinfo_status |= paylen << IXGBE_ADVTXD_PAYLEN_SHIFT;
+ ++txr->tso_tx.ev_count;
+ return (0);
}
#ifdef IXGBE_FDIR
@@ -3781,11 +3802,12 @@ ixgbe_atr(struct tx_ring *txr, struct mbuf *mp)
static bool
ixgbe_txeof(struct tx_ring *txr)
{
- struct adapter *adapter = txr->adapter;
- struct ifnet *ifp = adapter->ifp;
- u32 first, last, done, processed;
- struct ixgbe_tx_buf *tx_buffer;
- struct ixgbe_legacy_tx_desc *tx_desc, *eop_desc;
+ struct adapter *adapter = txr->adapter;
+ struct ifnet *ifp = adapter->ifp;
+ u32 work, processed = 0;
+ u16 limit = txr->process_limit;
+ struct ixgbe_tx_buf *buf;
+ union ixgbe_adv_tx_desc *txd;
struct timeval now, elapsed;
KASSERT(mutex_owned(&txr->tx_mtx));
@@ -3794,9 +3816,7 @@ ixgbe_txeof(struct tx_ring *txr)
if (ifp->if_capenable & IFCAP_NETMAP) {
struct netmap_adapter *na = NA(ifp);
struct netmap_kring *kring = &na->tx_rings[txr->me];
-
- tx_desc = (struct ixgbe_legacy_tx_desc *)txr->tx_base;
-
+ txd = txr->tx_base;
bus_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
BUS_DMASYNC_POSTREAD);
/*
@@ -3819,96 +3839,108 @@ ixgbe_txeof(struct tx_ring *txr)
*/
if (!netmap_mitigate ||
(kring->nr_kflags < kring->nkr_num_slots &&
- tx_desc[kring->nr_kflags].upper.fields.status & IXGBE_TXD_STAT_DD)) {
- kring->nr_kflags = kring->nkr_num_slots;
- selwakeuppri(&na->tx_rings[txr->me].si, PI_NET);
- IXGBE_TX_UNLOCK(txr);
- IXGBE_CORE_LOCK(adapter);
- selwakeuppri(&na->tx_si, PI_NET);
- IXGBE_CORE_UNLOCK(adapter);
- IXGBE_TX_LOCK(txr);
+ txd[kring->nr_kflags].wb.status & IXGBE_TXD_STAT_DD)) {
+ netmap_tx_irq(ifp, txr->me |
+ (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT));
}
return FALSE;
}
#endif /* DEV_NETMAP */
- if (txr->tx_avail == adapter->num_tx_desc) {
+ if (txr->tx_avail == txr->num_desc) {
txr->queue_status = IXGBE_QUEUE_IDLE;
return false;
}
- processed = 0;
- first = txr->next_to_clean;
- tx_buffer = &txr->tx_buffers[first];
- /* For cleanup we just use legacy struct */
- tx_desc = (struct ixgbe_legacy_tx_desc *)&txr->tx_base[first];
- last = tx_buffer->eop_index;
- if (last == -1)
- return false;
- eop_desc = (struct ixgbe_legacy_tx_desc *)&txr->tx_base[last];
-
- /*
- ** Get the index of the first descriptor
- ** BEYOND the EOP and call that 'done'.
- ** I do this so the comparison in the
- ** inner while loop below can be simple
- */
- if (++last == adapter->num_tx_desc) last = 0;
- done = last;
-
+ /* Get work starting point */
+ work = txr->next_to_clean;
+ buf = &txr->tx_buffers[work];
+ txd = &txr->tx_base[work];
+ work -= txr->num_desc; /* The distance to ring end */
ixgbe_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
BUS_DMASYNC_POSTREAD);
- /*
- ** Only the EOP descriptor of a packet now has the DD
- ** bit set, this is what we look for...
- */
- while (eop_desc->upper.fields.status & IXGBE_TXD_STAT_DD) {
- /* We clean the range of the packet */
- while (first != done) {
- tx_desc->upper.data = 0;
- tx_desc->lower.data = 0;
- tx_desc->buffer_addr = 0;
- ++txr->tx_avail;
- ++processed;
+ do {
+ union ixgbe_adv_tx_desc *eop= buf->eop;
+ if (eop == NULL) /* No work */
+ break;
+
+ if ((eop->wb.status & IXGBE_TXD_STAT_DD) == 0)
+ break; /* I/O not complete */
- if (tx_buffer->m_head) {
+ if (buf->m_head) {
+ txr->bytes +=
+ buf->m_head->m_pkthdr.len;
+ bus_dmamap_sync(txr->txtag->dt_dmat,
+ buf->map,
+ 0, buf->m_head->m_pkthdr.len,
+ BUS_DMASYNC_POSTWRITE);
+ ixgbe_dmamap_unload(txr->txtag,
+ buf->map);
+ m_freem(buf->m_head);
+ buf->m_head = NULL;
+ /*
+ * NetBSD: Don't override buf->map with NULL here.
+ * It'll panic when a ring runs one lap around.
+ */
+ }
+ buf->eop = NULL;
+ ++txr->tx_avail;
+
+ /* We clean the range if multi segment */
+ while (txd != eop) {
+ ++txd;
+ ++buf;
+ ++work;
+ /* wrap the ring? */
+ if (__predict_false(!work)) {
+ work -= txr->num_desc;
+ buf = txr->tx_buffers;
+ txd = txr->tx_base;
+ }
+ if (buf->m_head) {
txr->bytes +=
- tx_buffer->m_head->m_pkthdr.len;
+ buf->m_head->m_pkthdr.len;
bus_dmamap_sync(txr->txtag->dt_dmat,
- tx_buffer->map,
- 0, tx_buffer->m_head->m_pkthdr.len,
+ buf->map,
+ 0, buf->m_head->m_pkthdr.len,
BUS_DMASYNC_POSTWRITE);
- ixgbe_dmamap_unload(txr->txtag, tx_buffer->map);
- m_freem(tx_buffer->m_head);
- tx_buffer->m_head = NULL;
+ ixgbe_dmamap_unload(txr->txtag,
+ buf->map);
+ m_freem(buf->m_head);
+ buf->m_head = NULL;
+ /*
+ * NetBSD: Don't override buf->map with NULL
+ * here. It'll panic when a ring runs one lap
+ * around.
+ */
}
- tx_buffer->eop_index = -1;
- getmicrotime(&txr->watchdog_time);
-
- if (++first == adapter->num_tx_desc)
- first = 0;
+ ++txr->tx_avail;
+ buf->eop = NULL;
- tx_buffer = &txr->tx_buffers[first];
- tx_desc =
- (struct ixgbe_legacy_tx_desc *)&txr->tx_base[first];
}
++txr->packets;
+ ++processed;
++ifp->if_opackets;
- /* See if there is more work now */
- last = tx_buffer->eop_index;
- if (last != -1) {
- eop_desc =
- (struct ixgbe_legacy_tx_desc *)&txr->tx_base[last];
- /* Get next done point */
- if (++last == adapter->num_tx_desc) last = 0;
- done = last;
- } else
- break;
- }
+ getmicrotime(&txr->watchdog_time);
+
+ /* Try the next packet */
+ ++txd;
+ ++buf;
+ ++work;
+ /* reset with a wrap */
+ if (__predict_false(!work)) {
+ work -= txr->num_desc;
+ buf = txr->tx_buffers;
+ txd = txr->tx_base;
+ }
+ prefetch(txd);
+ } while (__predict_true(--limit));
+
ixgbe_dmamap_sync(txr->txdma.dma_tag, txr->txdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- txr->next_to_clean = first;
+ work += txr->num_desc;
+ txr->next_to_clean = work;
/*
** Watchdog calculation, we know there's
@@ -3921,7 +3953,7 @@ ixgbe_txeof(struct tx_ring *txr)
if (!processed && tvtohz(&elapsed) > IXGBE_WATCHDOG)
txr->queue_status = IXGBE_QUEUE_HUNG;
- if (txr->tx_avail == adapter->num_tx_desc) {
+ if (txr->tx_avail == txr->num_desc) {
txr->queue_status = IXGBE_QUEUE_IDLE;
return false;
}
@@ -3949,29 +3981,31 @@ ixgbe_refresh_mbufs(struct rx_ring *rxr, int limit)
i = j = rxr->next_to_refresh;
/* Control the loop with one beyond */
- if (++j == adapter->num_rx_desc)
+ if (++j == rxr->num_desc)
j = 0;
while (j != limit) {
rxbuf = &rxr->rx_buffers[i];
if (rxbuf->buf == NULL) {
- mp = ixgbe_getjcl(&adapter->jcl_head, M_DONTWAIT,
- MT_DATA, M_PKTHDR, adapter->rx_mbuf_sz);
+ mp = ixgbe_getjcl(&adapter->jcl_head, M_NOWAIT,
+ MT_DATA, M_PKTHDR, rxr->mbuf_sz);
if (mp == NULL) {
rxr->no_jmbuf.ev_count++;
goto update;
}
+ if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN))
+ m_adj(mp, ETHER_ALIGN);
} else
mp = rxbuf->buf;
- mp->m_pkthdr.len = mp->m_len = adapter->rx_mbuf_sz;
+ mp->m_pkthdr.len = mp->m_len = rxr->mbuf_sz;
/* If we're dealing with an mbuf that was copied rather
* than replaced, there's no need to go through busdma.
*/
if ((rxbuf->flags & IXGBE_RX_COPY) == 0) {
/* Get the memory mapping */
- error = bus_dmamap_load_mbuf(rxr->tag->dt_dmat,
- rxbuf->map, mp, BUS_DMA_NOWAIT);
+ error = bus_dmamap_load_mbuf(rxr->ptag->dt_dmat,
+ rxbuf->pmap, mp, BUS_DMA_NOWAIT);
if (error != 0) {
printf("Refresh mbufs: payload dmamap load"
" failure - %d\n", error);
@@ -3980,10 +4014,10 @@ ixgbe_refresh_mbufs(struct rx_ring *rxr, int limit)
goto update;
}
rxbuf->buf = mp;
- bus_dmamap_sync(rxr->tag->dt_dmat, rxbuf->map,
+ bus_dmamap_sync(rxr->ptag->dt_dmat, rxbuf->pmap,
0, mp->m_pkthdr.len, BUS_DMASYNC_PREREAD);
rxbuf->addr = rxr->rx_base[i].read.pkt_addr =
- htole64(rxbuf->map->dm_segs[0].ds_addr);
+ htole64(rxbuf->pmap->dm_segs[0].ds_addr);
} else {
rxr->rx_base[i].read.pkt_addr = rxbuf->addr;
rxbuf->flags &= ~IXGBE_RX_COPY;
@@ -3993,7 +4027,7 @@ ixgbe_refresh_mbufs(struct rx_ring *rxr, int limit)
/* Next is precalculated */
i = j;
rxr->next_to_refresh = i;
- if (++j == adapter->num_rx_desc)
+ if (++j == rxr->num_desc)
j = 0;
}
update:
@@ -4019,7 +4053,7 @@ ixgbe_allocate_receive_buffers(struct rx_ring *rxr)
struct ixgbe_rx_buf *rxbuf;
int i, bsize, error;
- bsize = sizeof(struct ixgbe_rx_buf) * adapter->num_rx_desc;
+ bsize = sizeof(struct ixgbe_rx_buf) * rxr->num_desc;
if (!(rxr->rx_buffers =
(struct ixgbe_rx_buf *) malloc(bsize,
M_DEVBUF, M_NOWAIT | M_ZERO))) {
@@ -4034,15 +4068,15 @@ ixgbe_allocate_receive_buffers(struct rx_ring *rxr)
1, /* nsegments */
MJUM16BYTES, /* maxsegsize */
0, /* flags */
- &rxr->tag))) {
+ &rxr->ptag))) {
aprint_error_dev(dev, "Unable to create RX DMA tag\n");
goto fail;
}
- for (i = 0; i < adapter->num_rx_desc; i++, rxbuf++) {
+ for (i = 0; i < rxr->num_desc; i++, rxbuf++) {
rxbuf = &rxr->rx_buffers[i];
- error = ixgbe_dmamap_create(rxr->tag,
- BUS_DMA_NOWAIT, &rxbuf->map);
+ error = ixgbe_dmamap_create(rxr->ptag,
+ BUS_DMA_NOWAIT, &rxbuf->pmap);
if (error) {
aprint_error_dev(dev, "Unable to create RX dma map\n");
goto fail;
@@ -4108,11 +4142,11 @@ ixgbe_setup_hw_rsc(struct rx_ring *rxr)
** Limit the total number of descriptors that
** can be combined, so it does not exceed 64K
*/
- if (adapter->rx_mbuf_sz == MCLBYTES)
+ if (rxr->mbuf_sz == MCLBYTES)
rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
- else if (adapter->rx_mbuf_sz == MJUMPAGESIZE)
+ else if (rxr->mbuf_sz == MJUMPAGESIZE)
rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
- else if (adapter->rx_mbuf_sz == MJUM9BYTES)
+ else if (rxr->mbuf_sz == MJUM9BYTES)
rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
else /* Using 16K cluster */
rscctrl |= IXGBE_RSCCTL_MAXDESC_1;
@@ -4135,18 +4169,16 @@ ixgbe_setup_hw_rsc(struct rx_ring *rxr)
static void
ixgbe_free_receive_ring(struct rx_ring *rxr)
{
- struct adapter *adapter;
struct ixgbe_rx_buf *rxbuf;
int i;
- adapter = rxr->adapter;
- for (i = 0; i < adapter->num_rx_desc; i++) {
+ for (i = 0; i < rxr->num_desc; i++) {
rxbuf = &rxr->rx_buffers[i];
if (rxbuf->buf != NULL) {
- bus_dmamap_sync(rxr->tag->dt_dmat, rxbuf->map,
+ bus_dmamap_sync(rxr->ptag->dt_dmat, rxbuf->pmap,
0, rxbuf->buf->m_pkthdr.len,
BUS_DMASYNC_POSTREAD);
- ixgbe_dmamap_unload(rxr->tag, rxbuf->map);
+ ixgbe_dmamap_unload(rxr->ptag, rxbuf->pmap);
rxbuf->buf->m_flags |= M_PKTHDR;
m_freem(rxbuf->buf);
rxbuf->buf = NULL;
@@ -4189,6 +4221,8 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr)
rsize = roundup2(adapter->num_rx_desc *
sizeof(union ixgbe_adv_rx_desc), DBA_ALIGN);
bzero((void *)rxr->rx_base, rsize);
+ /* Cache the size */
+ rxr->mbuf_sz = adapter->rx_mbuf_sz;
/* Free current RX buffer structs and their mbufs */
ixgbe_free_receive_ring(rxr);
@@ -4198,13 +4232,13 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr)
/* Now reinitialize our supply of jumbo mbufs. The number
* or size of jumbo mbufs may have changed.
*/
- ixgbe_jcl_reinit(&adapter->jcl_head, rxr->tag->dt_dmat,
+ ixgbe_jcl_reinit(&adapter->jcl_head, rxr->ptag->dt_dmat,
2 * adapter->num_rx_desc, adapter->rx_mbuf_sz);
IXGBE_RX_LOCK(rxr);
/* Now replenish the mbufs */
- for (int j = 0; j != adapter->num_rx_desc; ++j) {
+ for (int j = 0; j != rxr->num_desc; ++j) {
struct mbuf *mp;
rxbuf = &rxr->rx_buffers[j];
@@ -4222,30 +4256,30 @@ ixgbe_setup_receive_ring(struct rx_ring *rxr)
void *addr;
addr = PNMB(slot + sj, &paddr);
- netmap_load_map(rxr->tag, rxbuf->map, addr);
+ netmap_load_map(rxr->ptag, rxbuf->pmap, addr);
/* Update descriptor */
rxr->rx_base[j].read.pkt_addr = htole64(paddr);
continue;
}
#endif /* DEV_NETMAP */
- rxbuf->buf = ixgbe_getjcl(&adapter->jcl_head, M_DONTWAIT,
+ rxbuf->buf = ixgbe_getjcl(&adapter->jcl_head, M_NOWAIT,
MT_DATA, M_PKTHDR, adapter->rx_mbuf_sz);
if (rxbuf->buf == NULL) {
error = ENOBUFS;
goto fail;
}
mp = rxbuf->buf;
- mp->m_pkthdr.len = mp->m_len = adapter->rx_mbuf_sz;
+ mp->m_pkthdr.len = mp->m_len = rxr->mbuf_sz;
/* Get the memory mapping */
- error = bus_dmamap_load_mbuf(rxr->tag->dt_dmat,
- rxbuf->map, mp, BUS_DMA_NOWAIT);
+ error = bus_dmamap_load_mbuf(rxr->ptag->dt_dmat,
+ rxbuf->pmap, mp, BUS_DMA_NOWAIT);
if (error != 0)
goto fail;
- bus_dmamap_sync(rxr->tag->dt_dmat, rxbuf->map,
+ bus_dmamap_sync(rxr->ptag->dt_dmat, rxbuf->pmap,
0, adapter->rx_mbuf_sz, BUS_DMASYNC_PREREAD);
/* Update descriptor */
rxr->rx_base[j].read.pkt_addr =
- htole64(rxbuf->map->dm_segs[0].ds_addr);
+ htole64(rxbuf->pmap->dm_segs[0].ds_addr);
}
@@ -4393,6 +4427,9 @@ ixgbe_initialize_receive_units(struct adapter *adapter)
/* Setup the HW Rx Head and Tail Descriptor Pointers */
IXGBE_WRITE_REG(hw, IXGBE_RDH(i), 0);
IXGBE_WRITE_REG(hw, IXGBE_RDT(i), 0);
+
+ /* Set the processing limit */
+ rxr->process_limit = ixgbe_rx_process_limit;
}
if (adapter->hw.mac.type != ixgbe_mac_82598EB) {
@@ -4499,17 +4536,17 @@ ixgbe_free_receive_buffers(struct rx_ring *rxr)
for (int i = 0; i < adapter->num_rx_desc; i++) {
rxbuf = &rxr->rx_buffers[i];
if (rxbuf->buf != NULL) {
- bus_dmamap_sync(rxr->tag->dt_dmat, rxbuf->map,
- 0, rxbuf->buf->m_pkthdr.len,
+ bus_dmamap_sync(rxr->ptag->dt_dmat,
+ rxbuf->pmap, 0, rxbuf->buf->m_pkthdr.len,
BUS_DMASYNC_POSTREAD);
- ixgbe_dmamap_unload(rxr->tag, rxbuf->map);
+ ixgbe_dmamap_unload(rxr->ptag, rxbuf->pmap);
rxbuf->buf->m_flags |= M_PKTHDR;
m_freem(rxbuf->buf);
}
rxbuf->buf = NULL;
- if (rxbuf->map != NULL) {
- ixgbe_dmamap_destroy(rxr->tag, rxbuf->map);
- rxbuf->map = NULL;
+ if (rxbuf->pmap != NULL) {
+ ixgbe_dmamap_destroy(rxr->ptag, rxbuf->pmap);
+ rxbuf->pmap = NULL;
}
}
if (rxr->rx_buffers != NULL) {
@@ -4518,9 +4555,9 @@ ixgbe_free_receive_buffers(struct rx_ring *rxr)
}
}
- if (rxr->tag != NULL) {
- ixgbe_dma_tag_destroy(rxr->tag);
- rxr->tag = NULL;
+ if (rxr->ptag != NULL) {
+ ixgbe_dma_tag_destroy(rxr->ptag);
+ rxr->ptag = NULL;
}
return;
@@ -4613,7 +4650,7 @@ ixgbe_rx_discard(struct rx_ring *rxr, int i)
* Return TRUE for more work, FALSE for all clean.
*********************************************************************/
static bool
-ixgbe_rxeof(struct ix_queue *que, int count)
+ixgbe_rxeof(struct ix_queue *que)
{
struct adapter *adapter = que->adapter;
struct rx_ring *rxr = que->rxr;
@@ -4624,29 +4661,16 @@ ixgbe_rxeof(struct ix_queue *que, int count)
#endif /* LRO */
int i, nextp, processed = 0;
u32 staterr = 0;
+ u16 count = rxr->process_limit;
union ixgbe_adv_rx_desc *cur;
struct ixgbe_rx_buf *rbuf, *nbuf;
IXGBE_RX_LOCK(rxr);
#ifdef DEV_NETMAP
- if (ifp->if_capenable & IFCAP_NETMAP) {
- /*
- * Same as the txeof routine: only wakeup clients on intr.
- * NKR_PENDINTR in nr_kflags is used to implement interrupt
- * mitigation (ixgbe_rxsync() will not look for new packets
- * unless NKR_PENDINTR is set).
- */
- struct netmap_adapter *na = NA(ifp);
-
- na->rx_rings[rxr->me].nr_kflags |= NKR_PENDINTR;
- selwakeuppri(&na->rx_rings[rxr->me].si, PI_NET);
- IXGBE_RX_UNLOCK(rxr);
- IXGBE_CORE_LOCK(adapter);
- selwakeuppri(&na->rx_si, PI_NET);
- IXGBE_CORE_UNLOCK(adapter);
+ /* Same as the txeof routine: wakeup clients on intr. */
+ if (netmap_rx_irq(ifp, rxr->me | NETMAP_LOCKED_ENTER, &processed))
return (FALSE);
- }
#endif /* DEV_NETMAP */
for (i = rxr->next_to_check; count != 0;) {
struct mbuf *sendmp, *mp;
@@ -4683,7 +4707,6 @@ ixgbe_rxeof(struct ix_queue *que, int count)
/* Make sure bad packets are discarded */
if (((staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) != 0) ||
(rxr->discard)) {
- ifp->if_ierrors++;
rxr->rx_discarded.ev_count++;
if (eop)
rxr->discard = FALSE;
@@ -4751,7 +4774,7 @@ ixgbe_rxeof(struct ix_queue *que, int count)
* leave the old mbuf+cluster for re-use.
*/
if (eop && len <= IXGBE_RX_COPY_LEN) {
- sendmp = m_gethdr(M_DONTWAIT, MT_DATA);
+ sendmp = m_gethdr(M_NOWAIT, MT_DATA);
if (sendmp != NULL) {
sendmp->m_data +=
IXGBE_RX_COPY_ALIGN;
@@ -4807,7 +4830,7 @@ next_desc:
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
/* Advance our pointers to the next descriptor. */
- if (++i == adapter->num_rx_desc)
+ if (++i == rxr->num_desc)
i = 0;
/* Now send to the stack or do LRO */
@@ -5009,22 +5032,37 @@ ixgbe_setup_vlan_hw_support(struct adapter *adapter)
static void
ixgbe_enable_intr(struct adapter *adapter)
{
- struct ixgbe_hw *hw = &adapter->hw;
- struct ix_queue *que = adapter->queues;
- u32 mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
-
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct ix_queue *que = adapter->queues;
+ u32 mask, fwsm;
+ mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
/* Enable Fan Failure detection */
if (hw->device_id == IXGBE_DEV_ID_82598AT)
mask |= IXGBE_EIMS_GPI_SDP1;
- else {
- mask |= IXGBE_EIMS_ECC;
- mask |= IXGBE_EIMS_GPI_SDP0;
- mask |= IXGBE_EIMS_GPI_SDP1;
- mask |= IXGBE_EIMS_GPI_SDP2;
+
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82599EB:
+ mask |= IXGBE_EIMS_ECC;
+ mask |= IXGBE_EIMS_GPI_SDP0;
+ mask |= IXGBE_EIMS_GPI_SDP1;
+ mask |= IXGBE_EIMS_GPI_SDP2;
#ifdef IXGBE_FDIR
- mask |= IXGBE_EIMS_FLOW_DIR;
+ mask |= IXGBE_EIMS_FLOW_DIR;
#endif
+ break;
+ case ixgbe_mac_X540:
+ mask |= IXGBE_EIMS_ECC;
+ /* Detect if Thermal Sensor is enabled */
+ fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM);
+ if (fwsm & IXGBE_FWSM_TS_ENABLED)
+ mask |= IXGBE_EIMS_TS;
+#ifdef IXGBE_FDIR
+ mask |= IXGBE_EIMS_FLOW_DIR;
+#endif
+ /* falls through */
+ default:
+ break;
}
IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask);
@@ -5275,7 +5313,7 @@ ixgbe_handle_msf(void *context)
else
negotiate = 0;
if (hw->mac.ops.setup_link)
- hw->mac.ops.setup_link(hw, autoneg, negotiate, TRUE);
+ hw->mac.ops.setup_link(hw, autoneg, TRUE);
return;
}
@@ -5321,6 +5359,11 @@ ixgbe_update_stats_counters(struct adapter *adapter)
adapter->stats.errbc.ev_count += IXGBE_READ_REG(hw, IXGBE_ERRBC);
adapter->stats.mspdc.ev_count += IXGBE_READ_REG(hw, IXGBE_MSPDC);
+ /*
+ ** Note: these are for the 8 possible traffic classes,
+ ** which in current implementation is unused,
+ ** therefore only 0 should read real data.
+ */
for (int i = 0; i < __arraycount(adapter->stats.mpc); i++) {
int j = i % adapter->num_queues;
u32 mp;
@@ -5331,13 +5374,21 @@ ixgbe_update_stats_counters(struct adapter *adapter)
adapter->stats.mpc[j].ev_count += mp;
/* Running comprehensive total for stats display */
total_missed_rx += mp;
- if (hw->mac.type == ixgbe_mac_82598EB)
+ if (hw->mac.type == ixgbe_mac_82598EB) {
adapter->stats.rnbc[j] +=
IXGBE_READ_REG(hw, IXGBE_RNBC(i));
+ adapter->stats.qbtc[j].ev_count +=
+ IXGBE_READ_REG(hw, IXGBE_QBTC(i));
+ adapter->stats.qbrc[j].ev_count +=
+ IXGBE_READ_REG(hw, IXGBE_QBRC(i));
+ adapter->stats.pxonrxc[j].ev_count +=
+ IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
+ } else {
+ adapter->stats.pxonrxc[j].ev_count +=
+ IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
+ }
adapter->stats.pxontxc[j].ev_count +=
IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
- adapter->stats.pxonrxc[j].ev_count +=
- IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
adapter->stats.pxofftxc[j].ev_count +=
IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
adapter->stats.pxoffrxc[j].ev_count +=
@@ -5349,12 +5400,6 @@ ixgbe_update_stats_counters(struct adapter *adapter)
int j = i % adapter->num_queues;
adapter->stats.qprc[j].ev_count += IXGBE_READ_REG(hw, IXGBE_QPRC(i));
adapter->stats.qptc[j].ev_count += IXGBE_READ_REG(hw, IXGBE_QPTC(i));
- adapter->stats.qbrc[j].ev_count += IXGBE_READ_REG(hw, IXGBE_QBRC(i));
- adapter->stats.qbrc[j].ev_count +=
- ((u64)IXGBE_READ_REG(hw, IXGBE_QBRC(i)) << 32);
- adapter->stats.qbtc[j].ev_count += IXGBE_READ_REG(hw, IXGBE_QBTC(i));
- adapter->stats.qbtc[j].ev_count +=
- ((u64)IXGBE_READ_REG(hw, IXGBE_QBTC(i)) << 32);
adapter->stats.qprdc[j].ev_count += IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
}
adapter->stats.mlfc.ev_count += IXGBE_READ_REG(hw, IXGBE_MLFC);
@@ -5448,9 +5493,10 @@ ixgbe_update_stats_counters(struct adapter *adapter)
* (SOICZIFDATA) work.
*/
ifp->if_collisions = 0;
-
+
/* Rx Errors */
- ifp->if_ierrors += total_missed_rx + crcerrs + rlec;
+ ifp->if_iqdrops += total_missed_rx;
+ ifp->if_ierrors += crcerrs + rlec;
}
/** ixgbe_sysctl_tdh_handler - Handler function
@@ -5597,8 +5643,6 @@ ixgbe_add_hw_stats(struct adapter *adapter)
struct sysctllog **log = &adapter->sysctllog;
struct tx_ring *txr = adapter->tx_rings;
struct rx_ring *rxr = adapter->rx_rings;
- struct ixgbe_hw *hw = &adapter->hw;
-
struct ixgbe_hw_stats *stats = &adapter->stats;
/* Driver Statistics */
@@ -5645,8 +5689,6 @@ ixgbe_add_hw_stats(struct adapter *adapter)
NULL, device_xname(dev), "Watchdog timeouts");
evcnt_attach_dynamic(&adapter->tso_err, EVCNT_TYPE_MISC,
NULL, device_xname(dev), "TSO errors");
- evcnt_attach_dynamic(&adapter->tso_tx, EVCNT_TYPE_MISC,
- NULL, device_xname(dev), "TSO");
evcnt_attach_dynamic(&adapter->link_irq, EVCNT_TYPE_MISC,
NULL, device_xname(dev), "Link MSIX IRQ Handled");
@@ -5696,6 +5738,8 @@ ixgbe_add_hw_stats(struct adapter *adapter)
0, CTL_CREATE, CTL_EOL) != 0)
break;
+ evcnt_attach_dynamic(&txr->tso_tx, EVCNT_TYPE_MISC,
+ NULL, device_xname(dev), "TSO");
evcnt_attach_dynamic(&txr->no_desc_avail, EVCNT_TYPE_MISC,
NULL, adapter->queues[i].evnamebuf,
"Queue No Descriptor Available");
@@ -5889,24 +5933,6 @@ ixgbe_add_hw_stats(struct adapter *adapter)
stats->namebuf, "512-1023 byte frames transmitted");
evcnt_attach_dynamic(&stats->ptc1522, EVCNT_TYPE_MISC, NULL,
stats->namebuf, "1024-1522 byte frames transmitted");
-
- /* FC Stats */
- evcnt_attach_dynamic(&stats->fccrc, EVCNT_TYPE_MISC, NULL,
- stats->namebuf, "FC CRC Errors");
- evcnt_attach_dynamic(&stats->fclast, EVCNT_TYPE_MISC, NULL,
- stats->namebuf, "FC Last Error");
- if (hw->mac.type != ixgbe_mac_82598EB) {
- evcnt_attach_dynamic(&stats->fcoerpdc, EVCNT_TYPE_MISC, NULL,
- stats->namebuf, "FCoE Packets Dropped");
- evcnt_attach_dynamic(&stats->fcoeprc, EVCNT_TYPE_MISC, NULL,
- stats->namebuf, "FCoE Packets Received");
- evcnt_attach_dynamic(&stats->fcoeptc, EVCNT_TYPE_MISC, NULL,
- stats->namebuf, "FCoE Packets Transmitted");
- evcnt_attach_dynamic(&stats->fcoedwrc, EVCNT_TYPE_MISC, NULL,
- stats->namebuf, "FCoE DWords Received");
- evcnt_attach_dynamic(&stats->fcoedwtc, EVCNT_TYPE_MISC, NULL,
- stats->namebuf, "FCoE DWords Transmitted");
- }
}
/*
@@ -5945,10 +5971,13 @@ ixgbe_set_flowcntl(SYSCTLFN_ARGS)
ixgbe_disable_rx_drop(adapter);
break;
case ixgbe_fc_none:
- default:
adapter->hw.fc.requested_mode = ixgbe_fc_none;
if (adapter->num_queues > 1)
ixgbe_enable_rx_drop(adapter);
+ break;
+ default:
+ adapter->fc = last;
+ return (EINVAL);
}
/* Don't autoneg if forcing a value */
adapter->hw.fc.disable_fc_autoneg = TRUE;
@@ -5956,29 +5985,6 @@ ixgbe_set_flowcntl(SYSCTLFN_ARGS)
return 0;
}
-static void
-ixgbe_add_rx_process_limit(struct adapter *adapter, const char *name,
- const char *description, int *limit, int value)
-{
- const struct sysctlnode *rnode, *cnode;
- struct sysctllog **log = &adapter->sysctllog;
-
- *limit = value;
-
- if ((rnode = ixgbe_sysctl_instance(adapter)) == NULL)
- aprint_error_dev(adapter->dev,
- "could not create sysctl root\n");
- else if (sysctl_createv(log, 0, &rnode, &cnode,
- CTLFLAG_READWRITE,
- CTLTYPE_INT,
- name, SYSCTL_DESCR(description),
- NULL, 0, limit, 0,
- CTL_CREATE, CTL_EOL) != 0) {
- aprint_error_dev(adapter->dev, "%s: could not create sysctl",
- __func__);
- }
-}
-
/*
** Control link advertise speed:
** 1 - advertise only 1G
@@ -6016,11 +6022,11 @@ ixgbe_set_advertise(SYSCTLFN_ARGS)
if (!((hw->phy.media_type == ixgbe_media_type_copper) ||
(hw->phy.multispeed_fiber)))
- return 0;
+ return (EINVAL);
if ((adapter->advertise == 2) && (hw->mac.type != ixgbe_mac_X540)) {
device_printf(dev, "Set Advertise: 100Mb on X540 only\n");
- return (error);
+ return (EINVAL);
}
if (adapter->advertise == 1)
@@ -6030,11 +6036,13 @@ ixgbe_set_advertise(SYSCTLFN_ARGS)
else if (adapter->advertise == 3)
speed = IXGBE_LINK_SPEED_1GB_FULL |
IXGBE_LINK_SPEED_10GB_FULL;
- else /* bogus value */
- return (error);
+ else {/* bogus value */
+ adapter->advertise = last;
+ return (EINVAL);
+ }
hw->mac.autotry_restart = TRUE;
- hw->mac.ops.setup_link(hw, speed, TRUE, TRUE);
+ hw->mac.ops.setup_link(hw, speed, TRUE);
return 0;
}
diff --git a/sys/dev/pci/ixgbe/ixgbe.h b/sys/dev/pci/ixgbe/ixgbe.h
index da3fb25d939..69748589786 100644
--- a/sys/dev/pci/ixgbe/ixgbe.h
+++ b/sys/dev/pci/ixgbe/ixgbe.h
@@ -58,8 +58,8 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-/*$FreeBSD: head/sys/dev/ixgbe/ixgbe.h 243716 2012-11-30 22:33:21Z jfv $*/
-/*$NetBSD: ixgbe.h,v 1.6 2015/04/14 07:17:06 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe.h 244514 2012-12-20 22:26:03Z luigi $*/
+/*$NetBSD: ixgbe.h,v 1.7 2015/04/24 07:00:51 msaitoh Exp $*/
#ifndef _IXGBE_H_
@@ -106,10 +106,7 @@
#include <sys/sysctl.h>
#include <sys/endian.h>
#include <sys/workqueue.h>
-
-#ifdef IXGBE_IEEE1588
-#include <sys/ieee1588.h>
-#endif
+#include <sys/cpu.h>
#include "ixgbe_netbsd.h"
#include "ixgbe_api.h"
@@ -218,6 +215,9 @@
#define IXGBE_BR_SIZE 4096
#define IXGBE_QUEUE_MIN_FREE 32
+/* IOCTL define to gather SFP+ Diagnostic data */
+#define SIOCGI2C SIOCGIFGENERIC
+
/* Offload bits in mbuf flag */
#define M_CSUM_OFFLOAD \
(M_CSUM_IPv4|M_CSUM_UDPv4|M_CSUM_TCPv4|M_CSUM_UDPv6|M_CSUM_TCPv6)
@@ -247,9 +247,16 @@ typedef struct _ixgbe_vendor_info_t {
unsigned int index;
} ixgbe_vendor_info_t;
+/* This is used to get SFP+ module data */
+struct ixgbe_i2c_req {
+ u8 dev_addr;
+ u8 offset;
+ u8 len;
+ u8 data[8];
+};
struct ixgbe_tx_buf {
- u32 eop_index;
+ union ixgbe_adv_tx_desc *eop;
struct mbuf *m_head;
bus_dmamap_t map;
};
@@ -257,7 +264,7 @@ struct ixgbe_tx_buf {
struct ixgbe_rx_buf {
struct mbuf *buf;
struct mbuf *fmp;
- bus_dmamap_t map;
+ bus_dmamap_t pmap;
u_int flags;
#define IXGBE_RX_COPY 0x01
uint64_t addr;
@@ -301,24 +308,26 @@ struct tx_ring {
struct adapter *adapter;
kmutex_t tx_mtx;
u32 me;
+ struct timeval watchdog_time;
+ union ixgbe_adv_tx_desc *tx_base;
+ struct ixgbe_tx_buf *tx_buffers;
+ struct ixgbe_dma_alloc txdma;
+ volatile u16 tx_avail;
+ u16 next_avail_desc;
+ u16 next_to_clean;
+ u32 process_limit;
+ u16 num_desc;
enum {
IXGBE_QUEUE_IDLE,
IXGBE_QUEUE_WORKING,
IXGBE_QUEUE_HUNG,
} queue_status;
- struct timeval watchdog_time;
- union ixgbe_adv_tx_desc *tx_base;
- struct ixgbe_dma_alloc txdma;
- u32 next_avail_desc;
- u32 next_to_clean;
- struct ixgbe_tx_buf *tx_buffers;
- volatile u16 tx_avail;
u32 txd_cmd;
ixgbe_dma_tag_t *txtag;
char mtx_name[16];
-#if __FreeBSD_version >= 800000
+#ifndef IXGBE_LEGACY_TX
struct buf_ring *br;
- struct task txq_task;
+ void *txq_si;
#endif
#ifdef IXGBE_FDIR
u16 atr_sample;
@@ -327,6 +336,8 @@ struct tx_ring {
u32 bytes; /* used for AIM */
u32 packets;
/* Soft Stats */
+ struct evcnt tso_tx;
+ struct evcnt no_tx_map_avail;
struct evcnt no_desc_avail;
struct evcnt total_packets;
};
@@ -348,11 +359,14 @@ struct rx_ring {
bool hw_rsc;
bool discard;
bool vtag_strip;
- u32 next_to_refresh;
- u32 next_to_check;
+ u16 next_to_refresh;
+ u16 next_to_check;
+ u16 num_desc;
+ u16 mbuf_sz;
+ u32 process_limit;
char mtx_name[16];
struct ixgbe_rx_buf *rx_buffers;
- ixgbe_dma_tag_t *tag;
+ ixgbe_dma_tag_t *ptag;
u32 bytes; /* Used for AIM calc */
u32 packets;
@@ -443,16 +457,15 @@ struct adapter {
* Allocated at run time, an array of rings.
*/
struct tx_ring *tx_rings;
- int num_tx_desc;
+ u32 num_tx_desc;
/*
* Receive rings:
* Allocated at run time, an array of rings.
*/
struct rx_ring *rx_rings;
- int num_rx_desc;
u64 que_mask;
- u32 rx_process_limit;
+ u32 num_rx_desc;
/* Multicast array memory */
u8 *mta;
@@ -462,7 +475,6 @@ struct adapter {
struct evcnt mbuf_defrag_failed;
struct evcnt mbuf_header_failed;
struct evcnt mbuf_packet_failed;
- struct evcnt no_tx_map_avail;
struct evcnt efbig_tx_dma_setup;
struct evcnt efbig2_tx_dma_setup;
struct evcnt m_defrag_failed;
@@ -472,7 +484,6 @@ struct adapter {
struct evcnt enomem_tx_dma_setup;
struct evcnt watchdog_events;
struct evcnt tso_err;
- struct evcnt tso_tx;
struct evcnt link_irq;
struct evcnt morerx;
struct evcnt moretx;
@@ -543,12 +554,10 @@ drbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br)
static inline u16
ixgbe_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) -
+ return ((rxr->num_desc + rxr->next_to_check) -
rxr->next_to_refresh - 1);
}
diff --git a/sys/dev/pci/ixgbe/ixgbe_82598.c b/sys/dev/pci/ixgbe/ixgbe_82598.c
index f10ee442627..08278ee67f2 100644
--- a/sys/dev/pci/ixgbe/ixgbe_82598.c
+++ b/sys/dev/pci/ixgbe/ixgbe_82598.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,8 +30,8 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_82598.c 238149 2012-07-05 20:51:44Z jfv $*/
-/*$NetBSD: ixgbe_82598.c,v 1.3 2015/04/02 09:26:55 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_82598.c 247822 2013-03-04 23:07:40Z jfv $*/
+/*$NetBSD: ixgbe_82598.c,v 1.4 2015/04/24 07:00:51 msaitoh Exp $*/
#include "ixgbe_type.h"
#include "ixgbe_82598.h"
@@ -50,18 +50,17 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
bool link_up_wait_to_complete);
static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete);
static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete);
static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw);
static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw);
static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb,
u32 headroom, int strategy);
-
+static s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 *sff8472_data);
/**
* ixgbe_set_pcie_completion_timeout - set pci-e completion timeout
* @hw: pointer to the HW structure
@@ -156,6 +155,7 @@ s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw)
/* SFP+ Module */
phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_82598;
+ phy->ops.read_i2c_sff8472 = &ixgbe_read_i2c_sff8472_82598;
/* Link */
mac->ops.check_link = &ixgbe_check_mac_link_82598;
@@ -713,15 +713,15 @@ out:
* ixgbe_setup_mac_link_82598 - Set MAC link speed
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
* @autoneg_wait_to_complete: TRUE when waiting for completion is needed
*
* Set the link speed in the AUTOC register and restarts link.
**/
static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+ ixgbe_link_speed speed,
bool autoneg_wait_to_complete)
{
+ bool autoneg = FALSE;
s32 status = IXGBE_SUCCESS;
ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
@@ -767,14 +767,12 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
* ixgbe_setup_copper_link_82598 - Set the PHY autoneg advertised field
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
* @autoneg_wait_to_complete: TRUE if waiting is needed to complete
*
* Sets the link speed in the AUTOC register in the MAC and restarts link.
**/
static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete)
{
s32 status;
@@ -782,7 +780,7 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
DEBUGFUNC("ixgbe_setup_copper_link_82598");
/* Setup the PHY according to input speed */
- status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+ status = hw->phy.ops.setup_link_speed(hw, speed,
autoneg_wait_to_complete);
/* Set up MAC */
ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete);
@@ -1103,15 +1101,16 @@ s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val)
}
/**
- * ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface.
+ * ixgbe_read_i2c_phy_82598 - Reads 8 bit word over I2C interface.
* @hw: pointer to hardware structure
- * @byte_offset: EEPROM byte offset to read
+ * @dev_addr: address to read from
+ * @byte_offset: byte offset to read from dev_addr
* @eeprom_data: value read
*
* Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
**/
-s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
- u8 *eeprom_data)
+static s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr,
+ u8 byte_offset, u8 *eeprom_data)
{
s32 status = IXGBE_SUCCESS;
u16 sfp_addr = 0;
@@ -1119,7 +1118,7 @@ s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
u16 sfp_stat = 0;
u32 i;
- DEBUGFUNC("ixgbe_read_i2c_eeprom_82598");
+ DEBUGFUNC("ixgbe_read_i2c_phy_82598");
if (hw->phy.type == ixgbe_phy_nl) {
/*
@@ -1127,7 +1126,7 @@ s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
* 0xC30D. These registers are used to talk to the SFP+
* module's EEPROM through the SDA/SCL (I2C) interface.
*/
- sfp_addr = (IXGBE_I2C_EEPROM_DEV_ADDR << 8) + byte_offset;
+ sfp_addr = (dev_addr << 8) + byte_offset;
sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK);
hw->phy.ops.write_reg(hw,
IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
@@ -1159,7 +1158,6 @@ s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
*eeprom_data = (u8)(sfp_data >> 8);
} else {
status = IXGBE_ERR_PHY;
- goto out;
}
out:
@@ -1167,6 +1165,36 @@ out:
}
/**
+ * ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface.
+ * @hw: pointer to hardware structure
+ * @byte_offset: EEPROM byte offset to read
+ * @eeprom_data: value read
+ *
+ * Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
+ **/
+s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 *eeprom_data)
+{
+ return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR,
+ byte_offset, eeprom_data);
+}
+
+/**
+ * ixgbe_read_i2c_sff8472_82598 - Reads 8 bit word over I2C interface.
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset at address 0xA2
+ * @eeprom_data: value read
+ *
+ * Performs 8 byte read operation to SFP module's SFF-8472 data over I2C
+ **/
+static s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 *sff8472_data)
+{
+ return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR2,
+ byte_offset, sff8472_data);
+}
+
+/**
* ixgbe_get_supported_physical_layer_82598 - Returns physical layer type
* @hw: pointer to hardware structure
*
diff --git a/sys/dev/pci/ixgbe/ixgbe_82598.h b/sys/dev/pci/ixgbe/ixgbe_82598.h
index 29032053978..ca45b672236 100644
--- a/sys/dev/pci/ixgbe/ixgbe_82598.h
+++ b/sys/dev/pci/ixgbe/ixgbe_82598.h
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_82598.h 238149 2012-07-05 20:51:44Z jfv $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_82598.h 245952 2013-01-26 22:08:21Z pfg $*/
#ifndef _IXGBE_82598_H_
#define _IXGBE_82598_H_
diff --git a/sys/dev/pci/ixgbe/ixgbe_82599.c b/sys/dev/pci/ixgbe/ixgbe_82599.c
index 35d4967ac19..ec2d8f60a58 100644
--- a/sys/dev/pci/ixgbe/ixgbe_82599.c
+++ b/sys/dev/pci/ixgbe/ixgbe_82599.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,8 +30,8 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_82599.c 240155 2012-09-06 02:07:58Z kevlo $*/
-/*$NetBSD: ixgbe_82599.c,v 1.8 2015/04/14 07:17:06 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_82599.c 247822 2013-03-04 23:07:40Z jfv $*/
+/*$NetBSD: ixgbe_82599.c,v 1.9 2015/04/24 07:00:51 msaitoh Exp $*/
#include "ixgbe_type.h"
#include "ixgbe_82599.h"
@@ -41,7 +41,6 @@
static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete);
static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
@@ -49,14 +48,37 @@ static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
u16 words, u16 *data);
+static bool ixgbe_mng_enabled(struct ixgbe_hw *hw)
+{
+ u32 fwsm, manc, factps;
+
+ fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM);
+ if ((fwsm & IXGBE_FWSM_MODE_MASK) != IXGBE_FWSM_FW_MODE_PT)
+ return FALSE;
+
+ manc = IXGBE_READ_REG(hw, IXGBE_MANC);
+ if (!(manc & IXGBE_MANC_RCV_TCO_EN))
+ return FALSE;
+
+ factps = IXGBE_READ_REG(hw, IXGBE_FACTPS);
+ if (factps & IXGBE_FACTPS_MNGCG)
+ return FALSE;
+
+ return TRUE;
+}
+
void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
{
struct ixgbe_mac_info *mac = &hw->mac;
DEBUGFUNC("ixgbe_init_mac_link_ops_82599");
- /* enable the laser control functions for SFP+ fiber */
- if (mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) {
+ /*
+ * enable the laser control functions for SFP+ fiber
+ * and MNG not enabled
+ */
+ if ((mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
+ !(ixgbe_mng_enabled(hw))) {
mac->ops.disable_tx_laser =
&ixgbe_disable_tx_laser_multispeed_fiber;
mac->ops.enable_tx_laser =
@@ -136,9 +158,8 @@ init_phy_ops_out:
s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
{
s32 ret_val = IXGBE_SUCCESS;
- u32 reg_anlp1 = 0;
- u32 i = 0;
u16 list_offset, data_offset, data_value;
+ bool got_lock = FALSE;
DEBUGFUNC("ixgbe_setup_sfp_modules_82599");
@@ -172,28 +193,39 @@ s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
/* Delay obtaining semaphore again to allow FW access */
msec_delay(hw->eeprom.semaphore_delay);
- /* Now restart DSP by setting Restart_AN and clearing LMS */
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw,
- IXGBE_AUTOC) & ~IXGBE_AUTOC_LMS_MASK) |
- IXGBE_AUTOC_AN_RESTART));
-
- /* Wait for AN to leave state 0 */
- for (i = 0; i < 10; i++) {
- msec_delay(4);
- reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1);
- if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)
- break;
+ /* Need SW/FW semaphore around AUTOC writes if LESM on,
+ * likewise reset_pipeline requires lock as it also writes
+ * AUTOC.
+ */
+ if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+ ret_val = hw->mac.ops.acquire_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ if (ret_val != IXGBE_SUCCESS) {
+ ret_val = IXGBE_ERR_SWFW_SYNC;
+ goto setup_sfp_out;
+ }
+
+ got_lock = TRUE;
+ }
+
+ /* Restart DSP and set SFI mode */
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((hw->mac.orig_autoc) |
+ IXGBE_AUTOC_LMS_10G_SERIAL));
+ hw->mac.cached_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ ret_val = ixgbe_reset_pipeline_82599(hw);
+
+ if (got_lock) {
+ hw->mac.ops.release_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ got_lock = FALSE;
}
- if (!(reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)) {
+
+ if (ret_val) {
DEBUGOUT("sfp module setup not complete\n");
ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE;
goto setup_sfp_out;
}
- /* Restart DSP by setting Restart_AN and return to SFI mode */
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw,
- IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL |
- IXGBE_AUTOC_AN_RESTART));
}
setup_sfp_out:
@@ -217,7 +249,7 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)
DEBUGFUNC("ixgbe_init_ops_82599");
- ret_val = ixgbe_init_phy_ops_generic(hw);
+ ixgbe_init_phy_ops_generic(hw);
ret_val = ixgbe_init_ops_generic(hw);
/* PHY */
@@ -290,13 +322,13 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)
* ixgbe_get_link_capabilities_82599 - Determines link capabilities
* @hw: pointer to hardware structure
* @speed: pointer to link speed
- * @negotiation: TRUE when autoneg or autotry is enabled
+ * @autoneg: TRUE when autoneg or autotry is enabled
*
* Determines the link capabilities by reading the AUTOC register.
**/
s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
ixgbe_link_speed *speed,
- bool *negotiation)
+ bool *autoneg)
{
s32 status = IXGBE_SUCCESS;
u32 autoc = 0;
@@ -310,7 +342,7 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
*speed = IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = TRUE;
+ *autoneg = TRUE;
goto out;
}
@@ -327,22 +359,22 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
switch (autoc & IXGBE_AUTOC_LMS_MASK) {
case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
*speed = IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = FALSE;
+ *autoneg = FALSE;
break;
case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
*speed = IXGBE_LINK_SPEED_10GB_FULL;
- *negotiation = FALSE;
+ *autoneg = FALSE;
break;
case IXGBE_AUTOC_LMS_1G_AN:
*speed = IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = TRUE;
+ *autoneg = TRUE;
break;
case IXGBE_AUTOC_LMS_10G_SERIAL:
*speed = IXGBE_LINK_SPEED_10GB_FULL;
- *negotiation = FALSE;
+ *autoneg = FALSE;
break;
case IXGBE_AUTOC_LMS_KX4_KX_KR:
@@ -354,7 +386,7 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
if (autoc & IXGBE_AUTOC_KX_SUPP)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = TRUE;
+ *autoneg = TRUE;
break;
case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII:
@@ -365,12 +397,12 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
if (autoc & IXGBE_AUTOC_KX_SUPP)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = TRUE;
+ *autoneg = TRUE;
break;
case IXGBE_AUTOC_LMS_SGMII_1G_100M:
*speed = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_100_FULL;
- *negotiation = FALSE;
+ *autoneg = FALSE;
break;
default:
@@ -382,7 +414,7 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
if (hw->phy.multispeed_fiber) {
*speed |= IXGBE_LINK_SPEED_10GB_FULL |
IXGBE_LINK_SPEED_1GB_FULL;
- *negotiation = TRUE;
+ *autoneg = TRUE;
}
out:
@@ -435,6 +467,10 @@ enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_82599_T3_LOM:
media_type = ixgbe_media_type_copper;
break;
+ case IXGBE_DEV_ID_82599_BYPASS:
+ media_type = ixgbe_media_type_fiber_fixed;
+ hw->phy.multispeed_fiber = TRUE;
+ break;
default:
media_type = ixgbe_media_type_unknown;
break;
@@ -458,17 +494,32 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
u32 links_reg;
u32 i;
s32 status = IXGBE_SUCCESS;
+ bool got_lock = FALSE;
DEBUGFUNC("ixgbe_start_mac_link_82599");
+ /* reset_pipeline requires us to hold this lock as it writes to
+ * AUTOC.
+ */
+ if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+ status = hw->mac.ops.acquire_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ if (status != IXGBE_SUCCESS)
+ goto out;
+
+ got_lock = TRUE;
+ }
+
/* Restart link */
- autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- autoc_reg |= IXGBE_AUTOC_AN_RESTART;
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+ ixgbe_reset_pipeline_82599(hw);
+
+ if (got_lock)
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
/* Only poll for autoneg to complete if specified to do so */
if (autoneg_wait_to_complete) {
+ autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
IXGBE_AUTOC_LMS_KX4_KX_KR ||
(autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
@@ -492,6 +543,7 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
/* Add delay to filter out noises during initial link setup */
msec_delay(50);
+out:
return status;
}
@@ -557,16 +609,84 @@ void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_set_fiber_fixed_speed - Set module link speed for fixed fiber
+ * @hw: pointer to hardware structure
+ * @speed: link speed to set
+ *
+ * We set the module speed differently for fixed fiber. For other
+ * multi-speed devices we don't have an error value so here if we
+ * detect an error we just log it and exit.
+ */
+static void ixgbe_set_fiber_fixed_speed(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed)
+{
+ s32 status;
+ u8 rs, eeprom_data;
+
+ switch (speed) {
+ case IXGBE_LINK_SPEED_10GB_FULL:
+ /* one bit mask same as setting on */
+ rs = IXGBE_SFF_SOFT_RS_SELECT_10G;
+ break;
+ case IXGBE_LINK_SPEED_1GB_FULL:
+ rs = IXGBE_SFF_SOFT_RS_SELECT_1G;
+ break;
+ default:
+ DEBUGOUT("Invalid fixed module speed\n");
+ return;
+ }
+
+ /* Set RS0 */
+ status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
+ IXGBE_I2C_EEPROM_DEV_ADDR2,
+ &eeprom_data);
+ if (status) {
+ DEBUGOUT("Failed to read Rx Rate Select RS0\n");
+ goto out;
+ }
+
+ eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
+
+ status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
+ IXGBE_I2C_EEPROM_DEV_ADDR2,
+ eeprom_data);
+ if (status) {
+ DEBUGOUT("Failed to write Rx Rate Select RS0\n");
+ goto out;
+ }
+
+ /* Set RS1 */
+ status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
+ IXGBE_I2C_EEPROM_DEV_ADDR2,
+ &eeprom_data);
+ if (status) {
+ DEBUGOUT("Failed to read Rx Rate Select RS1\n");
+ goto out;
+ }
+
+ eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) & rs;
+
+ status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
+ IXGBE_I2C_EEPROM_DEV_ADDR2,
+ eeprom_data);
+ if (status) {
+ DEBUGOUT("Failed to write Rx Rate Select RS1\n");
+ goto out;
+ }
+out:
+ return;
+}
+
+/**
* ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
* @autoneg_wait_to_complete: TRUE when waiting for completion is needed
*
* Set the link speed in the AUTOC register and restarts link.
**/
s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+ ixgbe_link_speed speed,
bool autoneg_wait_to_complete)
{
s32 status = IXGBE_SUCCESS;
@@ -575,13 +695,12 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
u32 speedcnt = 0;
u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
u32 i = 0;
- bool link_up = FALSE;
- bool negotiation;
+ bool autoneg, link_up = FALSE;
DEBUGFUNC("ixgbe_setup_mac_link_multispeed_fiber");
/* Mask off requested but non-supported speeds */
- status = ixgbe_get_link_capabilities(hw, &link_speed, &negotiation);
+ status = ixgbe_get_link_capabilities(hw, &link_speed, &autoneg);
if (status != IXGBE_SUCCESS)
return status;
@@ -604,16 +723,20 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
goto out;
/* Set the module link speed */
- esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
- IXGBE_WRITE_FLUSH(hw);
+ if (hw->phy.media_type == ixgbe_media_type_fiber_fixed) {
+ ixgbe_set_fiber_fixed_speed(hw,
+ IXGBE_LINK_SPEED_10GB_FULL);
+ } else {
+ esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+ IXGBE_WRITE_FLUSH(hw);
+ }
/* Allow module to change analog characteristics (1G->10G) */
msec_delay(40);
status = ixgbe_setup_mac_link_82599(hw,
IXGBE_LINK_SPEED_10GB_FULL,
- autoneg,
autoneg_wait_to_complete);
if (status != IXGBE_SUCCESS)
return status;
@@ -655,17 +778,21 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
goto out;
/* Set the module link speed */
- esdp_reg &= ~IXGBE_ESDP_SDP5;
- esdp_reg |= IXGBE_ESDP_SDP5_DIR;
- IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
- IXGBE_WRITE_FLUSH(hw);
+ if (hw->phy.media_type == ixgbe_media_type_fiber_fixed) {
+ ixgbe_set_fiber_fixed_speed(hw,
+ IXGBE_LINK_SPEED_1GB_FULL);
+ } else {
+ esdp_reg &= ~IXGBE_ESDP_SDP5;
+ esdp_reg |= IXGBE_ESDP_SDP5_DIR;
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+ IXGBE_WRITE_FLUSH(hw);
+ }
/* Allow module to change analog characteristics (10G->1G) */
msec_delay(40);
status = ixgbe_setup_mac_link_82599(hw,
IXGBE_LINK_SPEED_1GB_FULL,
- autoneg,
autoneg_wait_to_complete);
if (status != IXGBE_SUCCESS)
return status;
@@ -692,7 +819,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
*/
if (speedcnt > 1)
status = ixgbe_setup_mac_link_multispeed_fiber(hw,
- highest_link_speed, autoneg, autoneg_wait_to_complete);
+ highest_link_speed, autoneg_wait_to_complete);
out:
/* Set autoneg_advertised value based on input link speed */
@@ -711,13 +838,12 @@ out:
* ixgbe_setup_mac_link_smartspeed - Set MAC link speed using SmartSpeed
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
* @autoneg_wait_to_complete: TRUE when waiting for completion is needed
*
* Implements the Intel SmartSpeed algorithm.
**/
s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+ ixgbe_link_speed speed,
bool autoneg_wait_to_complete)
{
s32 status = IXGBE_SUCCESS;
@@ -750,7 +876,7 @@ s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
/* First, try to get link with full advertisement */
hw->phy.smart_speed_active = FALSE;
for (j = 0; j < IXGBE_SMARTSPEED_MAX_RETRIES; j++) {
- status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
+ status = ixgbe_setup_mac_link_82599(hw, speed,
autoneg_wait_to_complete);
if (status != IXGBE_SUCCESS)
goto out;
@@ -785,7 +911,7 @@ s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
/* Turn SmartSpeed on to disable KR support */
hw->phy.smart_speed_active = TRUE;
- status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
+ status = ixgbe_setup_mac_link_82599(hw, speed,
autoneg_wait_to_complete);
if (status != IXGBE_SUCCESS)
goto out;
@@ -810,7 +936,7 @@ s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
/* We didn't get link. Turn SmartSpeed back off. */
hw->phy.smart_speed_active = FALSE;
- status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
+ status = ixgbe_setup_mac_link_82599(hw, speed,
autoneg_wait_to_complete);
out:
@@ -824,32 +950,30 @@ out:
* ixgbe_setup_mac_link_82599 - Set MAC link speed
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
* @autoneg_wait_to_complete: TRUE when waiting for completion is needed
*
* Set the link speed in the AUTOC register and restarts link.
**/
s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+ ixgbe_link_speed speed,
bool autoneg_wait_to_complete)
{
+ bool autoneg = FALSE;
s32 status = IXGBE_SUCCESS;
- u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ u32 autoc, pma_pmd_1g, link_mode, start_autoc;
u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
- u32 start_autoc = autoc;
u32 orig_autoc = 0;
- u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
- u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
u32 links_reg;
u32 i;
ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
+ bool got_lock = FALSE;
DEBUGFUNC("ixgbe_setup_mac_link_82599");
/* Check to see if speed passed in is supported. */
status = ixgbe_get_link_capabilities(hw, &link_capabilities, &autoneg);
- if (status != IXGBE_SUCCESS)
+ if (status)
goto out;
speed &= link_capabilities;
@@ -861,9 +985,14 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
/* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
if (hw->mac.orig_link_settings_stored)
- orig_autoc = hw->mac.orig_autoc;
+ autoc = hw->mac.orig_autoc;
else
- orig_autoc = autoc;
+ autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+
+ orig_autoc = autoc;
+ start_autoc = hw->mac.cached_autoc;
+ link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
+ pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
@@ -902,9 +1031,31 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
}
if (autoc != start_autoc) {
+ /* Need SW/FW semaphore around AUTOC writes if LESM is on,
+ * likewise reset_pipeline requires us to hold this lock as
+ * it also writes to AUTOC.
+ */
+ if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+ status = hw->mac.ops.acquire_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ if (status != IXGBE_SUCCESS) {
+ status = IXGBE_ERR_SWFW_SYNC;
+ goto out;
+ }
+
+ got_lock = TRUE;
+ }
+
/* Restart link */
- autoc |= IXGBE_AUTOC_AN_RESTART;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
+ hw->mac.cached_autoc = autoc;
+ ixgbe_reset_pipeline_82599(hw);
+
+ if (got_lock) {
+ hw->mac.ops.release_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ got_lock = FALSE;
+ }
/* Only poll for autoneg to complete if specified to do so */
if (autoneg_wait_to_complete) {
@@ -939,14 +1090,12 @@ out:
* ixgbe_setup_copper_link_82599 - Set the PHY autoneg advertised field
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
* @autoneg_wait_to_complete: TRUE if waiting is needed to complete
*
* Restarts link on PHY and MAC based on settings passed in.
**/
static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete)
{
s32 status;
@@ -954,7 +1103,7 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
DEBUGFUNC("ixgbe_setup_copper_link_82599");
/* Setup the PHY according to input speed */
- status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+ status = hw->phy.ops.setup_link_speed(hw, speed,
autoneg_wait_to_complete);
/* Set up MAC */
ixgbe_start_mac_link_82599(hw, autoneg_wait_to_complete);
@@ -1058,14 +1207,45 @@ mac_reset_top:
*/
autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+
+ /* Enable link if disabled in NVM */
+ if (autoc2 & IXGBE_AUTOC2_LINK_DISABLE_MASK) {
+ autoc2 &= ~IXGBE_AUTOC2_LINK_DISABLE_MASK;
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2);
+ IXGBE_WRITE_FLUSH(hw);
+ }
+
if (hw->mac.orig_link_settings_stored == FALSE) {
hw->mac.orig_autoc = autoc;
hw->mac.orig_autoc2 = autoc2;
+ hw->mac.cached_autoc = autoc;
hw->mac.orig_link_settings_stored = TRUE;
} else {
- if (autoc != hw->mac.orig_autoc)
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc |
- IXGBE_AUTOC_AN_RESTART));
+ if (autoc != hw->mac.orig_autoc) {
+ /* Need SW/FW semaphore around AUTOC writes if LESM is
+ * on, likewise reset_pipeline requires us to hold
+ * this lock as it also writes to AUTOC.
+ */
+ bool got_lock = FALSE;
+ if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+ status = hw->mac.ops.acquire_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ if (status != IXGBE_SUCCESS) {
+ status = IXGBE_ERR_SWFW_SYNC;
+ goto reset_hw_out;
+ }
+
+ got_lock = TRUE;
+ }
+
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
+ hw->mac.cached_autoc = hw->mac.orig_autoc;
+ ixgbe_reset_pipeline_82599(hw);
+
+ if (got_lock)
+ hw->mac.ops.release_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ }
if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
(hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) {
@@ -1170,7 +1350,7 @@ s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)
if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
IXGBE_FDIRCTRL_INIT_DONE)
break;
- usec_delay(10);
+ msec_delay(1);
}
if (i >= IXGBE_FDIR_INIT_DONE_POLL) {
DEBUGOUT("Flow Director Signature poll time exceeded!\n");
@@ -2096,7 +2276,7 @@ s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
* Returns IXGBE_ERR_EEPROM_VERSION if the FW is not present or
* if the FW version is not supported.
**/
-static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
+s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
{
s32 status = IXGBE_ERR_EEPROM_VERSION;
u16 fw_offset, fw_ptp_cfg_offset;
@@ -2245,4 +2425,55 @@ static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
return ret_val;
}
+/**
+ * ixgbe_reset_pipeline_82599 - perform pipeline reset
+ *
+ * @hw: pointer to hardware structure
+ *
+ * Reset pipeline by asserting Restart_AN together with LMS change to ensure
+ * full pipeline reset
+ **/
+s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw)
+{
+ s32 ret_val;
+ u32 anlp1_reg = 0;
+ u32 i, autoc_reg, autoc2_reg;
+
+ /* Enable link if disabled in NVM */
+ autoc2_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+ if (autoc2_reg & IXGBE_AUTOC2_LINK_DISABLE_MASK) {
+ autoc2_reg &= ~IXGBE_AUTOC2_LINK_DISABLE_MASK;
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2_reg);
+ IXGBE_WRITE_FLUSH(hw);
+ }
+
+ autoc_reg = hw->mac.cached_autoc;
+ autoc_reg |= IXGBE_AUTOC_AN_RESTART;
+ /* Write AUTOC register with toggled LMS[2] bit and Restart_AN */
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg ^ IXGBE_AUTOC_LMS_1G_AN);
+ /* Wait for AN to leave state 0 */
+ for (i = 0; i < 10; i++) {
+ msec_delay(4);
+ anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1);
+ if (anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)
+ break;
+ }
+
+ if (!(anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)) {
+ DEBUGOUT("auto negotiation not completed\n");
+ ret_val = IXGBE_ERR_RESET_FAILED;
+ goto reset_pipeline_out;
+ }
+
+ ret_val = IXGBE_SUCCESS;
+
+reset_pipeline_out:
+ /* Write AUTOC register with original LMS field and Restart_AN */
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return ret_val;
+}
+
+
diff --git a/sys/dev/pci/ixgbe/ixgbe_82599.h b/sys/dev/pci/ixgbe/ixgbe_82599.h
index dca39b7af12..5de1f09c17e 100644
--- a/sys/dev/pci/ixgbe/ixgbe_82599.h
+++ b/sys/dev/pci/ixgbe/ixgbe_82599.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD$*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_82599.h 247822 2013-03-04 23:07:40Z jfv $*/
#ifndef _IXGBE_82599_H_
#define _IXGBE_82599_H_
@@ -42,15 +42,15 @@ void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+ ixgbe_link_speed speed,
bool autoneg_wait_to_complete);
s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+ ixgbe_link_speed speed,
bool autoneg_wait_to_complete);
s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
bool autoneg_wait_to_complete);
s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg, bool autoneg_wait_to_complete);
+ bool autoneg_wait_to_complete);
s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw);
void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw);
s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw);
@@ -61,5 +61,4 @@ s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw);
s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw);
u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw);
s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval);
-bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw);
#endif /* _IXGBE_82599_H_ */
diff --git a/sys/dev/pci/ixgbe/ixgbe_api.c b/sys/dev/pci/ixgbe/ixgbe_api.c
index ce847f41f41..6323f2a18e8 100644
--- a/sys/dev/pci/ixgbe/ixgbe_api.c
+++ b/sys/dev/pci/ixgbe/ixgbe_api.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,8 +30,8 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_api.c 238149 2012-07-05 20:51:44Z jfv $*/
-/*$NetBSD: ixgbe_api.c,v 1.6 2015/04/02 09:26:55 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_api.c 247822 2013-03-04 23:07:40Z jfv $*/
+/*$NetBSD: ixgbe_api.c,v 1.7 2015/04/24 07:00:51 msaitoh Exp $*/
#include "ixgbe_api.h"
#include "ixgbe_common.h"
@@ -94,55 +94,54 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw)
DEBUGFUNC("ixgbe_set_mac_type\n");
- if (hw->vendor_id == IXGBE_INTEL_VENDOR_ID) {
- switch (hw->device_id) {
- case IXGBE_DEV_ID_82598:
- case IXGBE_DEV_ID_82598_BX:
- case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
- case IXGBE_DEV_ID_82598AF_DUAL_PORT:
- case IXGBE_DEV_ID_82598AT:
- case IXGBE_DEV_ID_82598AT2:
- case IXGBE_DEV_ID_82598EB_CX4:
- case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
- case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
- case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
- case IXGBE_DEV_ID_82598EB_XF_LR:
- case IXGBE_DEV_ID_82598EB_SFP_LOM:
- hw->mac.type = ixgbe_mac_82598EB;
- break;
- case IXGBE_DEV_ID_82599_KX4:
- case IXGBE_DEV_ID_82599_KX4_MEZZ:
- case IXGBE_DEV_ID_82599_XAUI_LOM:
- case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
- case IXGBE_DEV_ID_82599_KR:
- case IXGBE_DEV_ID_82599_SFP:
- case IXGBE_DEV_ID_82599_BACKPLANE_FCOE:
- case IXGBE_DEV_ID_82599_SFP_FCOE:
- case IXGBE_DEV_ID_82599_SFP_EM:
- case IXGBE_DEV_ID_82599_SFP_SF2:
- case IXGBE_DEV_ID_82599_SFP_SF_QP:
- case IXGBE_DEV_ID_82599EN_SFP:
- case IXGBE_DEV_ID_82599_CX4:
- case IXGBE_DEV_ID_82599_T3_LOM:
- hw->mac.type = ixgbe_mac_82599EB;
- break;
- case IXGBE_DEV_ID_82599_VF:
- hw->mac.type = ixgbe_mac_82599_vf;
- break;
- case IXGBE_DEV_ID_X540_VF:
- hw->mac.type = ixgbe_mac_X540_vf;
- break;
- case IXGBE_DEV_ID_X540T:
- case IXGBE_DEV_ID_X540T1:
- hw->mac.type = ixgbe_mac_X540;
- break;
- default:
- ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED;
- break;
- }
- } else {
- ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED;
- }
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_82598:
+ case IXGBE_DEV_ID_82598_BX:
+ case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
+ case IXGBE_DEV_ID_82598AF_DUAL_PORT:
+ case IXGBE_DEV_ID_82598AT:
+ case IXGBE_DEV_ID_82598AT2:
+ case IXGBE_DEV_ID_82598EB_CX4:
+ case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
+ case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
+ case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
+ case IXGBE_DEV_ID_82598EB_XF_LR:
+ case IXGBE_DEV_ID_82598EB_SFP_LOM:
+ hw->mac.type = ixgbe_mac_82598EB;
+ break;
+ case IXGBE_DEV_ID_82599_KX4:
+ case IXGBE_DEV_ID_82599_KX4_MEZZ:
+ case IXGBE_DEV_ID_82599_XAUI_LOM:
+ case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
+ case IXGBE_DEV_ID_82599_KR:
+ case IXGBE_DEV_ID_82599_SFP:
+ case IXGBE_DEV_ID_82599_BACKPLANE_FCOE:
+ case IXGBE_DEV_ID_82599_SFP_FCOE:
+ case IXGBE_DEV_ID_82599_SFP_EM:
+ case IXGBE_DEV_ID_82599_SFP_SF2:
+ case IXGBE_DEV_ID_82599_SFP_SF_QP:
+ case IXGBE_DEV_ID_82599EN_SFP:
+ case IXGBE_DEV_ID_82599_CX4:
+ case IXGBE_DEV_ID_82599_BYPASS:
+ case IXGBE_DEV_ID_82599_T3_LOM:
+ hw->mac.type = ixgbe_mac_82599EB;
+ break;
+ case IXGBE_DEV_ID_82599_VF:
+ case IXGBE_DEV_ID_82599_VF_HV:
+ hw->mac.type = ixgbe_mac_82599_vf;
+ break;
+ case IXGBE_DEV_ID_X540_VF:
+ case IXGBE_DEV_ID_X540_VF_HV:
+ hw->mac.type = ixgbe_mac_X540_vf;
+ break;
+ case IXGBE_DEV_ID_X540T:
+ case IXGBE_DEV_ID_X540_BYPASS:
+ hw->mac.type = ixgbe_mac_X540;
+ break;
+ default:
+ ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED;
+ break;
+ }
DEBUGOUT2("ixgbe_set_mac_type found mac: %d, returns: %d\n",
hw->mac.type, ret_val);
@@ -509,16 +508,14 @@ s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
* ixgbe_setup_phy_link_speed - Set auto advertise
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
*
* Sets the auto advertised capabilities
**/
s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete)
{
return ixgbe_call_func(hw, hw->phy.ops.setup_link_speed, (hw, speed,
- autoneg, autoneg_wait_to_complete),
+ autoneg_wait_to_complete),
IXGBE_NOT_IMPLEMENTED);
}
@@ -578,17 +575,15 @@ void ixgbe_flap_tx_laser(struct ixgbe_hw *hw)
* ixgbe_setup_link - Set link speed
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
*
* Configures link settings. Restarts the link.
* Performs autonegotiation if needed.
**/
s32 ixgbe_setup_link(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete)
{
return ixgbe_call_func(hw, hw->mac.ops.setup_link, (hw, speed,
- autoneg, autoneg_wait_to_complete),
+ autoneg_wait_to_complete),
IXGBE_NOT_IMPLEMENTED);
}
diff --git a/sys/dev/pci/ixgbe/ixgbe_api.h b/sys/dev/pci/ixgbe/ixgbe_api.h
index a5da1d79af8..56a744b2843 100644
--- a/sys/dev/pci/ixgbe/ixgbe_api.h
+++ b/sys/dev/pci/ixgbe/ixgbe_api.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,8 +30,8 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_api.h 238149 2012-07-05 20:51:44Z jfv $*/
-/*$NetBSD: ixgbe_api.h,v 1.3 2015/04/02 09:26:55 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_api.h 247822 2013-03-04 23:07:40Z jfv $*/
+/*$NetBSD: ixgbe_api.h,v 1.4 2015/04/24 07:00:51 msaitoh Exp $*/
#ifndef _IXGBE_API_H_
#define _IXGBE_API_H_
@@ -73,13 +73,12 @@ s32 ixgbe_check_phy_link(struct ixgbe_hw *hw,
bool *link_up);
s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete);
void ixgbe_disable_tx_laser(struct ixgbe_hw *hw);
void ixgbe_enable_tx_laser(struct ixgbe_hw *hw);
void ixgbe_flap_tx_laser(struct ixgbe_hw *hw);
s32 ixgbe_setup_link(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg, bool autoneg_wait_to_complete);
+ bool autoneg_wait_to_complete);
s32 ixgbe_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
bool *link_up, bool link_up_wait_to_complete);
s32 ixgbe_get_link_capabilities(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
@@ -160,6 +159,7 @@ void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
union ixgbe_atr_input *mask);
u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input,
union ixgbe_atr_hash_dword common);
+bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw);
s32 ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
u8 *data);
s32 ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
diff --git a/sys/dev/pci/ixgbe/ixgbe_common.c b/sys/dev/pci/ixgbe/ixgbe_common.c
index 74f1327939b..b3c95ce2a8b 100644
--- a/sys/dev/pci/ixgbe/ixgbe_common.c
+++ b/sys/dev/pci/ixgbe/ixgbe_common.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
******************************************************************************/
/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_common.c 238149 2012-07-05 20:51:44Z jfv $*/
-/*$NetBSD: ixgbe_common.c,v 1.4 2015/04/02 09:26:55 msaitoh Exp $*/
+/*$NetBSD: ixgbe_common.c,v 1.5 2015/04/24 07:00:51 msaitoh Exp $*/
#include "ixgbe_common.h"
#include "ixgbe_phy.h"
@@ -148,16 +148,14 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
* function check the device id to see if the associated phy supports
* autoneg flow control.
**/
-static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
+s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
{
DEBUGFUNC("ixgbe_device_supports_autoneg_fc");
switch (hw->device_id) {
- case IXGBE_DEV_ID_X540T:
- case IXGBE_DEV_ID_X540T1:
- return IXGBE_SUCCESS;
case IXGBE_DEV_ID_82599_T3_LOM:
+ case IXGBE_DEV_ID_X540T:
return IXGBE_SUCCESS;
default:
return IXGBE_ERR_FC_NOT_SUPPORTED;
@@ -175,6 +173,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
s32 ret_val = IXGBE_SUCCESS;
u32 reg = 0, reg_bp = 0;
u16 reg_cu = 0;
+ bool got_lock = FALSE;
DEBUGFUNC("ixgbe_setup_fc");
@@ -201,6 +200,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
* we link at 10G, the 1G advertisement is harmless and vice versa.
*/
switch (hw->phy.media_type) {
+ case ixgbe_media_type_fiber_fixed:
case ixgbe_media_type_fiber:
case ixgbe_media_type_backplane:
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
@@ -298,7 +298,28 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
*/
if (hw->phy.media_type == ixgbe_media_type_backplane) {
reg_bp |= IXGBE_AUTOC_AN_RESTART;
+ /* Need the SW/FW semaphore around AUTOC writes if 82599 and
+ * LESM is on, likewise reset_pipeline requries the lock as
+ * it also writes AUTOC.
+ */
+ if ((hw->mac.type == ixgbe_mac_82599EB) &&
+ ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+ ret_val = hw->mac.ops.acquire_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ if (ret_val != IXGBE_SUCCESS) {
+ ret_val = IXGBE_ERR_SWFW_SYNC;
+ goto out;
+ }
+ got_lock = TRUE;
+ }
+
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp);
+ if (hw->mac.type == ixgbe_mac_82599EB)
+ ixgbe_reset_pipeline_82599(hw);
+
+ if (got_lock)
+ hw->mac.ops.release_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
} else if ((hw->phy.media_type == ixgbe_media_type_copper) &&
(ixgbe_device_supports_autoneg_fc(hw) == IXGBE_SUCCESS)) {
hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
@@ -681,6 +702,195 @@ s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num)
}
/**
+ * ixgbe_read_pba_raw
+ * @hw: pointer to the HW structure
+ * @eeprom_buf: optional pointer to EEPROM image
+ * @eeprom_buf_size: size of EEPROM image in words
+ * @max_pba_block_size: PBA block size limit
+ * @pba: pointer to output PBA structure
+ *
+ * Reads PBA from EEPROM image when eeprom_buf is not NULL.
+ * Reads PBA from physical EEPROM device when eeprom_buf is NULL.
+ *
+ **/
+s32 ixgbe_read_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
+ u32 eeprom_buf_size, u16 max_pba_block_size,
+ struct ixgbe_pba *pba)
+{
+ s32 ret_val;
+ u16 pba_block_size;
+
+ if (pba == NULL)
+ return IXGBE_ERR_PARAM;
+
+ if (eeprom_buf == NULL) {
+ ret_val = hw->eeprom.ops.read_buffer(hw, IXGBE_PBANUM0_PTR, 2,
+ &pba->word[0]);
+ if (ret_val)
+ return ret_val;
+ } else {
+ if (eeprom_buf_size > IXGBE_PBANUM1_PTR) {
+ pba->word[0] = eeprom_buf[IXGBE_PBANUM0_PTR];
+ pba->word[1] = eeprom_buf[IXGBE_PBANUM1_PTR];
+ } else {
+ return IXGBE_ERR_PARAM;
+ }
+ }
+
+ if (pba->word[0] == IXGBE_PBANUM_PTR_GUARD) {
+ if (pba->pba_block == NULL)
+ return IXGBE_ERR_PARAM;
+
+ ret_val = ixgbe_get_pba_block_size(hw, eeprom_buf,
+ eeprom_buf_size,
+ &pba_block_size);
+ if (ret_val)
+ return ret_val;
+
+ if (pba_block_size > max_pba_block_size)
+ return IXGBE_ERR_PARAM;
+
+ if (eeprom_buf == NULL) {
+ ret_val = hw->eeprom.ops.read_buffer(hw, pba->word[1],
+ pba_block_size,
+ pba->pba_block);
+ if (ret_val)
+ return ret_val;
+ } else {
+ if (eeprom_buf_size > (u32)(pba->word[1] +
+ pba->pba_block[0])) {
+ memcpy(pba->pba_block,
+ &eeprom_buf[pba->word[1]],
+ pba_block_size * sizeof(u16));
+ } else {
+ return IXGBE_ERR_PARAM;
+ }
+ }
+ }
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_write_pba_raw
+ * @hw: pointer to the HW structure
+ * @eeprom_buf: optional pointer to EEPROM image
+ * @eeprom_buf_size: size of EEPROM image in words
+ * @pba: pointer to PBA structure
+ *
+ * Writes PBA to EEPROM image when eeprom_buf is not NULL.
+ * Writes PBA to physical EEPROM device when eeprom_buf is NULL.
+ *
+ **/
+s32 ixgbe_write_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
+ u32 eeprom_buf_size, struct ixgbe_pba *pba)
+{
+ s32 ret_val;
+
+ if (pba == NULL)
+ return IXGBE_ERR_PARAM;
+
+ if (eeprom_buf == NULL) {
+ ret_val = hw->eeprom.ops.write_buffer(hw, IXGBE_PBANUM0_PTR, 2,
+ &pba->word[0]);
+ if (ret_val)
+ return ret_val;
+ } else {
+ if (eeprom_buf_size > IXGBE_PBANUM1_PTR) {
+ eeprom_buf[IXGBE_PBANUM0_PTR] = pba->word[0];
+ eeprom_buf[IXGBE_PBANUM1_PTR] = pba->word[1];
+ } else {
+ return IXGBE_ERR_PARAM;
+ }
+ }
+
+ if (pba->word[0] == IXGBE_PBANUM_PTR_GUARD) {
+ if (pba->pba_block == NULL)
+ return IXGBE_ERR_PARAM;
+
+ if (eeprom_buf == NULL) {
+ ret_val = hw->eeprom.ops.write_buffer(hw, pba->word[1],
+ pba->pba_block[0],
+ pba->pba_block);
+ if (ret_val)
+ return ret_val;
+ } else {
+ if (eeprom_buf_size > (u32)(pba->word[1] +
+ pba->pba_block[0])) {
+ memcpy(&eeprom_buf[pba->word[1]],
+ pba->pba_block,
+ pba->pba_block[0] * sizeof(u16));
+ } else {
+ return IXGBE_ERR_PARAM;
+ }
+ }
+ }
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_get_pba_block_size
+ * @hw: pointer to the HW structure
+ * @eeprom_buf: optional pointer to EEPROM image
+ * @eeprom_buf_size: size of EEPROM image in words
+ * @pba_data_size: pointer to output variable
+ *
+ * Returns the size of the PBA block in words. Function operates on EEPROM
+ * image if the eeprom_buf pointer is not NULL otherwise it accesses physical
+ * EEPROM device.
+ *
+ **/
+s32 ixgbe_get_pba_block_size(struct ixgbe_hw *hw, u16 *eeprom_buf,
+ u32 eeprom_buf_size, u16 *pba_block_size)
+{
+ s32 ret_val;
+ u16 pba_word[2];
+ u16 length;
+
+ DEBUGFUNC("ixgbe_get_pba_block_size");
+
+ if (eeprom_buf == NULL) {
+ ret_val = hw->eeprom.ops.read_buffer(hw, IXGBE_PBANUM0_PTR, 2,
+ &pba_word[0]);
+ if (ret_val)
+ return ret_val;
+ } else {
+ if (eeprom_buf_size > IXGBE_PBANUM1_PTR) {
+ pba_word[0] = eeprom_buf[IXGBE_PBANUM0_PTR];
+ pba_word[1] = eeprom_buf[IXGBE_PBANUM1_PTR];
+ } else {
+ return IXGBE_ERR_PARAM;
+ }
+ }
+
+ if (pba_word[0] == IXGBE_PBANUM_PTR_GUARD) {
+ if (eeprom_buf == NULL) {
+ ret_val = hw->eeprom.ops.read(hw, pba_word[1] + 0,
+ &length);
+ if (ret_val)
+ return ret_val;
+ } else {
+ if (eeprom_buf_size > pba_word[1])
+ length = eeprom_buf[pba_word[1] + 0];
+ else
+ return IXGBE_ERR_PARAM;
+ }
+
+ if (length == 0xFFFF || length == 0)
+ return IXGBE_ERR_PBA_SECTION;
+ } else {
+ /* PBA number in legacy format, there is no PBA Block. */
+ length = 0;
+ }
+
+ if (pba_block_size != NULL)
+ *pba_block_size = length;
+
+ return IXGBE_SUCCESS;
+}
+
+/**
* ixgbe_get_mac_addr_generic - Generic get MAC address
* @hw: pointer to hardware structure
* @mac_addr: Adapter MAC address
@@ -1269,7 +1479,7 @@ s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
}
for (i = 0; i < words; i++) {
- eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) +
+ eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
IXGBE_EEPROM_RW_REG_START;
IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
@@ -2720,6 +2930,7 @@ void ixgbe_fc_autoneg(struct ixgbe_hw *hw)
switch (hw->phy.media_type) {
/* Autoneg flow control on fiber adapters */
+ case ixgbe_media_type_fiber_fixed:
case ixgbe_media_type_fiber:
if (speed == IXGBE_LINK_SPEED_1GB_FULL)
ret_val = ixgbe_fc_autoneg_fiber(hw);
@@ -2966,6 +3177,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
bool link_up = 0;
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+ s32 ret_val = IXGBE_SUCCESS;
DEBUGFUNC("ixgbe_blink_led_start_generic");
@@ -2976,10 +3188,29 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
hw->mac.ops.check_link(hw, &speed, &link_up, FALSE);
if (!link_up) {
+ /* Need the SW/FW semaphore around AUTOC writes if 82599 and
+ * LESM is on.
+ */
+ bool got_lock = FALSE;
+ if ((hw->mac.type == ixgbe_mac_82599EB) &&
+ ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+ ret_val = hw->mac.ops.acquire_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ if (ret_val != IXGBE_SUCCESS) {
+ ret_val = IXGBE_ERR_SWFW_SYNC;
+ goto out;
+ }
+ got_lock = TRUE;
+ }
+
autoc_reg |= IXGBE_AUTOC_AN_RESTART;
autoc_reg |= IXGBE_AUTOC_FLU;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
IXGBE_WRITE_FLUSH(hw);
+
+ if (got_lock)
+ hw->mac.ops.release_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
msec_delay(10);
}
@@ -2988,7 +3219,8 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
IXGBE_WRITE_FLUSH(hw);
- return IXGBE_SUCCESS;
+out:
+ return ret_val;
}
/**
@@ -3000,21 +3232,43 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
{
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+ s32 ret_val = IXGBE_SUCCESS;
+ bool got_lock = FALSE;
DEBUGFUNC("ixgbe_blink_led_stop_generic");
+ /* Need the SW/FW semaphore around AUTOC writes if 82599 and
+ * LESM is on.
+ */
+ if ((hw->mac.type == ixgbe_mac_82599EB) &&
+ ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+ ret_val = hw->mac.ops.acquire_swfw_sync(hw,
+ IXGBE_GSSR_MAC_CSR_SM);
+ if (ret_val != IXGBE_SUCCESS) {
+ ret_val = IXGBE_ERR_SWFW_SYNC;
+ goto out;
+ }
+ got_lock = TRUE;
+ }
autoc_reg &= ~IXGBE_AUTOC_FLU;
autoc_reg |= IXGBE_AUTOC_AN_RESTART;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+ if (hw->mac.type == ixgbe_mac_82599EB)
+ ixgbe_reset_pipeline_82599(hw);
+
+ if (got_lock)
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+
led_reg &= ~IXGBE_LED_MODE_MASK(index);
led_reg &= ~IXGBE_LED_BLINK(index);
led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
IXGBE_WRITE_FLUSH(hw);
- return IXGBE_SUCCESS;
+out:
+ return ret_val;
}
/**
@@ -3883,7 +4137,7 @@ void ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw *hw)
* Calculates the checksum for some buffer on a specified length. The
* checksum calculated is returned.
**/
-static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
+u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
{
u32 i;
u8 sum = 0;
@@ -3909,8 +4163,8 @@ static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
* Communicates with the manageability block. On success return IXGBE_SUCCESS
* else return IXGBE_ERR_HOST_INTERFACE_COMMAND.
**/
-static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
- u32 length)
+s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
+ u32 length)
{
u32 hicr, i, bi;
u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
diff --git a/sys/dev/pci/ixgbe/ixgbe_common.h b/sys/dev/pci/ixgbe/ixgbe_common.h
index 22d8249173d..5455d70efec 100644
--- a/sys/dev/pci/ixgbe/ixgbe_common.h
+++ b/sys/dev/pci/ixgbe/ixgbe_common.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,8 +30,8 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_common.h 238149 2012-07-05 20:51:44Z jfv $*/
-/*$NetBSD: ixgbe_common.h,v 1.3 2015/04/02 09:26:55 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_common.h 247822 2013-03-04 23:07:40Z jfv $*/
+/*$NetBSD: ixgbe_common.h,v 1.4 2015/04/24 07:00:51 msaitoh Exp $*/
#ifndef _IXGBE_COMMON_H_
#define _IXGBE_COMMON_H_
@@ -42,9 +42,14 @@
IXGBE_WRITE_REG(hw, reg, (u32) value); \
IXGBE_WRITE_REG(hw, reg + 4, (u32) (value >> 32)); \
} while (0)
+#if !defined(NO_READ_PBA_RAW) || !defined(NO_WRITE_PBA_RAW)
+struct ixgbe_pba {
+ u16 word[2];
+ u16 *pba_block;
+};
+#endif
u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw);
-
s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw);
s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw);
s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw);
@@ -53,6 +58,13 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw);
s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num);
s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num,
u32 pba_num_size);
+s32 ixgbe_read_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
+ u32 eeprom_buf_size, u16 max_pba_block_size,
+ struct ixgbe_pba *pba);
+s32 ixgbe_write_pba_raw(struct ixgbe_hw *hw, u16 *eeprom_buf,
+ u32 eeprom_buf_size, struct ixgbe_pba *pba);
+s32 ixgbe_get_pba_block_size(struct ixgbe_hw *hw, u16 *eeprom_buf,
+ u32 eeprom_buf_size, u16 *pba_block_size);
s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr);
s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw);
void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw);
@@ -97,6 +109,7 @@ s32 ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw *hw);
s32 ixgbe_enable_sec_rx_path_generic(struct ixgbe_hw *hw);
s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw);
+s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw);
void ixgbe_fc_autoneg(struct ixgbe_hw *hw);
s32 ixgbe_validate_mac_addr(u8 *mac_addr);
@@ -138,5 +151,11 @@ void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw, int num_pb, u32 headroom,
void ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw *hw);
s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
u8 build, u8 ver);
+u8 ixgbe_calculate_checksum(u8 *buffer, u32 length);
+s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
+ u32 length);
void ixgbe_clear_tx_pending(struct ixgbe_hw *hw);
+
+extern s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw);
+
#endif /* IXGBE_COMMON */
diff --git a/sys/dev/pci/ixgbe/ixgbe_mbx.h b/sys/dev/pci/ixgbe/ixgbe_mbx.h
index 6d019b56048..c4e7c2b9596 100644
--- a/sys/dev/pci/ixgbe/ixgbe_mbx.h
+++ b/sys/dev/pci/ixgbe/ixgbe_mbx.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,8 +30,8 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: src/sys/dev/ixgbe/ixgbe_mbx.h,v 1.1 2010/11/26 22:46:32 jfv Exp $*/
-/*$NetBSD: ixgbe_mbx.h,v 1.3 2015/04/02 09:26:55 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_mbx.h 247822 2013-03-04 23:07:40Z jfv $*/
+/*$NetBSD: ixgbe_mbx.h,v 1.4 2015/04/24 07:00:51 msaitoh Exp $*/
#ifndef _IXGBE_MBX_H_
#define _IXGBE_MBX_H_
@@ -85,8 +85,20 @@
#define IXGBE_VF_SET_MAC_ADDR 0x02 /* VF requests PF to set MAC addr */
#define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
#define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */
+
+/* mailbox API, version 1.0 VF requests */
#define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */
#define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */
+#define IXGBE_VF_API_NEGOTIATE 0x08 /* negotiate API version */
+
+/* mailbox API, version 1.1 VF requests */
+#define IXGBE_VF_GET_QUEUES 0x09 /* get queue configuration */
+
+/* GET_QUEUES return data indices within the mailbox */
+#define IXGBE_VF_TX_QUEUES 1 /* number of Tx queues supported */
+#define IXGBE_VF_RX_QUEUES 2 /* number of Rx queues supported */
+#define IXGBE_VF_TRANS_VLAN 3 /* Indication of port vlan */
+#define IXGBE_VF_DEF_QUEUE 4 /* Default queue offset */
/* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4
diff --git a/sys/dev/pci/ixgbe/ixgbe_netbsd.h b/sys/dev/pci/ixgbe/ixgbe_netbsd.h
index 672c3a29ff7..e2923bc20ae 100644
--- a/sys/dev/pci/ixgbe/ixgbe_netbsd.h
+++ b/sys/dev/pci/ixgbe/ixgbe_netbsd.h
@@ -1,4 +1,4 @@
-/*$NetBSD: ixgbe_netbsd.h,v 1.2 2014/04/17 16:22:48 christos Exp $*/
+/*$NetBSD: ixgbe_netbsd.h,v 1.3 2015/04/24 07:00:51 msaitoh Exp $*/
/*
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -31,6 +31,8 @@
#ifndef _IXGBE_NETBSD_H
#define _IXGBE_NETBSD_H
+#define IXGBE_LEGACY_TX 1
+
#define ETHERCAP_VLAN_HWFILTER 0
#define ETHERCAP_VLAN_HWCSUM 0
#define MJUM9BYTES (9 * 1024)
diff --git a/sys/dev/pci/ixgbe/ixgbe_osdep.h b/sys/dev/pci/ixgbe/ixgbe_osdep.h
index 6c5eece734c..f1a9245ec6e 100644
--- a/sys/dev/pci/ixgbe/ixgbe_osdep.h
+++ b/sys/dev/pci/ixgbe/ixgbe_osdep.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,8 +30,8 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_osdep.h 240466 2012-09-13 14:40:24Z eadler $*/
-/*$NetBSD: ixgbe_osdep.h,v 1.6 2015/04/14 07:17:06 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_osdep.h 247822 2013-03-04 23:07:40Z jfv $*/
+/*$NetBSD: ixgbe_osdep.h,v 1.7 2015/04/24 07:00:51 msaitoh Exp $*/
#ifndef _IXGBE_OS_H_
#define _IXGBE_OS_H_
@@ -91,6 +91,9 @@
#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */
#define PCI_COMMAND_REGISTER PCIR_COMMAND
+/* Shared code dropped this define.. */
+#define IXGBE_INTEL_VENDOR_ID 0x8086
+
/* Bunch of defines for shared code bogosity */
#define UNREFERENCED_PARAMETER(_p)
#define UNREFERENCED_1PARAMETER(_p)
diff --git a/sys/dev/pci/ixgbe/ixgbe_phy.c b/sys/dev/pci/ixgbe/ixgbe_phy.c
index 48793920bda..3d37ddbd42a 100644
--- a/sys/dev/pci/ixgbe/ixgbe_phy.c
+++ b/sys/dev/pci/ixgbe/ixgbe_phy.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,8 +30,8 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_phy.c 238149 2012-07-05 20:51:44Z jfv $*/
-/*$NetBSD: ixgbe_phy.c,v 1.4 2015/04/02 09:26:55 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_phy.c 247822 2013-03-04 23:07:40Z jfv $*/
+/*$NetBSD: ixgbe_phy.c,v 1.5 2015/04/24 07:00:51 msaitoh Exp $*/
#include "ixgbe_api.h"
#include "ixgbe_common.h"
@@ -48,6 +48,8 @@ static void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
static bool ixgbe_get_i2c_data(u32 *i2cctl);
+static s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 *sff8472_data);
/**
* ixgbe_init_phy_ops_generic - Inits PHY function ptrs
@@ -72,6 +74,7 @@ s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw)
phy->ops.get_firmware_version = ixgbe_get_phy_firmware_version_generic;
phy->ops.read_i2c_byte = &ixgbe_read_i2c_byte_generic;
phy->ops.write_i2c_byte = &ixgbe_write_i2c_byte_generic;
+ phy->ops.read_i2c_sff8472 = &ixgbe_read_i2c_sff8472_generic;
phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic;
phy->ops.write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic;
phy->ops.i2c_bus_clear = &ixgbe_i2c_bus_clear;
@@ -564,14 +567,12 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
* ixgbe_setup_phy_link_speed_generic - Sets the auto advertised capabilities
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
**/
s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete)
{
- UNREFERENCED_2PARAMETER(autoneg, autoneg_wait_to_complete);
+ UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
DEBUGFUNC("ixgbe_setup_phy_link_speed_generic");
@@ -970,9 +971,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
IXGBE_SFF_IDENTIFIER,
&identifier);
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
+ if (status != IXGBE_SUCCESS)
goto err_read_i2c_eeprom;
/* LAN ID is needed for sfp_type determination */
@@ -986,26 +985,20 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
IXGBE_SFF_1GBE_COMP_CODES,
&comp_codes_1g);
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
+ if (status != IXGBE_SUCCESS)
goto err_read_i2c_eeprom;
status = hw->phy.ops.read_i2c_eeprom(hw,
IXGBE_SFF_10GBE_COMP_CODES,
&comp_codes_10g);
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
+ if (status != IXGBE_SUCCESS)
goto err_read_i2c_eeprom;
status = hw->phy.ops.read_i2c_eeprom(hw,
IXGBE_SFF_CABLE_TECHNOLOGY,
&cable_tech);
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
+ if (status != IXGBE_SUCCESS)
goto err_read_i2c_eeprom;
/* ID Module
@@ -1103,27 +1096,21 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
IXGBE_SFF_VENDOR_OUI_BYTE0,
&oui_bytes[0]);
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
+ if (status != IXGBE_SUCCESS)
goto err_read_i2c_eeprom;
status = hw->phy.ops.read_i2c_eeprom(hw,
IXGBE_SFF_VENDOR_OUI_BYTE1,
&oui_bytes[1]);
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
+ if (status != IXGBE_SUCCESS)
goto err_read_i2c_eeprom;
status = hw->phy.ops.read_i2c_eeprom(hw,
IXGBE_SFF_VENDOR_OUI_BYTE2,
&oui_bytes[2]);
- if (status == IXGBE_ERR_SWFW_SYNC ||
- status == IXGBE_ERR_I2C ||
- status == IXGBE_ERR_SFP_NOT_PRESENT)
+ if (status != IXGBE_SUCCESS)
goto err_read_i2c_eeprom;
vendor_oui =
@@ -1334,6 +1321,22 @@ s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
}
/**
+ * ixgbe_read_i2c_sff8472_generic - Reads 8 bit word over I2C interface
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset at address 0xA2
+ * @eeprom_data: value read
+ *
+ * Performs byte read operation to SFP module's SFF-8472 data over I2C
+ **/
+static s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 *sff8472_data)
+{
+ return hw->phy.ops.read_i2c_byte(hw, byte_offset,
+ IXGBE_I2C_EEPROM_DEV_ADDR2,
+ sff8472_data);
+}
+
+/**
* ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface
* @hw: pointer to hardware structure
* @byte_offset: EEPROM byte offset to write
@@ -1426,9 +1429,9 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
break;
fail:
+ ixgbe_i2c_bus_clear(hw);
hw->mac.ops.release_swfw_sync(hw, swfw_mask);
msec_delay(100);
- ixgbe_i2c_bus_clear(hw);
retry++;
if (retry < max_retry)
DEBUGOUT("I2C byte read error - Retrying.\n");
diff --git a/sys/dev/pci/ixgbe/ixgbe_phy.h b/sys/dev/pci/ixgbe/ixgbe_phy.h
index a2808b5ba21..e7a5299d96b 100644
--- a/sys/dev/pci/ixgbe/ixgbe_phy.h
+++ b/sys/dev/pci/ixgbe/ixgbe_phy.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,14 +30,16 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: src/sys/dev/ixgbe/ixgbe_phy.h,v 1.11 2010/11/26 22:46:32 jfv Exp $*/
-/*$NetBSD: ixgbe_phy.h,v 1.3 2015/04/02 09:26:55 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_phy.h 247822 2013-03-04 23:07:40Z jfv $*/
+/*$NetBSD: ixgbe_phy.h,v 1.4 2015/04/24 07:00:51 msaitoh Exp $*/
#ifndef _IXGBE_PHY_H_
#define _IXGBE_PHY_H_
#include "ixgbe_type.h"
-#define IXGBE_I2C_EEPROM_DEV_ADDR 0xA0
+#define IXGBE_I2C_EEPROM_DEV_ADDR 0xA0
+#define IXGBE_I2C_EEPROM_DEV_ADDR2 0xA2
+#define IXGBE_I2C_EEPROM_BANK_LEN 0xFF
/* EEPROM byte offsets */
#define IXGBE_SFF_IDENTIFIER 0x0
@@ -49,6 +51,10 @@
#define IXGBE_SFF_10GBE_COMP_CODES 0x3
#define IXGBE_SFF_CABLE_TECHNOLOGY 0x8
#define IXGBE_SFF_CABLE_SPEC_COMP 0x3C
+#define IXGBE_SFF_SFF_8472_SWAP 0x5C
+#define IXGBE_SFF_SFF_8472_COMP 0x5E
+#define IXGBE_SFF_SFF_8472_OSCB 0x6E
+#define IXGBE_SFF_SFF_8472_ESCB 0x76
/* Bitmasks */
#define IXGBE_SFF_DA_PASSIVE_CABLE 0x4
@@ -59,6 +65,9 @@
#define IXGBE_SFF_1GBASET_CAPABLE 0x8
#define IXGBE_SFF_10GBASESR_CAPABLE 0x10
#define IXGBE_SFF_10GBASELR_CAPABLE 0x20
+#define IXGBE_SFF_SOFT_RS_SELECT_MASK 0x8
+#define IXGBE_SFF_SOFT_RS_SELECT_10G 0x8
+#define IXGBE_SFF_SOFT_RS_SELECT_1G 0x0
#define IXGBE_I2C_EEPROM_READ_MASK 0x100
#define IXGBE_I2C_EEPROM_STATUS_MASK 0x3
#define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION 0x0
@@ -96,6 +105,14 @@
#define IXGBE_TN_LASI_STATUS_REG 0x9005
#define IXGBE_TN_LASI_STATUS_TEMP_ALARM 0x0008
+/* SFP+ SFF-8472 Compliance */
+#define IXGBE_SFF_SFF_8472_UNSUP 0x00
+#define IXGBE_SFF_SFF_8472_REV_9_3 0x01
+#define IXGBE_SFF_SFF_8472_REV_9_5 0x02
+#define IXGBE_SFF_SFF_8472_REV_10_2 0x03
+#define IXGBE_SFF_SFF_8472_REV_10_4 0x04
+#define IXGBE_SFF_SFF_8472_REV_11_0 0x05
+
s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw);
bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
@@ -109,7 +126,6 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw);
s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
- bool autoneg,
bool autoneg_wait_to_complete);
s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw,
ixgbe_link_speed *speed,
diff --git a/sys/dev/pci/ixgbe/ixgbe_type.h b/sys/dev/pci/ixgbe/ixgbe_type.h
index ae454a412e9..504e2df0e48 100644
--- a/sys/dev/pci/ixgbe/ixgbe_type.h
+++ b/sys/dev/pci/ixgbe/ixgbe_type.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2010, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,8 +30,8 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_type.h 238149 2012-07-05 20:51:44Z jfv $*/
-/*$NetBSD: ixgbe_type.h,v 1.9 2015/04/02 09:26:55 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_type.h 247822 2013-03-04 23:07:40Z jfv $*/
+/*$NetBSD: ixgbe_type.h,v 1.10 2015/04/24 07:00:51 msaitoh Exp $*/
#ifndef _IXGBE_TYPE_H_
#define _IXGBE_TYPE_H_
@@ -45,9 +45,6 @@
#include "ixgbe_osdep.h"
-/* Vendor ID */
-#define IXGBE_INTEL_VENDOR_ID 0x8086
-
/* Device IDs */
#define IXGBE_DEV_ID_82598 0x10B6
#define IXGBE_DEV_ID_82598_BX 0x1508
@@ -69,7 +66,9 @@
#define IXGBE_DEV_ID_82599_CX4 PCI_PRODUCT_INTEL_82599_CX4
#define IXGBE_DEV_ID_82599_SFP PCI_PRODUCT_INTEL_82599_SFP
#define IXGBE_SUBDEV_ID_82599_SFP 0x11A9
+#define IXGBE_SUBDEV_ID_82599_RNDC 0x1F72
#define IXGBE_SUBDEV_ID_82599_560FLR 0x17D0
+#define IXGBE_SUBDEV_ID_82599_ECNA_DP 0x0470
#define IXGBE_DEV_ID_82599_BACKPLANE_FCOE 0x152A
#define IXGBE_DEV_ID_82599_SFP_FCOE 0x1529
#define IXGBE_DEV_ID_82599_SFP_SF2 0x154D
@@ -79,9 +78,13 @@
#define IXGBE_DEV_ID_82599_XAUI_LOM PCI_PRODUCT_INTEL_82599_XAUI_LOM
#define IXGBE_DEV_ID_82599_T3_LOM 0x151C
#define IXGBE_DEV_ID_82599_VF 0x10ED
-#define IXGBE_DEV_ID_X540_VF 0x1515
+#define IXGBE_DEV_ID_82599_VF_HV 0x152E
+#define IXGBE_DEV_ID_82599_BYPASS 0x155D
#define IXGBE_DEV_ID_X540T 0x1528
-#define IXGBE_DEV_ID_X540T1 0x1560
+#define IXGBE_DEV_ID_X540_VF 0x1515
+#define IXGBE_DEV_ID_X540_VF_HV 0x1530
+#define IXGBE_DEV_ID_X540_BYPASS 0x155C
+
/* General Registers */
#define IXGBE_CTRL 0x00000
@@ -289,6 +292,7 @@
#define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */
+
/* Flow Director registers */
#define IXGBE_FDIRCTRL 0x0EE00
#define IXGBE_FDIRHKEY 0x0EE68
@@ -374,7 +378,11 @@
/* Ext Flexible Host Filter Table */
#define IXGBE_FHFT_EXT(_n) (0x09800 + (_n * 0x100))
+/* Four Flexible Filters are supported */
#define IXGBE_FLEXIBLE_FILTER_COUNT_MAX 4
+
+/* Six Flexible Filters are supported */
+#define IXGBE_FLEXIBLE_FILTER_COUNT_MAX_6 6
#define IXGBE_EXT_FLEXIBLE_FILTER_COUNT_MAX 2
/* Each Flexible Filter is at most 128 (0x80) bytes in length */
@@ -409,7 +417,8 @@
#define IXGBE_WUFC_FLX_FILTERS 0x000F0000 /* Mask for 4 flex filters */
/* Mask for Ext. flex filters */
#define IXGBE_WUFC_EXT_FLX_FILTERS 0x00300000
-#define IXGBE_WUFC_ALL_FILTERS 0x003F00FF /* Mask for all wakeup filters */
+#define IXGBE_WUFC_ALL_FILTERS 0x000F00FF /* Mask all 4 flex filters */
+#define IXGBE_WUFC_ALL_FILTERS_6 0x003F00FF /* Mask all 6 flex filters */
#define IXGBE_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */
/* Wake Up Status */
@@ -584,6 +593,7 @@
#define IXGBE_RTTBCNRD 0x0498C
+
/* FCoE DMA Context Registers */
#define IXGBE_FCPTRL 0x02410 /* FC User Desc. PTR Low */
#define IXGBE_FCPTRH 0x02414 /* FC USer Desc. PTR High */
@@ -764,11 +774,14 @@
#define IXGBE_BMCIP_IPADDR_VALID 0x00000002
/* Management Bit Fields and Masks */
+#define IXGBE_MANC_RCV_TCO_EN 0x00020000 /* Rcv TCO packet enable */
#define IXGBE_MANC_EN_BMC2OS 0x10000000 /* Ena BMC2OS and OS2BMC traffic */
#define IXGBE_MANC_EN_BMC2OS_SHIFT 28
/* Firmware Semaphore Register */
#define IXGBE_FWSM_MODE_MASK 0xE
+#define IXGBE_FWSM_TS_ENABLED 0x1
+#define IXGBE_FWSM_FW_MODE_PT 0x4
/* ARC Subsystem registers */
#define IXGBE_HICR 0x15F00
@@ -1024,6 +1037,7 @@
#define IXGBE_RSCCTL_MAXDESC_4 0x04
#define IXGBE_RSCCTL_MAXDESC_8 0x08
#define IXGBE_RSCCTL_MAXDESC_16 0x0C
+#define IXGBE_RSCCTL_TS_DIS 0x02
/* RSCDBU Bit Masks */
#define IXGBE_RSCDBU_RSCSMALDIS_MASK 0x0000007F
@@ -1062,6 +1076,7 @@
#define IXGBE_CTRL_RST_MASK (IXGBE_CTRL_LNK_RST | IXGBE_CTRL_RST)
/* FACTPS */
+#define IXGBE_FACTPS_MNGCG 0x20000000 /* Manageblility Clock Gated */
#define IXGBE_FACTPS_LFS 0x40000000 /* LAN Function Select */
/* MHADD Bit Masks */
@@ -1600,6 +1615,7 @@ enum {
#define IXGBE_ESDP_SDP7 0x00000080 /* SDP7 Data Value */
#define IXGBE_ESDP_SDP0_DIR 0x00000100 /* SDP0 IO direction */
#define IXGBE_ESDP_SDP1_DIR 0x00000200 /* SDP1 IO direction */
+#define IXGBE_ESDP_SDP2_DIR 0x00000400 /* SDP1 IO direction */
#define IXGBE_ESDP_SDP3_DIR 0x00000800 /* SDP3 IO direction */
#define IXGBE_ESDP_SDP4_DIR 0x00001000 /* SDP4 IO direction */
#define IXGBE_ESDP_SDP5_DIR 0x00002000 /* SDP5 IO direction */
@@ -1678,6 +1694,7 @@ enum {
#define IXGBE_AUTOC2_10G_KR (0x0 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
#define IXGBE_AUTOC2_10G_XFI (0x1 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
#define IXGBE_AUTOC2_10G_SFI (0x2 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
+#define IXGBE_AUTOC2_LINK_DISABLE_MASK 0x70000000
#define IXGBE_MACC_FLU 0x00000001
#define IXGBE_MACC_FSV_10G 0x00030000
@@ -1848,7 +1865,7 @@ enum {
#define IXGBE_ETH_LENGTH_OF_ADDRESS ETHER_ADDR_LEN
#define IXGBE_EEPROM_PAGE_SIZE_MAX 128
-#define IXGBE_EEPROM_RD_BUFFER_MAX_COUNT 512 /* words rd in burst */
+#define IXGBE_EEPROM_RD_BUFFER_MAX_COUNT 256 /* words rd in burst */
#define IXGBE_EEPROM_WR_BUFFER_MAX_COUNT 256 /* words wr in burst */
#ifndef IXGBE_EEPROM_GRANT_ATTEMPTS
@@ -2766,6 +2783,7 @@ enum ixgbe_sfp_type {
enum ixgbe_media_type {
ixgbe_media_type_unknown = 0,
ixgbe_media_type_fiber,
+ ixgbe_media_type_fiber_fixed,
ixgbe_media_type_copper,
ixgbe_media_type_backplane,
ixgbe_media_type_cx4,
@@ -2991,7 +3009,7 @@ struct ixgbe_mac_operations {
void (*disable_tx_laser)(struct ixgbe_hw *);
void (*enable_tx_laser)(struct ixgbe_hw *);
void (*flap_tx_laser)(struct ixgbe_hw *);
- s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool);
+ s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool);
s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool);
s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *,
bool *);
@@ -3042,12 +3060,12 @@ struct ixgbe_phy_operations {
s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *);
s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16);
s32 (*setup_link)(struct ixgbe_hw *);
- s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool,
- bool);
+ s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool);
s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *);
s32 (*get_firmware_version)(struct ixgbe_hw *, u16 *);
s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *);
s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8);
+ s32 (*read_i2c_sff8472)(struct ixgbe_hw *, u8 , u8 *);
s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8);
void (*i2c_bus_clear)(struct ixgbe_hw *);
@@ -3085,7 +3103,9 @@ struct ixgbe_mac_info {
u32 max_tx_queues;
u32 max_rx_queues;
u32 orig_autoc;
+ u32 cached_autoc;
u8 san_mac_rar_index;
+ bool get_link_status;
u32 orig_autoc2;
u16 max_msix_vectors;
bool arc_subsystem_valid;
@@ -3157,6 +3177,7 @@ struct ixgbe_hw {
u16 subsystem_vendor_id;
u8 revision_id;
bool adapter_stopped;
+ int api_version;
bool force_full_reset;
bool allow_unsupported_sfp;
};
@@ -3200,6 +3221,7 @@ struct ixgbe_hw {
#define IXGBE_ERR_INVALID_ARGUMENT -32
#define IXGBE_ERR_HOST_INTERFACE_COMMAND -33
#define IXGBE_ERR_OUT_OF_MEM -34
+#define IXGBE_ERR_FEATURE_NOT_SUPPORTED -36
#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
diff --git a/sys/dev/pci/ixgbe/ixgbe_vf.c b/sys/dev/pci/ixgbe/ixgbe_vf.c
index d8430bf58af..ea0ccf77431 100644
--- a/sys/dev/pci/ixgbe/ixgbe_vf.c
+++ b/sys/dev/pci/ixgbe/ixgbe_vf.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,8 +30,8 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_vf.c 238149 2012-07-05 20:51:44Z jfv $*/
-/*$NetBSD: ixgbe_vf.c,v 1.3 2015/04/02 09:26:55 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_vf.c 247822 2013-03-04 23:07:40Z jfv $*/
+/*$NetBSD: ixgbe_vf.c,v 1.4 2015/04/24 07:00:51 msaitoh Exp $*/
#include "ixgbe_api.h"
@@ -143,6 +143,7 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw)
/* Call adapter stop to disable tx/rx and clear interrupts */
hw->mac.ops.stop_adapter(hw);
+
DEBUGOUT("Issuing a function level reset to MAC\n");
ctrl = IXGBE_VFREAD_REG(hw, IXGBE_VFCTRL) | IXGBE_CTRL_RST;
@@ -273,6 +274,17 @@ static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
return vector;
}
+static void ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw,
+ u32 *msg, u16 size)
+{
+ struct ixgbe_mbx_info *mbx = &hw->mbx;
+ u32 retmsg[IXGBE_VFMAILBOX_SIZE];
+ s32 retval = mbx->ops.write_posted(hw, msg, size, 0);
+
+ if (!retval)
+ mbx->ops.read_posted(hw, retmsg, size, 0);
+}
+
/**
* ixgbe_set_rar_vf - set device MAC address
* @hw: pointer to hardware structure
@@ -464,11 +476,10 @@ s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
*
* Set the link speed in the AUTOC register and restarts link.
**/
-s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed speed,
bool autoneg_wait_to_complete)
{
- UNREFERENCED_4PARAMETER(hw, speed, autoneg, autoneg_wait_to_complete);
+ UNREFERENCED_3PARAMETER(hw, speed, autoneg_wait_to_complete);
return IXGBE_SUCCESS;
}
@@ -484,23 +495,26 @@ s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw,
s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
bool *link_up, bool autoneg_wait_to_complete)
{
+ struct ixgbe_mbx_info *mbx = &hw->mbx;
+ struct ixgbe_mac_info *mac = &hw->mac;
+ s32 ret_val = IXGBE_SUCCESS;
u32 links_reg;
+ u32 in_msg = 0;
UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
- if (!(hw->mbx.ops.check_for_rst(hw, 0))) {
- *link_up = FALSE;
- *speed = 0;
- return -1;
- }
+ /* If we were hit with a reset drop the link */
+ if (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout)
+ mac->get_link_status = TRUE;
- links_reg = IXGBE_VFREAD_REG(hw, IXGBE_VFLINKS);
+ if (!mac->get_link_status)
+ goto out;
- if (links_reg & IXGBE_LINKS_UP)
- *link_up = TRUE;
- else
- *link_up = FALSE;
+ /* if link status is down no point in checking to see if pf is up */
+ links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
+ if (!(links_reg & IXGBE_LINKS_UP))
+ goto out;
- switch (links_reg & IXGBE_LINKS_SPEED_10G_82599) {
+ switch (links_reg & IXGBE_LINKS_SPEED_82599) {
case IXGBE_LINKS_SPEED_10G_82599:
*speed = IXGBE_LINK_SPEED_10GB_FULL;
break;
@@ -512,6 +526,87 @@ s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
break;
}
+ /* if the read failed it could just be a mailbox collision, best wait
+ * until we are called again and don't report an error
+ */
+ if (mbx->ops.read(hw, &in_msg, 1, 0))
+ goto out;
+
+ if (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) {
+ /* msg is not CTS and is NACK we must have lost CTS status */
+ if (in_msg & IXGBE_VT_MSGTYPE_NACK)
+ ret_val = -1;
+ goto out;
+ }
+
+ /* the pf is talking, if we timed out in the past we reinit */
+ if (!mbx->timeout) {
+ ret_val = -1;
+ goto out;
+ }
+
+ /* if we passed all the tests above then the link is up and we no
+ * longer need to check for link
+ */
+ mac->get_link_status = FALSE;
+
+out:
+ *link_up = !mac->get_link_status;
+ return ret_val;
+}
+
+/**
+ * ixgbevf_rlpml_set_vf - Set the maximum receive packet length
+ * @hw: pointer to the HW structure
+ * @max_size: value to assign to max frame size
+ **/
+void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size)
+{
+ u32 msgbuf[2];
+
+ msgbuf[0] = IXGBE_VF_SET_LPE;
+ msgbuf[1] = max_size;
+ ixgbevf_write_msg_read_ack(hw, msgbuf, 2);
+}
+
+/**
+ * ixgbevf_negotiate_api_version - Negotiate supported API version
+ * @hw: pointer to the HW structure
+ * @api: integer containing requested API version
+ **/
+int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api)
+{
+ int err;
+ u32 msg[3];
+
+ /* Negotiate the mailbox API version */
+ msg[0] = IXGBE_VF_API_NEGOTIATE;
+ msg[1] = api;
+ msg[2] = 0;
+ err = hw->mbx.ops.write_posted(hw, msg, 3, 0);
+
+ if (!err)
+ err = hw->mbx.ops.read_posted(hw, msg, 3, 0);
+
+ if (!err) {
+ msg[0] &= ~IXGBE_VT_MSGTYPE_CTS;
+
+ /* Store value and return 0 on success */
+ if (msg[0] == (IXGBE_VF_API_NEGOTIATE | IXGBE_VT_MSGTYPE_ACK)) {
+ hw->api_version = api;
+ return 0;
+ }
+
+ err = IXGBE_ERR_INVALID_ARGUMENT;
+ }
+
+ return err;
+}
+
+int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
+ unsigned int *default_tc)
+{
+ UNREFERENCED_3PARAMETER(hw, num_tcs, default_tc);
return IXGBE_SUCCESS;
}
diff --git a/sys/dev/pci/ixgbe/ixgbe_vf.h b/sys/dev/pci/ixgbe/ixgbe_vf.h
index dc3b59382ba..f922caffb7b 100644
--- a/sys/dev/pci/ixgbe/ixgbe_vf.h
+++ b/sys/dev/pci/ixgbe/ixgbe_vf.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,8 +30,8 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: src/sys/dev/ixgbe/ixgbe_vf.h,v 1.1 2010/11/26 22:46:32 jfv Exp $*/
-/*$NetBSD: ixgbe_vf.h,v 1.4 2015/04/02 09:26:55 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_vf.h 247822 2013-03-04 23:07:40Z jfv $*/
+/*$NetBSD: ixgbe_vf.h,v 1.5 2015/04/24 07:00:51 msaitoh Exp $*/
#ifndef __IXGBE_VF_H__
#define __IXGBE_VF_H__
@@ -40,6 +40,9 @@
#define IXGBE_VF_MAX_TX_QUEUES 8
#define IXGBE_VF_MAX_RX_QUEUES 8
+/* DCB define */
+#define IXGBE_VF_MAX_TRAFFIC_CLASS 8
+
#define IXGBE_VFCTRL 0x00000
#define IXGBE_VFSTATUS 0x00008
#define IXGBE_VFLINKS 0x00010
@@ -123,7 +126,7 @@ u32 ixgbe_get_num_of_tx_queues_vf(struct ixgbe_hw *hw);
u32 ixgbe_get_num_of_rx_queues_vf(struct ixgbe_hw *hw);
s32 ixgbe_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr);
s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg, bool autoneg_wait_to_complete);
+ bool autoneg_wait_to_complete);
s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
bool *link_up, bool autoneg_wait_to_complete);
s32 ixgbe_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
@@ -133,5 +136,9 @@ s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list,
u32 mc_addr_count, ixgbe_mc_addr_itr,
bool clear);
s32 ixgbe_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on);
+void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size);
+int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api);
+int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
+ unsigned int *default_tc);
#endif /* __IXGBE_VF_H__ */
diff --git a/sys/dev/pci/ixgbe/ixgbe_x540.c b/sys/dev/pci/ixgbe/ixgbe_x540.c
index a80d4c446b6..99ad6b84c44 100644
--- a/sys/dev/pci/ixgbe/ixgbe_x540.c
+++ b/sys/dev/pci/ixgbe/ixgbe_x540.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_x540.c 238149 2012-07-05 20:51:44Z jfv $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_x540.c 247822 2013-03-04 23:07:40Z jfv $*/
#include "ixgbe_x540.h"
#include "ixgbe_type.h"
@@ -116,6 +116,7 @@ s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw)
mac->ops.setup_rxpba = &ixgbe_set_rxpba_generic;
mac->ops.check_link = &ixgbe_check_mac_link_generic;
+
mac->mcft_size = 128;
mac->vft_size = 128;
mac->num_rar_entries = 128;
@@ -177,16 +178,14 @@ enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw)
* ixgbe_setup_mac_link_X540 - Sets the auto advertised capabilities
* @hw: pointer to hardware structure
* @speed: new link speed
- * @autoneg: TRUE if autonegotiation enabled
* @autoneg_wait_to_complete: TRUE when waiting for completion is needed
**/
s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
+ ixgbe_link_speed speed,
bool autoneg_wait_to_complete)
{
DEBUGFUNC("ixgbe_setup_mac_link_X540");
- return hw->phy.ops.setup_link_speed(hw, speed, autoneg,
- autoneg_wait_to_complete);
+ return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete);
}
/**
@@ -973,3 +972,4 @@ s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index)
return IXGBE_SUCCESS;
}
+
diff --git a/sys/dev/pci/ixgbe/ixgbe_x540.h b/sys/dev/pci/ixgbe/ixgbe_x540.h
index 29cf8bb2ab2..55b561d5430 100644
--- a/sys/dev/pci/ixgbe/ixgbe_x540.h
+++ b/sys/dev/pci/ixgbe/ixgbe_x540.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD$*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_x540.h 247822 2013-03-04 23:07:40Z jfv $*/
#ifndef _IXGBE_X540_H_
#define _IXGBE_X540_H_
@@ -41,7 +41,7 @@ s32 ixgbe_get_link_capabilities_X540(struct ixgbe_hw *hw,
ixgbe_link_speed *speed, bool *autoneg);
enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw);
s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, ixgbe_link_speed speed,
- bool autoneg, bool link_up_wait_to_complete);
+ bool link_up_wait_to_complete);
s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw);
s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw);
u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw);
diff --git a/sys/dev/pci/ixgbe/ixv.c b/sys/dev/pci/ixgbe/ixv.c
index 764b571d14e..3ab893d5ce9 100644
--- a/sys/dev/pci/ixgbe/ixv.c
+++ b/sys/dev/pci/ixgbe/ixv.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2012, Intel Corporation
+ Copyright (c) 2001-2013, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,8 +30,8 @@
POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
-/*$FreeBSD: head/sys/dev/ixgbe/ixv.c 241917 2012-10-22 22:29:48Z eadler $*/
-/*$NetBSD: ixv.c,v 1.7 2015/04/14 07:17:06 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixv.c 247822 2013-03-04 23:07:40Z jfv $*/
+/*$NetBSD: ixv.c,v 1.8 2015/04/24 07:00:51 msaitoh Exp $*/
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -182,7 +182,7 @@ static device_method_t ixv_methods[] = {
DEVMETHOD(device_attach, ixv_attach),
DEVMETHOD(device_detach, ixv_detach),
DEVMETHOD(device_shutdown, ixv_shutdown),
- {0, 0}
+ DEVMETHOD_END
};
#endif
@@ -597,7 +597,7 @@ ixv_start_locked(struct tx_ring *txr, struct ifnet * ifp)
if (rc == EFBIG) {
struct mbuf *mtmp;
- if ((mtmp = m_defrag(m_head, M_DONTWAIT)) != NULL) {
+ if ((mtmp = m_defrag(m_head, M_NOWAIT)) != NULL) {
m_head = mtmp;
rc = ixv_xmit(txr, m_head);
if (rc != 0)
@@ -690,21 +690,22 @@ ixv_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
enqueued = 0;
if (m == NULL) {
- next = drbr_dequeue(ifp, txr->br);
- } else if (drbr_needs_enqueue(ifp, txr->br)) {
- if ((err = drbr_enqueue(ifp, txr->br, m)) != 0)
- return (err);
- next = drbr_dequeue(ifp, txr->br);
- } else
- next = m;
-
+ err = drbr_dequeue(ifp, txr->br, m);
+ if (err) {
+ return (err);
+ }
+ }
/* Process the queue */
- while (next != NULL) {
+ while ((next = drbr_peek(ifp, txr->br)) != NULL) {
if ((err = ixv_xmit(txr, next)) != 0) {
- if (next != NULL)
- err = drbr_enqueue(ifp, txr->br, next);
+ if (next != NULL) {
+ drbr_advance(ifp, txr->br);
+ } else {
+ drbr_putback(ifp, txr->br, next);
+ }
break;
}
+ drbr_advance(ifp, txr->br);
enqueued++;
ifp->if_obytes += next->m_pkthdr.len;
if (next->m_flags & M_MCAST)
@@ -717,7 +718,6 @@ ixv_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
ifp->if_flags |= IFF_OACTIVE;
break;
}
- next = drbr_dequeue(ifp, txr->br);
}
if (enqueued > 0) {
@@ -1996,7 +1996,6 @@ ixv_config_link(struct adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 autoneg, err = 0;
- bool negotiate = TRUE;
if (hw->mac.ops.check_link)
err = hw->mac.ops.check_link(hw, &autoneg,
@@ -2005,8 +2004,8 @@ ixv_config_link(struct adapter *adapter)
goto out;
if (hw->mac.ops.setup_link)
- err = hw->mac.ops.setup_link(hw, autoneg,
- negotiate, adapter->link_up);
+ err = hw->mac.ops.setup_link(hw,
+ autoneg, adapter->link_up);
out:
return;
}
@@ -2826,7 +2825,7 @@ ixv_refresh_mbufs(struct rx_ring *rxr, int limit)
while (j != limit) {
rxbuf = &rxr->rx_buffers[i];
if ((rxbuf->m_head == NULL) && (rxr->hdr_split)) {
- mh = m_gethdr(M_DONTWAIT, MT_DATA);
+ mh = m_gethdr(M_NOWAIT, MT_DATA);
if (mh == NULL)
goto update;
mh->m_pkthdr.len = mh->m_len = MHLEN;
@@ -2850,7 +2849,7 @@ ixv_refresh_mbufs(struct rx_ring *rxr, int limit)
}
if (rxbuf->m_pack == NULL) {
- mp = ixgbe_getjcl(&adapter->jcl_head, M_DONTWAIT,
+ mp = ixgbe_getjcl(&adapter->jcl_head, M_NOWAIT,
MT_DATA, M_PKTHDR, adapter->rx_mbuf_sz);
if (mp == NULL) {
rxr->no_jmbuf.ev_count++;