From da07f8e1bdff63b7e58437ae1d42ba7ba63d7f29 Mon Sep 17 00:00:00 2001 From: msaitoh Date: Fri, 24 Apr 2015 07:00:51 +0000 Subject: [PATCH] Sync ixg(4) up to FreeBSD r250108: - Cleanup some unused counters and some unused code. - Improve performance. - Fix flow control - don't override user value on re-init - Fix to make 1G optics work correctly - Change to interrupt enabling - some bits were incorrect for certain hardware. - Certain stats fixes, remove a duplicate increment of ierror, thanks to Scott Long for pointing these out. - Fix the setting of RX which related to multicast. - Some netmap related fixes. --- sys/dev/pci/ixgbe/LICENSE | 6 +- sys/dev/pci/ixgbe/ixgbe.c | 816 ++++++++++++++++--------------- sys/dev/pci/ixgbe/ixgbe.h | 65 +-- sys/dev/pci/ixgbe/ixgbe_82598.c | 64 ++- sys/dev/pci/ixgbe/ixgbe_82598.h | 2 +- sys/dev/pci/ixgbe/ixgbe_82599.c | 383 ++++++++++++--- sys/dev/pci/ixgbe/ixgbe_82599.h | 11 +- sys/dev/pci/ixgbe/ixgbe_api.c | 111 ++--- sys/dev/pci/ixgbe/ixgbe_api.h | 10 +- sys/dev/pci/ixgbe/ixgbe_common.c | 278 ++++++++++- sys/dev/pci/ixgbe/ixgbe_common.h | 27 +- sys/dev/pci/ixgbe/ixgbe_mbx.h | 18 +- sys/dev/pci/ixgbe/ixgbe_netbsd.h | 4 +- sys/dev/pci/ixgbe/ixgbe_osdep.h | 9 +- sys/dev/pci/ixgbe/ixgbe_phy.c | 59 +-- sys/dev/pci/ixgbe/ixgbe_phy.h | 26 +- sys/dev/pci/ixgbe/ixgbe_type.h | 48 +- sys/dev/pci/ixgbe/ixgbe_vf.c | 129 ++++- sys/dev/pci/ixgbe/ixgbe_vf.h | 15 +- sys/dev/pci/ixgbe/ixgbe_x540.c | 12 +- sys/dev/pci/ixgbe/ixgbe_x540.h | 6 +- sys/dev/pci/ixgbe/ixv.c | 43 +- 22 files changed, 1422 insertions(+), 720 deletions(-) diff --git a/sys/dev/pci/ixgbe/LICENSE b/sys/dev/pci/ixgbe/LICENSE index 07ec728209ef..451e59cd9d3e 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 0e26aed8f822..8a58a9edd12b 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; - offload = ((mp->m_pkthdr.csum_flags & M_CSUM_OFFLOAD) != 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)); - tx_buffer = &txr->tx_buffers[ctxd]; + if ((mp->m_pkthdr.csum_flags & M_CSUM_OFFLOAD) == 0) + offload = FALSE; + + /* 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 (tx_buffer->m_head) { - txr->bytes += - tx_buffer->m_head->m_pkthdr.len; - bus_dmamap_sync(txr->txtag->dt_dmat, - tx_buffer->map, - 0, tx_buffer->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; + if ((eop->wb.status & IXGBE_TXD_STAT_DD) == 0) + break; /* I/O not complete */ + + 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; } - tx_buffer->eop_index = -1; - getmicrotime(&txr->watchdog_time); + 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. + */ + } + ++txr->tx_avail; + buf->eop = NULL; - if (++first == adapter->num_tx_desc) - first = 0; - - 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 da3fb25d939d..697485897869 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 #include #include - -#ifdef IXGBE_IEEE1588 -#include -#endif +#include #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 f10ee4426270..08278ee67f29 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,13 +1158,42 @@ 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: return status; } +/** + * 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 29032053978c..ca45b6722365 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 35d4967ac19f..ec2d8f60a589 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)); + /* 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; + } - /* 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; + got_lock = TRUE; } - if (!(reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)) { + + /* 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 (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; } @@ -556,17 +608,85 @@ 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 dca39b7af123..5de1f09c17e1 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 ce847f41f41d..6323f2a18e8b 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 a5da1d79af85..56a744b28436 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 74f1327939b3..b3c95ce2a8bb 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, @@ -680,6 +701,195 @@ s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num) return IXGBE_SUCCESS; } +/** + * 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 @@ -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 22d8249173d3..5455d70efeca 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 6d019b56048c..c4e7c2b95961 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 672c3a29ff70..e2923bc20aed 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 6c5eece734cb..f1a9245ec6ea 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 48793920bda5..3d37ddbd42a1 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 = @@ -1333,6 +1320,22 @@ s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, eeprom_data); } +/** + * 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 @@ -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 a2808b5ba21a..e7a5299d96b9 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 ae454a412e9e..504e2df0e482 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 d8430bf58afb..ea0ccf77431d 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 dc3b59382ba6..f922caffb7b0 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 a80d4c446b6a..99ad6b84c44f 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 29cf8bb2ab2b..55b561d54305 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 764b571d14ed..3ab893d5ce90 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++;