From owner-svn-src-head@FreeBSD.ORG Mon Jan 30 16:42:03 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 040D6106566C; Mon, 30 Jan 2012 16:42:03 +0000 (UTC) (envelope-from jfv@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E51A98FC12; Mon, 30 Jan 2012 16:42:02 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q0UGg2YI093710; Mon, 30 Jan 2012 16:42:02 GMT (envelope-from jfv@svn.freebsd.org) Received: (from jfv@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q0UGg2so093704; Mon, 30 Jan 2012 16:42:02 GMT (envelope-from jfv@svn.freebsd.org) Message-Id: <201201301642.q0UGg2so093704@svn.freebsd.org> From: Jack F Vogel Date: Mon, 30 Jan 2012 16:42:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r230775 - in head/sys: conf dev/ixgbe modules/ixgbe X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 30 Jan 2012 16:42:03 -0000 Author: jfv Date: Mon Jan 30 16:42:02 2012 New Revision: 230775 URL: http://svn.freebsd.org/changeset/base/230775 Log: New hardware support: Intel X540 adapter support added. Some shared code reorganization along with the new adapter. Sync changes to OACTIVE in igb into this driver. Misc small fixes. Added: head/sys/dev/ixgbe/ixgbe_82598.h (contents, props changed) head/sys/dev/ixgbe/ixgbe_82599.h (contents, props changed) head/sys/dev/ixgbe/ixgbe_x540.c (contents, props changed) head/sys/dev/ixgbe/ixgbe_x540.h (contents, props changed) Modified: head/sys/conf/files head/sys/dev/ixgbe/ixgbe.c head/sys/dev/ixgbe/ixgbe.h head/sys/dev/ixgbe/ixgbe_82598.c head/sys/dev/ixgbe/ixgbe_82599.c head/sys/dev/ixgbe/ixgbe_api.c head/sys/dev/ixgbe/ixgbe_api.h head/sys/dev/ixgbe/ixgbe_common.c head/sys/dev/ixgbe/ixgbe_common.h head/sys/dev/ixgbe/ixgbe_mbx.c head/sys/dev/ixgbe/ixgbe_mbx.h head/sys/dev/ixgbe/ixgbe_osdep.h head/sys/dev/ixgbe/ixgbe_phy.c head/sys/dev/ixgbe/ixgbe_phy.h head/sys/dev/ixgbe/ixgbe_type.h head/sys/dev/ixgbe/ixgbe_vf.c head/sys/dev/ixgbe/ixgbe_vf.h head/sys/dev/ixgbe/ixv.c head/sys/dev/ixgbe/ixv.h head/sys/modules/ixgbe/Makefile Modified: head/sys/conf/files ============================================================================== --- head/sys/conf/files Mon Jan 30 15:09:03 2012 (r230774) +++ head/sys/conf/files Mon Jan 30 16:42:02 2012 (r230775) @@ -1395,6 +1395,8 @@ dev/ixgbe/ixgbe_82598.c optional ixgbe compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_82599.c optional ixgbe inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" +dev/ixgbe/ixgbe_x540.c optional ixgbe inet \ + compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/jme/if_jme.c optional jme pci dev/joy/joy.c optional joy dev/joy/joy_isa.c optional joy isa Modified: head/sys/dev/ixgbe/ixgbe.c ============================================================================== --- head/sys/dev/ixgbe/ixgbe.c Mon Jan 30 15:09:03 2012 (r230774) +++ head/sys/dev/ixgbe/ixgbe.c Mon Jan 30 16:42:02 2012 (r230775) @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2011, Intel Corporation + Copyright (c) 2001-2012, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -47,7 +47,7 @@ int ixgbe_display_debug_stat /********************************************************************* * Driver version *********************************************************************/ -char ixgbe_driver_version[] = "2.3.11"; +char ixgbe_driver_version[] = "2.4.5"; /********************************************************************* * PCI Device ID Table @@ -81,6 +81,8 @@ static ixgbe_vendor_info_t ixgbe_vendor_ {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_COMBO_BACKPLANE, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_BACKPLANE_FCOE, 0, 0, 0}, {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_X540T, 0, 0, 0}, /* required last entry */ {0, 0, 0, 0, 0} }; @@ -153,6 +155,7 @@ static void ixgbe_refresh_mbufs(struct r static int ixgbe_xmit(struct tx_ring *, struct mbuf **); static int ixgbe_set_flowcntl(SYSCTL_HANDLER_ARGS); static int ixgbe_set_advertise(SYSCTL_HANDLER_ARGS); +static int ixgbe_set_thermal_test(SYSCTL_HANDLER_ARGS); 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 *); @@ -415,19 +418,29 @@ ixgbe_attach(device_t dev) SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "flow_control", CTLTYPE_INT | CTLFLAG_RW, + OID_AUTO, "fc", CTLTYPE_INT | CTLFLAG_RW, adapter, 0, ixgbe_set_flowcntl, "I", "Flow Control"); - SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "advertise_gig", CTLTYPE_INT | CTLFLAG_RW, - adapter, 0, ixgbe_set_advertise, "I", "1G Link"); - SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "enable_aim", CTLTYPE_INT|CTLFLAG_RW, &ixgbe_enable_aim, 1, "Interrupt Moderation"); + /* + ** Allow a kind of speed control by forcing the autoneg + ** advertised speed list to only a certain value, this + ** supports 1G on 82599 devices, and 100Mb on x540. + */ + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "advertise_speed", CTLTYPE_INT | CTLFLAG_RW, + adapter, 0, ixgbe_set_advertise, "I", "Link Speed"); + + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "ts", CTLTYPE_INT | CTLFLAG_RW, adapter, + 0, ixgbe_set_thermal_test, "I", "Thermal Test"); + /* Set up the timer callout */ callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0); @@ -515,9 +528,10 @@ ixgbe_attach(device_t dev) /* Get Hardware Flow Control setting */ hw->fc.requested_mode = ixgbe_fc_full; + adapter->fc = hw->fc.requested_mode; hw->fc.pause_time = IXGBE_FC_PAUSE; hw->fc.low_water = IXGBE_FC_LO; - hw->fc.high_water = IXGBE_FC_HI; + hw->fc.high_water[0] = IXGBE_FC_HI; hw->fc.send_xon = TRUE; error = ixgbe_init_hw(hw); @@ -724,16 +738,20 @@ ixgbe_start_locked(struct tx_ring *txr, return; while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { + if (txr->tx_avail <= IXGBE_QUEUE_MIN_FREE) { + txr->queue_status |= IXGBE_QUEUE_DEPLETED; + break; + } IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; if (ixgbe_xmit(txr, &m_head)) { - if (m_head == NULL) - break; - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - IFQ_DRV_PREPEND(&ifp->if_snd, m_head); + if (m_head != NULL) + IFQ_DRV_PREPEND(&ifp->if_snd, m_head); + if (txr->tx_avail <= IXGBE_QUEUE_MIN_FREE) + txr->queue_status |= IXGBE_QUEUE_DEPLETED; break; } /* Send a copy of the frame to the BPF listener */ @@ -782,11 +800,14 @@ ixgbe_mq_start(struct ifnet *ifp, struct /* Which queue to use */ if ((m->m_flags & M_FLOWID) != 0) i = m->m_pkthdr.flowid % adapter->num_queues; + else + i = curcpu % adapter->num_queues; txr = &adapter->tx_rings[i]; que = &adapter->queues[i]; - if (IXGBE_TX_TRYLOCK(txr)) { + if (((txr->queue_status & IXGBE_QUEUE_DEPLETED) == 0) && + IXGBE_TX_TRYLOCK(txr)) { err = ixgbe_mq_start_locked(ifp, txr, m); IXGBE_TX_UNLOCK(txr); } else { @@ -804,8 +825,9 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct mbuf *next; int enqueued, err = 0; - if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING || adapter->link_active == 0) { + if (((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) || + (txr->queue_status == IXGBE_QUEUE_DEPLETED) || + adapter->link_active == 0) { if (m != NULL) err = drbr_enqueue(ifp, txr->br, m); return (err); @@ -837,7 +859,7 @@ ixgbe_mq_start_locked(struct ifnet *ifp, if (txr->tx_avail < IXGBE_TX_OP_THRESHOLD) ixgbe_txeof(txr); if (txr->tx_avail < IXGBE_TX_OP_THRESHOLD) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; + txr->queue_status |= IXGBE_QUEUE_DEPLETED; break; } next = drbr_dequeue(ifp, txr->br); @@ -845,10 +867,13 @@ ixgbe_mq_start_locked(struct ifnet *ifp, if (enqueued > 0) { /* Set watchdog on */ - txr->queue_status = IXGBE_QUEUE_WORKING; + txr->queue_status |= IXGBE_QUEUE_WORKING; txr->watchdog_time = ticks; } + if (txr->tx_avail < IXGBE_TX_CLEANUP_THRESHOLD) + ixgbe_txeof(txr); + return (err); } @@ -916,8 +941,8 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c arp_ifinit(ifp, ifa); } else error = ether_ioctl(ifp, command, data); - break; #endif + break; case SIOCSIFMTU: IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)"); if (ifr->ifr_mtu > IXGBE_MAX_FRAME_SIZE - ETHER_HDR_LEN) { @@ -1087,10 +1112,14 @@ ixgbe_init_locked(struct adapter *adapte /* Enable Fan Failure Interrupt */ gpie |= IXGBE_SDP1_GPIEN; - /* Add for Thermal detection */ + /* Add for Module detection */ if (hw->mac.type == ixgbe_mac_82599EB) gpie |= IXGBE_SDP2_GPIEN; + /* Thermal Failure Detection */ + if (hw->mac.type == ixgbe_mac_X540) + gpie |= IXGBE_SDP0_GPIEN; + if (adapter->msix > 1) { /* Enable Enhanced MSIX mode */ gpie |= IXGBE_GPIE_MSIX_MODE; @@ -1196,8 +1225,12 @@ ixgbe_init_locked(struct adapter *adapte #ifdef IXGBE_FDIR /* Init Flow director */ - if (hw->mac.type != ixgbe_mac_82598EB) + if (hw->mac.type != ixgbe_mac_82598EB) { + u32 hdrm = 64 << fdir_pballoc; + + hw->mac.ops.setup_rxpba(hw, 0, hdrm, PBA_STRATEGY_EQUAL); ixgbe_init_fdir_signature_82599(&adapter->hw, fdir_pballoc); + } #endif /* @@ -1325,7 +1358,7 @@ ixgbe_handle_que(void *context, int pend ixgbe_start_locked(txr, ifp); #endif IXGBE_TX_UNLOCK(txr); - if (more) { + if (more || (ifp->if_drv_flags & IFF_DRV_OACTIVE)) { taskqueue_enqueue(que->tq, &que->que_task); return; } @@ -1405,6 +1438,7 @@ ixgbe_msix_que(void *arg) bool more_tx, more_rx; u32 newitr = 0; + ixgbe_disable_queue(adapter, que->msix); ++que->irqs; more_rx = ixgbe_rxeof(que, adapter->rx_process_limit); @@ -1539,6 +1573,15 @@ ixgbe_msix_link(void *arg) IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1); } + /* Check for over temp condition */ + if ((hw->mac.type == ixgbe_mac_X540) && + (reg_eicr & IXGBE_EICR_GPI_SDP0)) { + 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(&adapter->hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); return; } @@ -1571,6 +1614,9 @@ ixgbe_media_status(struct ifnet * ifp, s ifmr->ifm_status |= IFM_ACTIVE; switch (adapter->link_speed) { + case IXGBE_LINK_SPEED_100_FULL: + ifmr->ifm_active |= IFM_100_TX | IFM_FDX; + break; case IXGBE_LINK_SPEED_1GB_FULL: ifmr->ifm_active |= IFM_1000_T | IFM_FDX; break; @@ -1606,7 +1652,9 @@ ixgbe_media_change(struct ifnet * ifp) switch (IFM_SUBTYPE(ifm->ifm_media)) { case IFM_AUTO: adapter->hw.phy.autoneg_advertised = - IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_10GB_FULL; + IXGBE_LINK_SPEED_100_FULL | + IXGBE_LINK_SPEED_1GB_FULL | + IXGBE_LINK_SPEED_10GB_FULL; break; default: device_printf(adapter->dev, "Only auto media type\n"); @@ -1878,7 +1926,7 @@ ixgbe_set_multi(struct adapter *adapter) update_ptr = mta; ixgbe_update_mc_addr_list(&adapter->hw, - update_ptr, mcnt, ixgbe_mc_array_itr); + update_ptr, mcnt, ixgbe_mc_array_itr, TRUE); return; } @@ -1912,11 +1960,15 @@ ixgbe_mc_array_itr(struct ixgbe_hw *hw, static void ixgbe_local_timer(void *arg) { - struct adapter *adapter = arg; + struct adapter *adapter = arg; device_t dev = adapter->dev; - struct tx_ring *txr = adapter->tx_rings; + struct ifnet *ifp = adapter->ifp; + struct ix_queue *que = adapter->queues; + struct tx_ring *txr = adapter->tx_rings; + int hung, busy, paused; mtx_assert(&adapter->core_mtx, MA_OWNED); + hung = busy = paused = 0; /* Check for pluggable optics */ if (adapter->sfp_probe) @@ -1931,21 +1983,38 @@ ixgbe_local_timer(void *arg) * then don't do the watchdog check */ if (IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF) - goto out; + paused = 1; /* - ** Check status on the TX queues for a hang - */ - for (int i = 0; i < adapter->num_queues; i++, txr++) - if (txr->queue_status == IXGBE_QUEUE_HUNG) - goto hung; + ** Check the TX queues status + ** - central locked handling of OACTIVE + ** - watchdog only if all queues show hung + */ + for (int i = 0; i < adapter->num_queues; i++, que++, txr++) { + if ((txr->queue_status & IXGBE_QUEUE_HUNG) && + (paused == 0)) + ++hung; + if (txr->queue_status & IXGBE_QUEUE_DEPLETED) + ++busy; + if ((txr->queue_status & IXGBE_QUEUE_IDLE) == 0) + taskqueue_enqueue(que->tq, &que->que_task); + } + /* Only truely watchdog if all queues show hung */ + if (hung == adapter->num_queues) + goto watchdog; + /* Only turn off the stack flow when ALL are depleted */ + if (busy == adapter->num_queues) + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + else if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) && + (busy < adapter->num_queues)) + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; out: ixgbe_rearm_queues(adapter, adapter->que_mask); callout_reset(&adapter->timer, hz, ixgbe_local_timer, adapter); return; -hung: +watchdog: device_printf(adapter->dev, "Watchdog timeout -- resetting\n"); device_printf(dev,"Queue(%d) tdh = %d, hw tdt = %d\n", txr->me, IXGBE_READ_REG(&adapter->hw, IXGBE_TDH(txr->me)), @@ -2015,9 +2084,11 @@ ixgbe_stop(void *arg) INIT_DEBUGOUT("ixgbe_stop: begin\n"); ixgbe_disable_intr(adapter); + callout_stop(&adapter->timer); - /* Tell the stack that the interface is no longer active */ - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + /* Let the stack know...*/ + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + ifp->if_drv_flags |= IFF_DRV_OACTIVE; ixgbe_reset_hw(hw); hw->adapter_stopped = FALSE; @@ -2025,7 +2096,6 @@ ixgbe_stop(void *arg) /* Turn off the laser */ if (hw->phy.multispeed_fiber) ixgbe_disable_tx_laser(hw); - callout_stop(&adapter->timer); /* reprogram the RAR[0] in case user changed it. */ ixgbe_set_rar(&adapter->hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV); @@ -2079,35 +2149,41 @@ ixgbe_setup_optics(struct adapter *adapt int layer; layer = ixgbe_get_supported_physical_layer(hw); - switch (layer) { - case IXGBE_PHYSICAL_LAYER_10GBASE_T: - adapter->optics = IFM_10G_T; - break; - case IXGBE_PHYSICAL_LAYER_1000BASE_T: - adapter->optics = IFM_1000_T; - break; - case IXGBE_PHYSICAL_LAYER_10GBASE_LR: - case IXGBE_PHYSICAL_LAYER_10GBASE_LRM: - adapter->optics = IFM_10G_LR; - break; - case IXGBE_PHYSICAL_LAYER_10GBASE_SR: - adapter->optics = IFM_10G_SR; - break; - case IXGBE_PHYSICAL_LAYER_10GBASE_KX4: - case IXGBE_PHYSICAL_LAYER_10GBASE_CX4: - adapter->optics = IFM_10G_CX4; - break; - case IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU: - adapter->optics = IFM_10G_TWINAX; - break; - case IXGBE_PHYSICAL_LAYER_1000BASE_KX: - case IXGBE_PHYSICAL_LAYER_10GBASE_KR: - case IXGBE_PHYSICAL_LAYER_10GBASE_XAUI: - case IXGBE_PHYSICAL_LAYER_UNKNOWN: - default: - adapter->optics = IFM_ETHER | IFM_AUTO; - break; + + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T) { + adapter->optics = IFM_10G_T; + return; + } + + if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_T) { + adapter->optics = IFM_1000_T; + return; } + + if (layer & (IXGBE_PHYSICAL_LAYER_10GBASE_LR | + IXGBE_PHYSICAL_LAYER_10GBASE_LRM)) { + adapter->optics = IFM_10G_LR; + return; + } + + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_SR) { + adapter->optics = IFM_10G_SR; + return; + } + + if (layer & IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU) { + adapter->optics = IFM_10G_TWINAX; + return; + } + + if (layer & (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 | + IXGBE_PHYSICAL_LAYER_10GBASE_CX4)) { + adapter->optics = IFM_10G_CX4; + return; + } + + /* If we get here just set the default */ + adapter->optics = IFM_ETHER | IFM_AUTO; return; } @@ -2975,6 +3051,7 @@ ixgbe_initialize_transmit_units(struct a txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i)); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: default: txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i)); break; @@ -2985,6 +3062,7 @@ ixgbe_initialize_transmit_units(struct a IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), txctrl); break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: default: IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), txctrl); break; @@ -3512,18 +3590,13 @@ ixgbe_txeof(struct tx_ring *txr) if ((!processed) && ((ticks - txr->watchdog_time) > IXGBE_WATCHDOG)) txr->queue_status = IXGBE_QUEUE_HUNG; - /* - * If we have enough room, clear IFF_DRV_OACTIVE to tell the stack that - * it is OK to send packets. If there are no pending descriptors, - * clear the timeout. Otherwise, if some descriptors have been freed, - * restart the timeout. - */ - if (txr->tx_avail > IXGBE_TX_CLEANUP_THRESHOLD) { - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - if (txr->tx_avail == adapter->num_tx_desc) { - txr->queue_status = IXGBE_QUEUE_IDLE; - return FALSE; - } + /* With a minimum free clear the depleted state bit. */ + if (txr->tx_avail > IXGBE_TX_CLEANUP_THRESHOLD) + txr->queue_status &= ~IXGBE_QUEUE_DEPLETED; + + if (txr->tx_avail == adapter->num_tx_desc) { + txr->queue_status = IXGBE_QUEUE_IDLE; + return (FALSE); } return TRUE; @@ -3923,6 +3996,7 @@ skip_head: rxr->rx_split_packets = 0; rxr->rx_bytes = 0; rxr->discard = FALSE; + rxr->vtag_strip = FALSE; bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -3930,7 +4004,7 @@ skip_head: /* ** Now set up the LRO interface: ** 82598 uses software LRO, the - ** 82599 uses a hardware assist. + ** 82599 and X540 use a hardware assist. */ if ((adapter->hw.mac.type != ixgbe_mac_82598EB) && (ifp->if_capenable & IFCAP_RXCSUM) && @@ -4028,7 +4102,8 @@ ixgbe_initialize_receive_units(struct ad hlreg &= ~IXGBE_HLREG0_JUMBOEN; IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg); - bufsz = (adapter->rx_mbuf_sz + BSIZEPKT_ROUNDUP) >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; + bufsz = (adapter->rx_mbuf_sz + + BSIZEPKT_ROUNDUP) >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; for (int i = 0; i < adapter->num_queues; i++, rxr++) { u64 rdba = rxr->rxdma.dma_paddr; @@ -4314,7 +4389,8 @@ ixgbe_rxeof(struct ix_queue *que, int co for (i = rxr->next_to_check; count != 0;) { struct mbuf *sendmp, *mh, *mp; u32 rsc, ptype; - u16 hlen, plen, hdr, vtag; + u16 hlen, plen, hdr; + u16 vtag = 0; bool eop; /* Sync the ring. */ @@ -4342,9 +4418,12 @@ ixgbe_rxeof(struct ix_queue *que, int co ptype = le32toh(cur->wb.lower.lo_dword.data) & IXGBE_RXDADV_PKTTYPE_MASK; hdr = le16toh(cur->wb.lower.lo_dword.hs_rss.hdr_info); - vtag = le16toh(cur->wb.upper.vlan); eop = ((staterr & IXGBE_RXD_STAT_EOP) != 0); + /* Process vlan info */ + if ((rxr->vtag_strip) && (staterr & IXGBE_RXD_STAT_VP)) + vtag = le16toh(cur->wb.upper.vlan); + /* Make sure bad packets are discarded */ if (((staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) != 0) || (rxr->discard)) { @@ -4445,8 +4524,8 @@ ixgbe_rxeof(struct ix_queue *que, int co } else { /* Singlet, prepare to send */ sendmp = mh; - if ((adapter->num_vlans) && - (staterr & IXGBE_RXD_STAT_VP)) { + /* If hardware handled vtag */ + if (vtag) { sendmp->m_pkthdr.ether_vtag = vtag; sendmp->m_flags |= M_VLANTAG; } @@ -4655,6 +4734,7 @@ ixgbe_setup_vlan_hw_support(struct adapt { struct ifnet *ifp = adapter->ifp; struct ixgbe_hw *hw = &adapter->hw; + struct rx_ring *rxr; u32 ctrl; @@ -4686,13 +4766,17 @@ ixgbe_setup_vlan_hw_support(struct adapt ctrl |= IXGBE_VLNCTRL_VME; IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, ctrl); - /* On 82599 the VLAN enable is per/queue in RXDCTL */ - if (hw->mac.type != ixgbe_mac_82598EB) - for (int i = 0; i < adapter->num_queues; i++) { + /* Setup the queues for vlans */ + for (int i = 0; i < adapter->num_queues; i++) { + rxr = &adapter->rx_rings[i]; + /* On 82599 the VLAN enable is per/queue in RXDCTL */ + if (hw->mac.type != ixgbe_mac_82598EB) { ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i)); - ctrl |= IXGBE_RXDCTL_VME; + ctrl |= IXGBE_RXDCTL_VME; IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), ctrl); } + rxr->vtag_strip = TRUE; + } } static void @@ -4708,6 +4792,7 @@ ixgbe_enable_intr(struct adapter *adapte 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; #ifdef IXGBE_FDIR @@ -4805,6 +4890,7 @@ ixgbe_set_ivar(struct adapter *adapter, break; case ixgbe_mac_82599EB: + case ixgbe_mac_X540: if (type == -1) { /* MISC IVAR */ index = (entry & 1) * 8; ivar = IXGBE_READ_REG(hw, IXGBE_IVAR_MISC); @@ -5492,24 +5578,23 @@ ixgbe_add_hw_stats(struct adapter *adapt static int ixgbe_set_flowcntl(SYSCTL_HANDLER_ARGS) { - int error; - int last = ixgbe_flow_control; - struct adapter *adapter; + int error, last; + struct adapter *adapter = (struct adapter *) arg1; - error = sysctl_handle_int(oidp, &ixgbe_flow_control, 0, req); - if (error) + last = adapter->fc; + error = sysctl_handle_int(oidp, &adapter->fc, 0, req); + if ((error) || (req->newptr == NULL)) return (error); /* Don't bother if it's not changed */ - if (ixgbe_flow_control == last) + if (adapter->fc == last) return (0); - adapter = (struct adapter *) arg1; - switch (ixgbe_flow_control) { + switch (adapter->fc) { case ixgbe_fc_rx_pause: case ixgbe_fc_tx_pause: case ixgbe_fc_full: - adapter->hw.fc.requested_mode = ixgbe_flow_control; + adapter->hw.fc.requested_mode = adapter->fc; break; case ixgbe_fc_none: default: @@ -5534,16 +5619,19 @@ ixgbe_add_rx_process_limit(struct adapte ** Control link advertise speed: ** 0 - normal ** 1 - advertise only 1G +** 2 - advertise 100Mb */ static int ixgbe_set_advertise(SYSCTL_HANDLER_ARGS) { int error = 0; struct adapter *adapter; + device_t dev; struct ixgbe_hw *hw; ixgbe_link_speed speed, last; adapter = (struct adapter *) arg1; + dev = adapter->dev; hw = &adapter->hw; last = hw->phy.autoneg_advertised; @@ -5556,8 +5644,15 @@ ixgbe_set_advertise(SYSCTL_HANDLER_ARGS) (hw->phy.multispeed_fiber))) return (error); + if ((adapter->advertise == 2) && (hw->mac.type != ixgbe_mac_X540)) { + device_printf(dev, "Set Advertise: 100Mb on X540 only\n"); + return (error); + } + if (adapter->advertise == 1) speed = IXGBE_LINK_SPEED_1GB_FULL; + else if (adapter->advertise == 2) + speed = IXGBE_LINK_SPEED_100_FULL; else speed = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_10GB_FULL; @@ -5570,3 +5665,31 @@ ixgbe_set_advertise(SYSCTL_HANDLER_ARGS) return (error); } + +/* +** Thermal Shutdown Trigger +** - cause a Thermal Overtemp IRQ +*/ +static int +ixgbe_set_thermal_test(SYSCTL_HANDLER_ARGS) +{ + int error, fire = 0; + struct adapter *adapter = (struct adapter *) arg1; + struct ixgbe_hw *hw = &adapter->hw; + + + if (hw->mac.type != ixgbe_mac_X540) + return (0); + + error = sysctl_handle_int(oidp, &fire, 0, req); + if ((error) || (req->newptr == NULL)) + return (error); + + if (fire) { + u32 reg = IXGBE_READ_REG(hw, IXGBE_EICS); + reg |= IXGBE_EICR_TS; + IXGBE_WRITE_REG(hw, IXGBE_EICS, reg); + } + + return (0); +} Modified: head/sys/dev/ixgbe/ixgbe.h ============================================================================== --- head/sys/dev/ixgbe/ixgbe.h Mon Jan 30 15:09:03 2012 (r230774) +++ head/sys/dev/ixgbe/ixgbe.h Mon Jan 30 16:42:02 2012 (r230775) @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2011, Intel Corporation + Copyright (c) 2001-2012, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -184,9 +184,11 @@ #define IXGBE_RX_HDR 128 #define IXGBE_VFTA_SIZE 128 #define IXGBE_BR_SIZE 4096 -#define IXGBE_QUEUE_IDLE 0 -#define IXGBE_QUEUE_WORKING 1 -#define IXGBE_QUEUE_HUNG 2 +#define IXGBE_QUEUE_MIN_FREE 32 +#define IXGBE_QUEUE_IDLE 1 +#define IXGBE_QUEUE_WORKING 2 +#define IXGBE_QUEUE_HUNG 4 +#define IXGBE_QUEUE_DEPLETED 8 /* Offload bits in mbuf flag */ #if __FreeBSD_version >= 800000 @@ -323,6 +325,7 @@ struct rx_ring { bool hdr_split; bool hw_rsc; bool discard; + bool vtag_strip; u32 next_to_refresh; u32 next_to_check; char mtx_name[16]; @@ -387,6 +390,7 @@ struct adapter { /* Info about the interface */ u32 optics; + u32 fc; /* local flow ctrl setting */ int advertise; /* link speeds */ bool link_active; u16 max_frame_size; Modified: head/sys/dev/ixgbe/ixgbe_82598.c ============================================================================== --- head/sys/dev/ixgbe/ixgbe_82598.c Mon Jan 30 15:09:03 2012 (r230774) +++ head/sys/dev/ixgbe/ixgbe_82598.c Mon Jan 30 16:42:02 2012 (r230775) @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2010, Intel Corporation + Copyright (c) 2001-2012, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -33,46 +33,33 @@ /*$FreeBSD$*/ #include "ixgbe_type.h" +#include "ixgbe_82598.h" #include "ixgbe_api.h" #include "ixgbe_common.h" #include "ixgbe_phy.h" -u32 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw); -s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw); static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, - ixgbe_link_speed *speed, - bool *autoneg); + ixgbe_link_speed *speed, + bool *autoneg); static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw); -s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num); static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw, - bool autoneg_wait_to_complete); + bool autoneg_wait_to_complete); static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, - ixgbe_link_speed *speed, bool *link_up, - bool link_up_wait_to_complete); + ixgbe_link_speed *speed, bool *link_up, + 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); + 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); + ixgbe_link_speed speed, + bool autoneg, + bool autoneg_wait_to_complete); static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw); -s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw); -void ixgbe_enable_relaxed_ordering_82598(struct ixgbe_hw *hw); -s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq); static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq); -s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, - u32 vind, bool vlan_on); static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw); -s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val); -s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val); -s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, - u8 *eeprom_data); -u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw); -s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw); -void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw); -void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw); +static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb, + u32 headroom, int strategy); /** * ixgbe_set_pcie_completion_timeout - set pci-e completion timeout @@ -131,7 +118,7 @@ u32 ixgbe_get_pcie_msix_count_82598(stru if (hw->mac.msix_vectors_from_pcie) { msix_count = IXGBE_READ_PCIE_WORD(hw, - IXGBE_PCIE_MSIX_82598_CAPS); + IXGBE_PCIE_MSIX_82598_CAPS); msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK; /* MSI-X count is zero-based in HW, so increment to give @@ -168,7 +155,7 @@ s32 ixgbe_init_ops_82598(struct ixgbe_hw mac->ops.reset_hw = &ixgbe_reset_hw_82598; mac->ops.get_media_type = &ixgbe_get_media_type_82598; mac->ops.get_supported_physical_layer = - &ixgbe_get_supported_physical_layer_82598; + &ixgbe_get_supported_physical_layer_82598; mac->ops.read_analog_reg8 = &ixgbe_read_analog_reg8_82598; mac->ops.write_analog_reg8 = &ixgbe_write_analog_reg8_82598; mac->ops.set_lan_id = &ixgbe_set_lan_id_multi_port_pcie_82598; @@ -177,18 +164,19 @@ s32 ixgbe_init_ops_82598(struct ixgbe_hw mac->ops.set_vmdq = &ixgbe_set_vmdq_82598; mac->ops.clear_vmdq = &ixgbe_clear_vmdq_82598; mac->ops.set_vfta = &ixgbe_set_vfta_82598; + mac->ops.set_vlvf = NULL; mac->ops.clear_vfta = &ixgbe_clear_vfta_82598; /* Flow Control */ mac->ops.fc_enable = &ixgbe_fc_enable_82598; - mac->mcft_size = 128; - mac->vft_size = 128; - mac->num_rar_entries = 16; - mac->rx_pb_size = 512; - mac->max_tx_queues = 32; - mac->max_rx_queues = 64; - mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw); + mac->mcft_size = 128; + mac->vft_size = 128; + mac->num_rar_entries = 16; + mac->rx_pb_size = 512; + mac->max_tx_queues = 32; + mac->max_rx_queues = 64; + mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw); /* SFP+ Module */ phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_82598; @@ -197,8 +185,11 @@ s32 ixgbe_init_ops_82598(struct ixgbe_hw mac->ops.check_link = &ixgbe_check_mac_link_82598; mac->ops.setup_link = &ixgbe_setup_mac_link_82598; mac->ops.flap_tx_laser = NULL; - mac->ops.get_link_capabilities = - &ixgbe_get_link_capabilities_82598; + mac->ops.get_link_capabilities = &ixgbe_get_link_capabilities_82598; + mac->ops.setup_rxpba = &ixgbe_set_rxpba_82598; + + /* Manageability interface */ + mac->ops.set_fw_drv_ver = NULL; return ret_val; } @@ -228,7 +219,7 @@ s32 ixgbe_init_phy_ops_82598(struct ixgb if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { mac->ops.setup_link = &ixgbe_setup_copper_link_82598; mac->ops.get_link_capabilities = - &ixgbe_get_copper_link_capabilities_generic; + &ixgbe_get_copper_link_capabilities_generic; } switch (hw->phy.type) { @@ -236,11 +227,7 @@ s32 ixgbe_init_phy_ops_82598(struct ixgb phy->ops.setup_link = &ixgbe_setup_phy_link_tnx; phy->ops.check_link = &ixgbe_check_phy_link_tnx; phy->ops.get_firmware_version = - &ixgbe_get_phy_firmware_version_tnx; - break; - case ixgbe_phy_aq: - phy->ops.get_firmware_version = - &ixgbe_get_phy_firmware_version_generic; + &ixgbe_get_phy_firmware_version_tnx; break; case ixgbe_phy_nl: phy->ops.reset = &ixgbe_reset_phy_nl; @@ -256,8 +243,8 @@ s32 ixgbe_init_phy_ops_82598(struct ixgb /* Check to see if SFP+ module is supported */ ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, - &list_offset, - &data_offset); + &list_offset, + &data_offset); if (ret_val != IXGBE_SUCCESS) { ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED; goto out; @@ -301,7 +288,7 @@ s32 ixgbe_start_hw_82598(struct ixgbe_hw (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN | - IXGBE_DCA_RXCTRL_DESC_HSRO_EN); + IXGBE_DCA_RXCTRL_DESC_HSRO_EN); IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); } @@ -321,8 +308,8 @@ s32 ixgbe_start_hw_82598(struct ixgbe_hw * Determines the link capabilities by reading the AUTOC register. **/ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, - ixgbe_link_speed *speed, - bool *autoneg) + ixgbe_link_speed *speed, + bool *autoneg) { s32 status = IXGBE_SUCCESS; u32 autoc = 0; @@ -389,7 +376,6 @@ static enum ixgbe_media_type ixgbe_get_m switch (hw->phy.type) { case ixgbe_phy_cu_unknown: case ixgbe_phy_tn: - case ixgbe_phy_aq: media_type = ixgbe_media_type_copper; goto out; default: @@ -440,7 +426,6 @@ s32 ixgbe_fc_enable_82598(struct ixgbe_h u32 fctrl_reg; u32 rmcs_reg; u32 reg; - u32 rx_pba_size; u32 link_speed = 0; bool link_up; @@ -532,16 +517,13 @@ s32 ixgbe_fc_enable_82598(struct ixgbe_h /* Set up and enable Rx high/low water mark thresholds, enable XON. */ if (hw->fc.current_mode & ixgbe_fc_tx_pause) { - rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num)); - rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT; - - reg = (rx_pba_size - hw->fc.low_water) << 6; + reg = hw->fc.low_water << 6; if (hw->fc.send_xon) reg |= IXGBE_FCRTL_XONE; IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), reg); - reg = (rx_pba_size - hw->fc.high_water) << 6; + reg = hw->fc.high_water[packetbuf_num] << 6; reg |= IXGBE_FCRTH_FCEN; IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), reg); @@ -569,7 +551,7 @@ out: * Restarts the link. Performs autonegotiation if needed. **/ static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw, - bool autoneg_wait_to_complete) + bool autoneg_wait_to_complete) { u32 autoc_reg; u32 links_reg; @@ -627,7 +609,7 @@ static s32 ixgbe_validate_link_ready(str for (timeout = 0; timeout < IXGBE_VALIDATE_LINK_READY_TIMEOUT; timeout++) { hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &an_reg); + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &an_reg); if ((an_reg & IXGBE_MII_AUTONEG_COMPLETE) && (an_reg & IXGBE_MII_AUTONEG_LINK_UP)) @@ -654,8 +636,8 @@ static s32 ixgbe_validate_link_ready(str * Reads the links register to determine if link is up and the current speed **/ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, - ixgbe_link_speed *speed, bool *link_up, - bool link_up_wait_to_complete) + ixgbe_link_speed *speed, bool *link_up, + bool link_up_wait_to_complete) { u32 links_reg; u32 i; @@ -673,7 +655,7 @@ static s32 ixgbe_check_mac_link_82598(st hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg); hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg); hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV, - &adapt_comp_reg); + &adapt_comp_reg); if (link_up_wait_to_complete) { for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { if ((link_reg & 1) && @@ -685,11 +667,11 @@ static s32 ixgbe_check_mac_link_82598(st } msec_delay(100); hw->phy.ops.read_reg(hw, 0xC79F, - IXGBE_TWINAX_DEV, - &link_reg); + IXGBE_TWINAX_DEV, + &link_reg); hw->phy.ops.read_reg(hw, 0xC00C, - IXGBE_TWINAX_DEV, - &adapt_comp_reg); + IXGBE_TWINAX_DEV, + &adapt_comp_reg); } } else { if ((link_reg & 1) && ((adapt_comp_reg & 1) == 0)) @@ -730,11 +712,6 @@ static s32 ixgbe_check_mac_link_82598(st (ixgbe_validate_link_ready(hw) != IXGBE_SUCCESS)) *link_up = FALSE; - /* if link is down, zero out the current_mode */ *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***