Index: sys/dev/ixl/if_ixl.c =================================================================== --- sys/dev/ixl/if_ixl.c +++ sys/dev/ixl/if_ixl.c @@ -40,7 +40,7 @@ /********************************************************************* * Driver version *********************************************************************/ -char ixl_driver_version[] = "1.2.8"; +char ixl_driver_version[] = "1.3.0"; /********************************************************************* * PCI Device ID Table @@ -174,7 +174,7 @@ static void ixl_stat_update32(struct i40e_hw *, u32, bool, u64 *, u64 *); -#ifdef IXL_DEBUG +#ifdef IXL_DEBUG_SYSCTL static int ixl_sysctl_link_status(SYSCTL_HANDLER_ARGS); static int ixl_sysctl_phy_abilities(SYSCTL_HANDLER_ARGS); static int ixl_sysctl_sw_filter_list(SYSCTL_HANDLER_ARGS); @@ -427,7 +427,7 @@ OID_AUTO, "dynamic_tx_itr", CTLFLAG_RW, &ixl_dynamic_tx_itr, 0, "Dynamic TX ITR"); -#ifdef IXL_DEBUG +#ifdef IXL_DEBUG_SYSCTL SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "link_status", CTLTYPE_STRING | CTLFLAG_RD, @@ -662,8 +662,9 @@ /* Reset port's advertised speeds */ if (!i40e_is_40G_device(hw->device_id)) { - pf->advertised_speed = 0x7; - ixl_set_advertised_speeds(pf, 0x7); + pf->advertised_speed = + (hw->device_id == I40E_DEV_ID_10G_BASE_T) ? 0x7 : 0x6; + ixl_set_advertised_speeds(pf, pf->advertised_speed); } /* Register for VLAN events */ @@ -1407,6 +1408,12 @@ case I40E_PHY_TYPE_10GBASE_SFPP_CU: ifmr->ifm_active |= IFM_10G_TWINAX; break; + case I40E_PHY_TYPE_10GBASE_KR: + /* + ** this is not technically correct + ** but FreeBSD does not have the media + ** type defined yet, so its a compromise. + */ case I40E_PHY_TYPE_10GBASE_SR: ifmr->ifm_active |= IFM_10G_SR; break; @@ -1721,8 +1728,10 @@ vsi->active_queues |= ((u64)1 << que->me); } if (que->busy >= IXL_MAX_TX_BUSY) { +#ifdef IXL_DEBUG device_printf(dev,"Warning queue %d " "appears to be hung!\n", i); +#endif que->busy = IXL_QUEUE_HUNG; ++hung; } @@ -1765,6 +1774,15 @@ "Full Duplex", ixl_fc_string[fc]); } vsi->link_active = TRUE; + /* + ** Warn user if link speed on NPAR enabled + ** partition is not at least 10GB + */ + if (hw->func_caps.npar_enable && + (hw->phy.link_info.link_speed == I40E_LINK_SPEED_1GB || + hw->phy.link_info.link_speed == I40E_LINK_SPEED_100MB)) + device_printf(dev, "The partition detected link" + "speed that is less than 10Gbps\n"); if_link_state_change(ifp, LINK_STATE_UP); } } else { /* Link down */ @@ -1928,7 +1946,7 @@ que->tq = taskqueue_create_fast("ixl_que", M_NOWAIT, taskqueue_thread_enqueue, &que->tq); taskqueue_start_threads(&que->tq, 1, PI_NET, "%s que", - device_get_nameunit(pf->dev)); + device_get_nameunit(dev)); } return (0); @@ -2383,7 +2401,8 @@ if (aq_error == I40E_ERR_UNKNOWN_PHY) { /* Need delay to detect fiber correctly */ i40e_msec_delay(200); - aq_error = i40e_aq_get_phy_capabilities(hw, FALSE, TRUE, &abilities_resp, NULL); + aq_error = i40e_aq_get_phy_capabilities(hw, FALSE, + TRUE, &abilities_resp, NULL); if (aq_error == I40E_ERR_UNKNOWN_PHY) device_printf(dev, "Unknown PHY type detected!\n"); else @@ -3043,7 +3062,6 @@ "Multicast Packets Transmitted"}, {ð_stats->tx_broadcast, "bcast_pkts_txd", "Broadcast Packets Transmitted"}, - {ð_stats->tx_discards, "tx_discards", "Discarded TX packets"}, // end {0,0,0} }; @@ -3126,17 +3144,16 @@ struct ixl_pf *pf = (struct ixl_pf *)vsi->back; struct i40e_hw *hw = vsi->hw; u32 lut = 0; - u64 set_hena, hena; + u64 set_hena = 0, hena; int i, j; - - static const u32 seed[I40E_PFQF_HKEY_MAX_INDEX + 1] = {0x41b01687, - 0x183cfd8c, 0xce880440, 0x580cbc3c, 0x35897377, - 0x328b25e1, 0x4fa98922, 0xb7d90c14, 0xd5bad70d, - 0xcd15a2c1, 0xe8580225, 0x4a1e9d11, 0xfe5731be}; + u32 rss_seed[IXL_KEYSZ] = {0x41b01687, + 0x183cfd8c, 0xce880440, 0x580cbc3c, + 0x35897377, 0x328b25e1, 0x4fa98922, + 0xb7d90c14, 0xd5bad70d, 0xcd15a2c1}; /* Fill out hash function seed */ - for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) - wr32(hw, I40E_PFQF_HKEY(i), seed[i]); + for (i = 0; i < IXL_KEYSZ; i++) + wr32(hw, I40E_PFQF_HKEY(i), rss_seed[i]); /* Enable PCTYPES for RSS: */ set_hena = @@ -3401,7 +3418,7 @@ a = malloc(sizeof(struct i40e_aqc_add_macvlan_element_data) * cnt, M_DEVBUF, M_NOWAIT | M_ZERO); if (a == NULL) { - device_printf(dev, "add hw filter failed to get memory\n"); + device_printf(dev, "add_hw_filters failed to get memory\n"); return; } @@ -3426,8 +3443,8 @@ if (j > 0) { err = i40e_aq_add_macvlan(hw, vsi->seid, a, j, NULL); if (err) - device_printf(dev, "aq_add_macvlan failure %d\n", - hw->aq.asq_last_status); + device_printf(dev, "aq_add_macvlan err %d, aq_error %d\n", + err, hw->aq.asq_last_status); else vsi->hw_filters_add += j; } @@ -3476,6 +3493,7 @@ err = i40e_aq_remove_macvlan(hw, vsi->seid, d, j, NULL); /* NOTE: returns ENOENT every time but seems to work fine, so we'll ignore that specific error. */ + // TODO: Does this still occur on current firmwares? if (err && hw->aq.asq_last_status != I40E_AQ_RC_ENOENT) { int sc = 0; for (int i = 0; i < j; i++) @@ -3828,29 +3846,6 @@ pf->stat_offsets_loaded, &osd->link_xoff_tx, &nsd->link_xoff_tx); - /* Priority flow control stats */ -#if 0 - for (int i = 0; i < 8; i++) { - ixl_stat_update32(hw, I40E_GLPRT_PXONRXC(hw->port, i), - pf->stat_offsets_loaded, - &osd->priority_xon_rx[i], - &nsd->priority_xon_rx[i]); - ixl_stat_update32(hw, I40E_GLPRT_PXONTXC(hw->port, i), - pf->stat_offsets_loaded, - &osd->priority_xon_tx[i], - &nsd->priority_xon_tx[i]); - ixl_stat_update32(hw, I40E_GLPRT_PXOFFTXC(hw->port, i), - pf->stat_offsets_loaded, - &osd->priority_xoff_tx[i], - &nsd->priority_xoff_tx[i]); - ixl_stat_update32(hw, - I40E_GLPRT_RXON2OFFCNT(hw->port, i), - pf->stat_offsets_loaded, - &osd->priority_xon_2_xoff[i], - &nsd->priority_xon_2_xoff[i]); - } -#endif - /* Packet size stats rx */ ixl_stat_update48(hw, I40E_GLPRT_PRC64H(hw->port), I40E_GLPRT_PRC64L(hw->port), @@ -4377,6 +4372,15 @@ return (EAGAIN); } + /* + ** This seems a bit heavy handed, but we + ** need to get a reinit on some devices + */ + IXL_PF_LOCK(pf); + ixl_stop(pf); + ixl_init_locked(pf); + IXL_PF_UNLOCK(pf); + return (0); } @@ -4521,7 +4525,7 @@ } -#ifdef IXL_DEBUG +#ifdef IXL_DEBUG_SYSCTL static int ixl_sysctl_link_status(SYSCTL_HANDLER_ARGS) { @@ -4630,6 +4634,16 @@ #define IXL_SW_RES_SIZE 0x14 static int +ixl_res_alloc_cmp(const void *a, const void *b) +{ + const struct i40e_aqc_switch_resource_alloc_element_resp *one, *two; + one = (struct i40e_aqc_switch_resource_alloc_element_resp *)a; + two = (struct i40e_aqc_switch_resource_alloc_element_resp *)b; + + return ((int)one->resource_type - (int)two->resource_type); +} + +static int ixl_sysctl_hw_res_alloc(SYSCTL_HANDLER_ARGS) { struct ixl_pf *pf = (struct ixl_pf *)arg1; @@ -4647,6 +4661,7 @@ return (ENOMEM); } + bzero(resp, sizeof(resp)); error = i40e_aq_get_switch_resource_alloc(hw, &num_entries, resp, IXL_SW_RES_SIZE, @@ -4657,9 +4672,14 @@ sbuf_delete(buf); return error; } - device_printf(dev, "Num_entries: %d\n", num_entries); + + /* Sort entries by type for display */ + qsort(resp, num_entries, + sizeof(struct i40e_aqc_switch_resource_alloc_element_resp), + &ixl_res_alloc_cmp); sbuf_cat(buf, "\n"); + sbuf_printf(buf, "# of entries: %d\n", num_entries); sbuf_printf(buf, "Type | Guaranteed | Total | Used | Un-allocated\n" " | (this) | (all) | (this) | (all) \n"); @@ -4847,5 +4867,5 @@ sbuf_delete(buf); return error; } -#endif +#endif /* IXL_DEBUG_SYSCTL */ Index: sys/dev/ixl/if_ixlv.c =================================================================== --- sys/dev/ixl/if_ixlv.c +++ sys/dev/ixl/if_ixlv.c @@ -40,7 +40,7 @@ /********************************************************************* * Driver version *********************************************************************/ -char ixlv_driver_version[] = "1.1.18"; +char ixlv_driver_version[] = "1.2.0"; /********************************************************************* * PCI Device ID Table @@ -1379,8 +1379,9 @@ TASK_INIT(&que->task, 0, ixlv_handle_que, que); que->tq = taskqueue_create_fast("ixlv_que", M_NOWAIT, taskqueue_thread_enqueue, &que->tq); - taskqueue_start_threads(&que->tq, 1, PI_NET, "%s que", - device_get_nameunit(sc->dev)); + taskqueue_start_threads(&que->tq, 1, PI_NET, "%s que", + device_get_nameunit(dev)); + } return (0); @@ -2521,16 +2522,13 @@ struct i40e_hw *hw = &sc->hw; struct ixl_vsi *vsi = &sc->vsi; u32 lut = 0; - u64 set_hena, hena; + u64 set_hena = 0, hena; int i, j; - - /* set up random bits */ - static const u32 seed[I40E_VFQF_HKEY_MAX_INDEX + 1] = { - 0x794221b4, 0xbca0c5ab, 0x6cd5ebd9, 0x1ada6127, - 0x983b3aa1, 0x1c4e71eb, 0x7f6328b2, 0xfcdc0da0, - 0xc135cafa, 0x7a6f7e2d, 0xe7102d28, 0x163cd12e, - 0x4954b126 }; - + u32 rss_seed[IXL_KEYSZ] = {0x41b01687, + 0x183cfd8c, 0xce880440, 0x580cbc3c, + 0x35897377, 0x328b25e1, 0x4fa98922, + 0xb7d90c14, 0xd5bad70d, 0xcd15a2c1}; + /* Don't set up RSS if using a single queue */ if (vsi->num_queues == 1) { wr32(hw, I40E_VFQF_HENA(0), 0); @@ -2540,8 +2538,8 @@ } /* Fill out hash function seed */ - for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++) - wr32(hw, I40E_VFQF_HKEY(i), seed[i]); + for (i = 0; i <= IXL_KEYSZ; i++) + wr32(hw, I40E_VFQF_HKEY(i), rss_seed[i]); /* Enable PCTYPES for RSS: */ set_hena = @@ -2564,16 +2562,15 @@ wr32(hw, I40E_VFQF_HENA(1), (u32)(hena >> 32)); /* Populate the LUT with max no. of queues in round robin fashion */ - for (i = 0, j = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; j++) { + for (i = 0, j = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++, j++) { if (j == vsi->num_queues) j = 0; /* lut = 4-byte sliding window of 4 lut entries */ lut = (lut << 8) | (j & 0xF); /* On i = 3, we have 4 entries in lut; write to the register */ - if ((j & 3) == 3) { + if ((i & 3) == 3) { wr32(hw, I40E_VFQF_HLUT(i), lut); DDPRINTF(sc->dev, "HLUT(%2d): %#010x", i, lut); - i++; } } ixl_flush(hw); Index: sys/dev/ixl/ixl.h =================================================================== --- sys/dev/ixl/ixl.h +++ sys/dev/ixl/ixl.h @@ -93,7 +93,7 @@ #include "i40e_type.h" #include "i40e_prototype.h" -#ifdef IXL_DEBUG +#if defined(IXL_DEBUG) || defined(IXL_DEBUG_SYSCTL) #include #define MAC_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x" @@ -101,7 +101,13 @@ (mac_addr)[0], (mac_addr)[1], (mac_addr)[2], (mac_addr)[3], \ (mac_addr)[4], (mac_addr)[5] #define ON_OFF_STR(is_set) ((is_set) ? "On" : "Off") +#endif /* IXL_DEBUG || IXL_DEBUG_SYSCTL */ +#ifdef IXL_DEBUG +/* Enable debug sysctls */ +#ifndef IXL_DEBUG_SYSCTL +#define IXL_DEBUG_SYSCTL 1 +#endif #define _DBG_PRINTF(S, ...) printf("%s: " S "\n", __func__, ##__VA_ARGS__) #define _DEV_DBG_PRINTF(dev, S, ...) device_printf(dev, "%s: " S "\n", __func__, ##__VA_ARGS__) @@ -128,7 +134,7 @@ #define HW_DEBUGOUT(...) if (DEBUG_HW) _DBG_PRINTF(__VA_ARGS__) -#else +#else /* no IXL_DEBUG */ #define DEBUG_INIT 0 #define DEBUG_IOCTL 0 #define DEBUG_HW 0 @@ -144,7 +150,7 @@ #define IOCTL_DBG_IF2(...) #define IOCTL_DBG_IF(...) #define HW_DEBUGOUT(...) -#endif +#endif /* IXL_DEBUG */ /* Tunables */ @@ -214,6 +220,7 @@ #define IXL_MAX_TSO_SEGS 66 #define IXL_SPARSE_CHAIN 6 #define IXL_QUEUE_HUNG 0x80000000 +#define IXL_KEYSZ 10 /* ERJ: hardware can support ~1.5k filters between all functions */ #define IXL_MAX_FILTERS 256 Index: sys/dev/ixl/ixl_txrx.c =================================================================== --- sys/dev/ixl/ixl_txrx.c +++ sys/dev/ixl/ixl_txrx.c @@ -66,8 +66,8 @@ struct tx_ring *txr; int err, i; - /* check if flowid is set */ - if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) + /* Which queue to use */ + if ((m->m_flags & M_FLOWID) != 0) i = m->m_pkthdr.flowid % vsi->num_queues; else i = curcpu % vsi->num_queues; @@ -1543,7 +1543,7 @@ if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) ixl_rx_checksum(sendmp, status, error, ptype); sendmp->m_pkthdr.flowid = que->msix; - M_HASHTYPE_SET(sendmp, M_HASHTYPE_OPAQUE); + sendmp->m_flags |= M_FLOWID; } next_desc: bus_dmamap_sync(rxr->dma.tag, rxr->dma.map,