From owner-svn-src-all@freebsd.org Thu May 12 18:20:20 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3C8F6B386EE; Thu, 12 May 2016 18:20:20 +0000 (UTC) (envelope-from erj@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 0B43A1C22; Thu, 12 May 2016 18:20:19 +0000 (UTC) (envelope-from erj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u4CIKJNa003931; Thu, 12 May 2016 18:20:19 GMT (envelope-from erj@FreeBSD.org) Received: (from erj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u4CIKIpG003923; Thu, 12 May 2016 18:20:18 GMT (envelope-from erj@FreeBSD.org) Message-Id: <201605121820.u4CIKIpG003923@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: erj set sender to erj@FreeBSD.org using -f From: Eric Joyner Date: Thu, 12 May 2016 18:20:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r299548 - head/sys/dev/ixl X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 May 2016 18:20:20 -0000 Author: erj Date: Thu May 12 18:20:18 2016 New Revision: 299548 URL: https://svnweb.freebsd.org/changeset/base/299548 Log: ixl: Update to 1.4.9-k. Changes by author: Kamil Krawczyk i40e-shared: use explicit cast from u16 to u8 Anjali Singhai Jain i40e-shared: Add a Virtchnl offload for RSS PCTYPE V2 Eric Joyner ixl: Remove HP device IDs. Jesse Brandeburg i40e-shared: add small bit of debug Mitch Williams i40e-shared: check for stopped admin queue Mitch Williams i40e-shared: set aq count after memory allocation Jesse Brandeburg i40e-shared: remove forever unused ID Eric Joyner ixl: Fix bug where RSS does not hash to more than 16 queues. Shannon Nelson i40e-shared: define function capabilities in only one place Eric Joyner ixl: Change spacing, comments, and a single error message. Eric Joyner ixl: Save admin queue phy interrupt mask as a define. Eric Joyner ixl: Move callout_reset() to later in init_locked(), and stop clearing OACTIVE in driver flags. Eric Joyner ixl: Add new reset+build flow to init() if it detects that the admin queue is stopped. Eric Joyner ixl: Return EACCES instead of EPERM when an nvmupdate command fails. Eric Joyner ixl: Remove KX_A device ID. Differential Revision: https://reviews.freebsd.org/D6211 Reviewed by: sbruno, kmacy, jeffrey.e.pieper@intel.com MFC after: 2 weeks Sponsored by: Intel Corporation Modified: head/sys/dev/ixl/i40e_adminq.c head/sys/dev/ixl/i40e_adminq_cmd.h head/sys/dev/ixl/i40e_common.c head/sys/dev/ixl/i40e_devids.h head/sys/dev/ixl/i40e_lan_hmc.c head/sys/dev/ixl/i40e_virtchnl.h head/sys/dev/ixl/if_ixl.c head/sys/dev/ixl/ixl_pf.h Modified: head/sys/dev/ixl/i40e_adminq.c ============================================================================== --- head/sys/dev/ixl/i40e_adminq.c Thu May 12 18:19:53 2016 (r299547) +++ head/sys/dev/ixl/i40e_adminq.c Thu May 12 18:20:18 2016 (r299548) @@ -400,7 +400,6 @@ enum i40e_status_code i40e_init_asq(stru hw->aq.asq.next_to_use = 0; hw->aq.asq.next_to_clean = 0; - hw->aq.asq.count = hw->aq.num_asq_entries; /* allocate the ring memory */ ret_code = i40e_alloc_adminq_asq_ring(hw); @@ -418,6 +417,7 @@ enum i40e_status_code i40e_init_asq(stru goto init_adminq_free_rings; /* success! */ + hw->aq.asq.count = hw->aq.num_asq_entries; goto init_adminq_exit; init_adminq_free_rings: @@ -459,7 +459,6 @@ enum i40e_status_code i40e_init_arq(stru hw->aq.arq.next_to_use = 0; hw->aq.arq.next_to_clean = 0; - hw->aq.arq.count = hw->aq.num_arq_entries; /* allocate the ring memory */ ret_code = i40e_alloc_adminq_arq_ring(hw); @@ -477,6 +476,7 @@ enum i40e_status_code i40e_init_arq(stru goto init_adminq_free_rings; /* success! */ + hw->aq.arq.count = hw->aq.num_arq_entries; goto init_adminq_exit; init_adminq_free_rings: @@ -996,6 +996,13 @@ enum i40e_status_code i40e_clean_arq_ele /* take the lock before we start messing with the ring */ i40e_acquire_spinlock(&hw->aq.arq_spinlock); + if (hw->aq.arq.count == 0) { + i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, + "AQRX: Admin queue not initialized.\n"); + ret_code = I40E_ERR_QUEUE_EMPTY; + goto clean_arq_element_err; + } + /* set next_to_use to head */ if (!i40e_is_vf(hw)) ntu = (rd32(hw, hw->aq.arq.head) & I40E_PF_ARQH_ARQH_MASK); @@ -1062,6 +1069,7 @@ clean_arq_element_out: /* Set pending if needed, unlock and return */ if (pending != NULL) *pending = (ntc > ntu ? hw->aq.arq.count : 0) + (ntu - ntc); +clean_arq_element_err: i40e_release_spinlock(&hw->aq.arq_spinlock); if (i40e_is_nvm_update_op(&e->desc)) { Modified: head/sys/dev/ixl/i40e_adminq_cmd.h ============================================================================== --- head/sys/dev/ixl/i40e_adminq_cmd.h Thu May 12 18:19:53 2016 (r299547) +++ head/sys/dev/ixl/i40e_adminq_cmd.h Thu May 12 18:20:18 2016 (r299548) @@ -267,10 +267,6 @@ enum i40e_admin_queue_opc { i40e_aqc_opc_add_udp_tunnel = 0x0B00, i40e_aqc_opc_del_udp_tunnel = 0x0B01, - /* Proxy commands */ - i40e_aqc_opc_set_proxy_config = 0x0104, - i40e_aqc_opc_set_ns_proxy_table_entry = 0x0105, - /* Async Events */ i40e_aqc_opc_event_lan_overflow = 0x1001, @@ -410,6 +406,7 @@ struct i40e_aqc_list_capabilities_elemen #define I40E_AQ_CAP_ID_OS2BMC_CAP 0x0004 #define I40E_AQ_CAP_ID_FUNCTIONS_VALID 0x0005 #define I40E_AQ_CAP_ID_ALTERNATE_RAM 0x0006 +#define I40E_AQ_CAP_ID_WOL_AND_PROXY 0x0008 #define I40E_AQ_CAP_ID_SRIOV 0x0012 #define I40E_AQ_CAP_ID_VF 0x0013 #define I40E_AQ_CAP_ID_VMDQ 0x0014 @@ -430,6 +427,7 @@ struct i40e_aqc_list_capabilities_elemen #define I40E_AQ_CAP_ID_LED 0x0061 #define I40E_AQ_CAP_ID_SDP 0x0062 #define I40E_AQ_CAP_ID_MDIO 0x0063 +#define I40E_AQ_CAP_ID_WSR_PROT 0x0064 #define I40E_AQ_CAP_ID_FLEX10 0x00F1 #define I40E_AQ_CAP_ID_CEM 0x00F2 Modified: head/sys/dev/ixl/i40e_common.c ============================================================================== --- head/sys/dev/ixl/i40e_common.c Thu May 12 18:19:53 2016 (r299547) +++ head/sys/dev/ixl/i40e_common.c Thu May 12 18:20:18 2016 (r299548) @@ -55,7 +55,6 @@ enum i40e_status_code i40e_set_mac_type( switch (hw->device_id) { case I40E_DEV_ID_SFP_XL710: case I40E_DEV_ID_QEMU: - case I40E_DEV_ID_KX_A: case I40E_DEV_ID_KX_B: case I40E_DEV_ID_KX_C: case I40E_DEV_ID_QSFP_A: @@ -3130,35 +3129,6 @@ i40e_aq_erase_nvm_exit: return status; } -#define I40E_DEV_FUNC_CAP_SWITCH_MODE 0x01 -#define I40E_DEV_FUNC_CAP_MGMT_MODE 0x02 -#define I40E_DEV_FUNC_CAP_NPAR 0x03 -#define I40E_DEV_FUNC_CAP_OS2BMC 0x04 -#define I40E_DEV_FUNC_CAP_VALID_FUNC 0x05 -#define I40E_DEV_FUNC_CAP_SRIOV_1_1 0x12 -#define I40E_DEV_FUNC_CAP_VF 0x13 -#define I40E_DEV_FUNC_CAP_VMDQ 0x14 -#define I40E_DEV_FUNC_CAP_802_1_QBG 0x15 -#define I40E_DEV_FUNC_CAP_802_1_QBH 0x16 -#define I40E_DEV_FUNC_CAP_VSI 0x17 -#define I40E_DEV_FUNC_CAP_DCB 0x18 -#define I40E_DEV_FUNC_CAP_FCOE 0x21 -#define I40E_DEV_FUNC_CAP_ISCSI 0x22 -#define I40E_DEV_FUNC_CAP_RSS 0x40 -#define I40E_DEV_FUNC_CAP_RX_QUEUES 0x41 -#define I40E_DEV_FUNC_CAP_TX_QUEUES 0x42 -#define I40E_DEV_FUNC_CAP_MSIX 0x43 -#define I40E_DEV_FUNC_CAP_MSIX_VF 0x44 -#define I40E_DEV_FUNC_CAP_FLOW_DIRECTOR 0x45 -#define I40E_DEV_FUNC_CAP_IEEE_1588 0x46 -#define I40E_DEV_FUNC_CAP_FLEX10 0xF1 -#define I40E_DEV_FUNC_CAP_CEM 0xF2 -#define I40E_DEV_FUNC_CAP_IWARP 0x51 -#define I40E_DEV_FUNC_CAP_LED 0x61 -#define I40E_DEV_FUNC_CAP_SDP 0x62 -#define I40E_DEV_FUNC_CAP_MDIO 0x63 -#define I40E_DEV_FUNC_CAP_WR_CSR_PROT 0x64 - /** * i40e_parse_discover_capabilities * @hw: pointer to the hw struct @@ -3197,79 +3167,79 @@ static void i40e_parse_discover_capabili major_rev = cap->major_rev; switch (id) { - case I40E_DEV_FUNC_CAP_SWITCH_MODE: + case I40E_AQ_CAP_ID_SWITCH_MODE: p->switch_mode = number; break; - case I40E_DEV_FUNC_CAP_MGMT_MODE: + case I40E_AQ_CAP_ID_MNG_MODE: p->management_mode = number; break; - case I40E_DEV_FUNC_CAP_NPAR: + case I40E_AQ_CAP_ID_NPAR_ACTIVE: p->npar_enable = number; break; - case I40E_DEV_FUNC_CAP_OS2BMC: + case I40E_AQ_CAP_ID_OS2BMC_CAP: p->os2bmc = number; break; - case I40E_DEV_FUNC_CAP_VALID_FUNC: + case I40E_AQ_CAP_ID_FUNCTIONS_VALID: p->valid_functions = number; break; - case I40E_DEV_FUNC_CAP_SRIOV_1_1: + case I40E_AQ_CAP_ID_SRIOV: if (number == 1) p->sr_iov_1_1 = TRUE; break; - case I40E_DEV_FUNC_CAP_VF: + case I40E_AQ_CAP_ID_VF: p->num_vfs = number; p->vf_base_id = logical_id; break; - case I40E_DEV_FUNC_CAP_VMDQ: + case I40E_AQ_CAP_ID_VMDQ: if (number == 1) p->vmdq = TRUE; break; - case I40E_DEV_FUNC_CAP_802_1_QBG: + case I40E_AQ_CAP_ID_8021QBG: if (number == 1) p->evb_802_1_qbg = TRUE; break; - case I40E_DEV_FUNC_CAP_802_1_QBH: + case I40E_AQ_CAP_ID_8021QBR: if (number == 1) p->evb_802_1_qbh = TRUE; break; - case I40E_DEV_FUNC_CAP_VSI: + case I40E_AQ_CAP_ID_VSI: p->num_vsis = number; break; - case I40E_DEV_FUNC_CAP_DCB: + case I40E_AQ_CAP_ID_DCB: if (number == 1) { p->dcb = TRUE; p->enabled_tcmap = logical_id; p->maxtc = phys_id; } break; - case I40E_DEV_FUNC_CAP_FCOE: + case I40E_AQ_CAP_ID_FCOE: if (number == 1) p->fcoe = TRUE; break; - case I40E_DEV_FUNC_CAP_ISCSI: + case I40E_AQ_CAP_ID_ISCSI: if (number == 1) p->iscsi = TRUE; break; - case I40E_DEV_FUNC_CAP_RSS: + case I40E_AQ_CAP_ID_RSS: p->rss = TRUE; p->rss_table_size = number; p->rss_table_entry_width = logical_id; break; - case I40E_DEV_FUNC_CAP_RX_QUEUES: + case I40E_AQ_CAP_ID_RXQ: p->num_rx_qp = number; p->base_queue = phys_id; break; - case I40E_DEV_FUNC_CAP_TX_QUEUES: + case I40E_AQ_CAP_ID_TXQ: p->num_tx_qp = number; p->base_queue = phys_id; break; - case I40E_DEV_FUNC_CAP_MSIX: + case I40E_AQ_CAP_ID_MSIX: p->num_msix_vectors = number; break; - case I40E_DEV_FUNC_CAP_MSIX_VF: + case I40E_AQ_CAP_ID_VF_MSIX: p->num_msix_vectors_vf = number; break; - case I40E_DEV_FUNC_CAP_FLEX10: + case I40E_AQ_CAP_ID_FLEX10: if (major_rev == 1) { if (number == 1) { p->flex10_enable = TRUE; @@ -3285,38 +3255,38 @@ static void i40e_parse_discover_capabili p->flex10_mode = logical_id; p->flex10_status = phys_id; break; - case I40E_DEV_FUNC_CAP_CEM: + case I40E_AQ_CAP_ID_CEM: if (number == 1) p->mgmt_cem = TRUE; break; - case I40E_DEV_FUNC_CAP_IWARP: + case I40E_AQ_CAP_ID_IWARP: if (number == 1) p->iwarp = TRUE; break; - case I40E_DEV_FUNC_CAP_LED: + case I40E_AQ_CAP_ID_LED: if (phys_id < I40E_HW_CAP_MAX_GPIO) p->led[phys_id] = TRUE; break; - case I40E_DEV_FUNC_CAP_SDP: + case I40E_AQ_CAP_ID_SDP: if (phys_id < I40E_HW_CAP_MAX_GPIO) p->sdp[phys_id] = TRUE; break; - case I40E_DEV_FUNC_CAP_MDIO: + case I40E_AQ_CAP_ID_MDIO: if (number == 1) { p->mdio_port_num = phys_id; p->mdio_port_mode = logical_id; } break; - case I40E_DEV_FUNC_CAP_IEEE_1588: + case I40E_AQ_CAP_ID_1588: if (number == 1) p->ieee_1588 = TRUE; break; - case I40E_DEV_FUNC_CAP_FLOW_DIRECTOR: + case I40E_AQ_CAP_ID_FLOW_DIRECTOR: p->fd = TRUE; p->fd_filters_guaranteed = number; p->fd_filters_best_effort = logical_id; break; - case I40E_DEV_FUNC_CAP_WR_CSR_PROT: + case I40E_AQ_CAP_ID_WSR_PROT: p->wr_csr_prot = (u64)number; p->wr_csr_prot |= (u64)logical_id << 32; break; Modified: head/sys/dev/ixl/i40e_devids.h ============================================================================== --- head/sys/dev/ixl/i40e_devids.h Thu May 12 18:19:53 2016 (r299547) +++ head/sys/dev/ixl/i40e_devids.h Thu May 12 18:20:18 2016 (r299548) @@ -41,7 +41,6 @@ /* Device IDs */ #define I40E_DEV_ID_SFP_XL710 0x1572 #define I40E_DEV_ID_QEMU 0x1574 -#define I40E_DEV_ID_KX_A 0x157F #define I40E_DEV_ID_KX_B 0x1580 #define I40E_DEV_ID_KX_C 0x1581 #define I40E_DEV_ID_QSFP_A 0x1583 Modified: head/sys/dev/ixl/i40e_lan_hmc.c ============================================================================== --- head/sys/dev/ixl/i40e_lan_hmc.c Thu May 12 18:19:53 2016 (r299547) +++ head/sys/dev/ixl/i40e_lan_hmc.c Thu May 12 18:20:18 2016 (r299548) @@ -770,7 +770,7 @@ static void i40e_write_byte(u8 *hmc_bits /* prepare the bits and mask */ shift_width = ce_info->lsb % 8; - mask = BIT(ce_info->width) - 1; + mask = (u8)(BIT(ce_info->width) - 1); src_byte = *from; src_byte &= mask; @@ -955,7 +955,7 @@ static void i40e_read_byte(u8 *hmc_bits, /* prepare the bits and mask */ shift_width = ce_info->lsb % 8; - mask = BIT(ce_info->width) - 1; + mask = (u8)(BIT(ce_info->width) - 1); /* shift to correct alignment */ mask <<= shift_width; Modified: head/sys/dev/ixl/i40e_virtchnl.h ============================================================================== --- head/sys/dev/ixl/i40e_virtchnl.h Thu May 12 18:19:53 2016 (r299547) +++ head/sys/dev/ixl/i40e_virtchnl.h Thu May 12 18:20:18 2016 (r299548) @@ -161,6 +161,7 @@ struct i40e_virtchnl_vsi_resource { #define I40E_VIRTCHNL_VF_OFFLOAD_WB_ON_ITR 0x00000020 #define I40E_VIRTCHNL_VF_OFFLOAD_VLAN 0x00010000 #define I40E_VIRTCHNL_VF_OFFLOAD_RX_POLLING 0x00020000 +#define I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2 0x00040000 struct i40e_virtchnl_vf_resource { u16 num_vsis; Modified: head/sys/dev/ixl/if_ixl.c ============================================================================== --- head/sys/dev/ixl/if_ixl.c Thu May 12 18:19:53 2016 (r299547) +++ head/sys/dev/ixl/if_ixl.c Thu May 12 18:20:18 2016 (r299548) @@ -48,7 +48,7 @@ /********************************************************************* * Driver version *********************************************************************/ -char ixl_driver_version[] = "1.4.7-k"; +char ixl_driver_version[] = "1.4.9-k"; /********************************************************************* * PCI Device ID Table @@ -63,7 +63,6 @@ char ixl_driver_version[] = "1.4.7-k"; static ixl_vendor_info_t ixl_vendor_info_array[] = { {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_XL710, 0, 0, 0}, - {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_A, 0, 0, 0}, {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_B, 0, 0, 0}, {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_C, 0, 0, 0}, {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_A, 0, 0, 0}, @@ -71,8 +70,6 @@ static ixl_vendor_info_t ixl_vendor_info {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_C, 0, 0, 0}, {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T, 0, 0, 0}, {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T4, 0, 0, 0}, - {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_20G_KR2, 0, 0, 0}, - {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_20G_KR2_A, 0, 0, 0}, /* required last entry */ {0, 0, 0, 0, 0} }; @@ -552,7 +549,7 @@ ixl_attach(device_t dev) i40e_clear_hw(hw); error = i40e_pf_reset(hw); if (error) { - device_printf(dev,"PF reset failure %x\n", error); + device_printf(dev, "PF reset failure %x\n", error); error = EIO; goto err_out; } @@ -566,7 +563,7 @@ ixl_attach(device_t dev) /* Initialize the shared code */ error = i40e_init_shared_code(hw); if (error) { - device_printf(dev,"Unable to initialize the shared code\n"); + device_printf(dev, "Unable to initialize the shared code\n"); error = EIO; goto err_out; } @@ -668,8 +665,7 @@ ixl_attach(device_t dev) } /* Limit PHY interrupts to link, autoneg, and modules failure */ - error = i40e_aq_set_phy_int_mask(hw, - I40E_AQ_EVENT_LINK_UPDOWN | I40E_AQ_EVENT_MODULE_QUAL_FAIL, + error = i40e_aq_set_phy_int_mask(hw, IXL_DEFAULT_PHY_INT_MASK, NULL); if (error) { device_printf(dev, "i40e_aq_set_phy_mask() failed: err %d," @@ -1184,15 +1180,14 @@ ixl_init_locked(struct ixl_pf *pf) #ifdef IXL_FDIR filter.enable_fdir = TRUE; #endif + filter.hash_lut_size = I40E_HASH_LUT_SIZE_512; if (i40e_set_filter_control(hw, &filter)) - device_printf(dev, "set_filter_control() failed\n"); + device_printf(dev, "i40e_set_filter_control() failed\n"); /* Set up RSS */ ixl_config_rss(vsi); - /* - ** Prepare the VSI: rings, hmc contexts, etc... - */ + /* Prepare the VSI: rings, hmc contexts, etc... */ if (ixl_initialize_vsi(vsi)) { device_printf(dev, "initialize vsi failed!!\n"); return; @@ -1204,9 +1199,6 @@ ixl_init_locked(struct ixl_pf *pf) /* Setup vlan's if needed */ ixl_setup_vlan_filters(vsi); - /* Start the local timer */ - callout_reset(&pf->timer, hz, ixl_local_timer, pf); - /* Set up MSI/X routing and the ITR settings */ if (ixl_enable_msix) { ixl_configure_msix(pf); @@ -1236,19 +1228,163 @@ ixl_init_locked(struct ixl_pf *pf) i40e_get_link_status(hw, &pf->link_up); ixl_update_link_status(pf); + /* Start the local timer */ + callout_reset(&pf->timer, hz, ixl_local_timer, pf); + /* Now inform the stack we're ready */ ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; return; } +// XXX: super experimental stuff +static int +ixl_teardown_hw_structs(struct ixl_pf *pf) +{ + enum i40e_status_code status = 0; + struct i40e_hw *hw = &pf->hw; + device_t dev = pf->dev; + + /* Shutdown LAN HMC */ + if (hw->hmc.hmc_obj) { + status = i40e_shutdown_lan_hmc(hw); + if (status) { + device_printf(dev, + "init: LAN HMC shutdown failure; status %d\n", status); + goto err_out; + } + } + + // XXX: This gets called when we know the adminq is inactive; + // so we already know it's setup when we get here. + + /* Shutdown admin queue */ + status = i40e_shutdown_adminq(hw); + if (status) + device_printf(dev, + "init: Admin Queue shutdown failure; status %d\n", status); + +err_out: + return (status); +} + +static int +ixl_reset(struct ixl_pf *pf) +{ + struct i40e_hw *hw = &pf->hw; + device_t dev = pf->dev; + int error = 0; + + // XXX: clear_hw() actually writes to hw registers -- maybe this isn't necessary + i40e_clear_hw(hw); + error = i40e_pf_reset(hw); + if (error) { + device_printf(dev, "init: PF reset failure"); + error = EIO; + goto err_out; + } + + error = i40e_init_adminq(hw); + if (error) { + device_printf(dev, "init: Admin queue init failure; status code %d", error); + error = EIO; + goto err_out; + } + + i40e_clear_pxe_mode(hw); + + error = ixl_get_hw_capabilities(pf); + if (error) { + device_printf(dev, "init: Error retrieving HW capabilities; status code %d\n", error); + goto err_out; + } + + error = i40e_init_lan_hmc(hw, hw->func_caps.num_tx_qp, + hw->func_caps.num_rx_qp, 0, 0); + if (error) { + device_printf(dev, "init: LAN HMC init failed; status code %d\n", error); + error = EIO; + goto err_out; + } + + error = i40e_configure_lan_hmc(hw, I40E_HMC_MODEL_DIRECT_ONLY); + if (error) { + device_printf(dev, "init: LAN HMC config failed; status code %d\n", error); + error = EIO; + goto err_out; + } + + // XXX: need to do switch config here? + + error = i40e_aq_set_phy_int_mask(hw, IXL_DEFAULT_PHY_INT_MASK, + NULL); + if (error) { + device_printf(dev, "init: i40e_aq_set_phy_mask() failed: err %d," + " aq_err %d\n", error, hw->aq.asq_last_status); + error = EIO; + goto err_out; + } + + u8 set_fc_err_mask; + error = i40e_set_fc(hw, &set_fc_err_mask, true); + if (error) { + device_printf(dev, "init: setting link flow control failed; retcode %d," + " fc_err_mask 0x%02x\n", error, set_fc_err_mask); + goto err_out; + } + + // XXX: (Rebuild VSIs?) + + // Firmware delay workaround + if (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) || + (hw->aq.fw_maj_ver < 4)) { + i40e_msec_delay(75); + error = i40e_aq_set_link_restart_an(hw, TRUE, NULL); + if (error) { + device_printf(dev, "init: link restart failed, aq_err %d\n", + hw->aq.asq_last_status); + goto err_out; + } + } + + // [add_filter_to_drop_tx_flow_control_frames] + // - TODO: Implement + + // i40e_send_version + // - TODO: Properly implement + struct i40e_driver_version dv; + + dv.major_version = 1; + dv.minor_version = 1; + dv.build_version = 1; + dv.subbuild_version = 0; + // put in a driver version string that is less than 0x80 bytes long + bzero(&dv.driver_string, sizeof(dv.driver_string)); + i40e_aq_send_driver_version(hw, &dv, NULL); + +err_out: + return (error); +} + static void ixl_init(void *arg) { struct ixl_pf *pf = arg; int ret = 0; + /* + * If the aq is dead here, it probably means something outside of the driver + * did something to the adapter, like a PF reset. + * So rebuild the driver's state here if that occurs. + */ + if (!i40e_check_asq_alive(&pf->hw)) { + device_printf(pf->dev, "asq is not alive; rebuilding...\n"); + IXL_PF_LOCK(pf); + ixl_teardown_hw_structs(pf); + ixl_reset(pf); + IXL_PF_UNLOCK(pf); + } + /* Set up interrupt routing here */ if (pf->msix > 1) ret = ixl_assign_vsi_msix(pf); @@ -1992,7 +2128,7 @@ ixl_assign_vsi_legacy(struct ixl_pf *pf) pf->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); if (pf->res == NULL) { - device_printf(dev,"Unable to allocate" + device_printf(dev, "Unable to allocate" " bus resource: vsi legacy/msi interrupt\n"); return (ENXIO); } @@ -2829,11 +2965,11 @@ ixl_initialize_vsi(struct ixl_vsi *vsi) ctxt.pf_num = hw->pf_id; err = i40e_aq_get_vsi_params(hw, &ctxt, NULL); if (err) { - device_printf(dev,"get vsi params failed %x!!\n", err); + device_printf(dev, "i40e_aq_get_vsi_params() failed, error %d\n", err); return (err); } #ifdef IXL_DEBUG - printf("get_vsi_params: seid: %d, uplinkseid: %d, vsi_number: %d, " + device_printf(dev, "get_vsi_params: seid: %d, uplinkseid: %d, vsi_number: %d, " "vsis_allocated: %d, vsis_unallocated: %d, flags: 0x%x, " "pfnum: %d, vfnum: %d, stat idx: %d, enabled: %d\n", ctxt.seid, ctxt.uplink_seid, ctxt.vsi_number, @@ -2849,15 +2985,15 @@ ixl_initialize_vsi(struct ixl_vsi *vsi) ctxt.info.valid_sections = I40E_AQ_VSI_PROP_QUEUE_MAP_VALID; ctxt.info.mapping_flags |= I40E_AQ_VSI_QUE_MAP_CONTIG; ctxt.info.queue_mapping[0] = 0; - ctxt.info.tc_mapping[0] = 0x0800; + ctxt.info.tc_mapping[0] = 0x0c00; /* Set VLAN receive stripping mode */ ctxt.info.valid_sections |= I40E_AQ_VSI_PROP_VLAN_VALID; ctxt.info.port_vlan_flags = I40E_AQ_VSI_PVLAN_MODE_ALL; if (vsi->ifp->if_capenable & IFCAP_VLAN_HWTAGGING) - ctxt.info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_EMOD_STR_BOTH; + ctxt.info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_EMOD_STR_BOTH; else - ctxt.info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_EMOD_NOTHING; + ctxt.info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_EMOD_NOTHING; /* Keep copy of VSI info in VSI for statistic counters */ memcpy(&vsi->info, &ctxt.info, sizeof(ctxt.info)); @@ -2871,8 +3007,8 @@ ixl_initialize_vsi(struct ixl_vsi *vsi) err = i40e_aq_update_vsi_params(hw, &ctxt, NULL); if (err) { - device_printf(dev,"update vsi params failed %x!!\n", - hw->aq.asq_last_status); + device_printf(dev, "i40e_aq_update_vsi_params() failed, error %d, aq_error %d\n", + err, hw->aq.asq_last_status); return (err); } @@ -2884,7 +3020,6 @@ ixl_initialize_vsi(struct ixl_vsi *vsi) u32 txctl; u16 size; - /* Setup the HMC TX Context */ size = que->num_desc * sizeof(struct i40e_tx_desc); memset(&tctx, 0, sizeof(struct i40e_hmc_obj_txq)); @@ -5051,8 +5186,15 @@ ixl_handle_nvmupd_cmd(struct ixl_pf *pf, nvma = (struct i40e_nvm_access *)ifd->ifd_data; status = i40e_nvmupd_command(hw, nvma, nvma->data, &perrno); + if (status) + device_printf(dev, "i40e_nvmupd_command status %d, perrno %d\n", + status, perrno); - return (status) ? perrno : 0; + /* Convert EPERM error code for tools */ + if (perrno == -EPERM) + return (-EACCES); + else + return (perrno); } #ifdef IXL_DEBUG_SYSCTL Modified: head/sys/dev/ixl/ixl_pf.h ============================================================================== --- head/sys/dev/ixl/ixl_pf.h Thu May 12 18:19:53 2016 (r299547) +++ head/sys/dev/ixl/ixl_pf.h Thu May 12 18:20:18 2016 (r299548) @@ -118,6 +118,9 @@ struct ixl_pf { #define I40E_NVM_ACCESS \ (((((((('E' << 4) + '1') << 4) + 'K') << 4) + 'G') << 4) | 5) +#define IXL_DEFAULT_PHY_INT_MASK \ + (I40E_AQ_EVENT_LINK_UPDOWN | I40E_AQ_EVENT_MODULE_QUAL_FAIL) + #define IXL_SET_ADVERTISE_HELP \ "Control link advertise speed:\n" \ "\tFlags:\n" \