Date: Fri, 11 Dec 2015 12:47:49 +0000 (UTC) From: Steven Hartland <smh@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r292097 - stable/10/sys/dev/ixl Message-ID: <201512111247.tBBClnLI053338@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: smh Date: Fri Dec 11 12:47:49 2015 New Revision: 292097 URL: https://svnweb.freebsd.org/changeset/base/292097 Log: MFC r279858 & r279860: SRIOV & 20G support Sponsored by: Multiplay Modified: stable/10/sys/dev/ixl/i40e_adminq_cmd.h stable/10/sys/dev/ixl/i40e_common.c stable/10/sys/dev/ixl/i40e_prototype.h stable/10/sys/dev/ixl/i40e_type.h stable/10/sys/dev/ixl/if_ixl.c stable/10/sys/dev/ixl/if_ixlv.c stable/10/sys/dev/ixl/ixl.h stable/10/sys/dev/ixl/ixl_pf.h stable/10/sys/dev/ixl/ixl_txrx.c stable/10/sys/dev/ixl/ixlv.h stable/10/sys/dev/ixl/ixlvc.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/ixl/i40e_adminq_cmd.h ============================================================================== --- stable/10/sys/dev/ixl/i40e_adminq_cmd.h Fri Dec 11 12:24:11 2015 (r292096) +++ stable/10/sys/dev/ixl/i40e_adminq_cmd.h Fri Dec 11 12:47:49 2015 (r292097) @@ -42,7 +42,7 @@ */ #define I40E_FW_API_VERSION_MAJOR 0x0001 -#define I40E_FW_API_VERSION_MINOR 0x0004 +#define I40E_FW_API_VERSION_MINOR 0x0002 struct i40e_aq_desc { __le16 flags; @@ -140,7 +140,12 @@ enum i40e_admin_queue_opc { i40e_aqc_opc_list_func_capabilities = 0x000A, i40e_aqc_opc_list_dev_capabilities = 0x000B, + i40e_aqc_opc_set_cppm_configuration = 0x0103, + i40e_aqc_opc_set_arp_proxy_entry = 0x0104, + i40e_aqc_opc_set_ns_proxy_entry = 0x0105, + /* LAA */ + i40e_aqc_opc_mng_laa = 0x0106, /* AQ obsolete */ i40e_aqc_opc_mac_address_read = 0x0107, i40e_aqc_opc_mac_address_write = 0x0108, @@ -265,6 +270,7 @@ enum i40e_admin_queue_opc { /* Tunnel commands */ i40e_aqc_opc_add_udp_tunnel = 0x0B00, i40e_aqc_opc_del_udp_tunnel = 0x0B01, + i40e_aqc_opc_tunnel_key_structure = 0x0B10, /* Async Events */ i40e_aqc_opc_event_lan_overflow = 0x1001, @@ -276,6 +282,8 @@ enum i40e_admin_queue_opc { i40e_aqc_opc_oem_ocbb_initialize = 0xFE03, /* debug commands */ + i40e_aqc_opc_debug_get_deviceid = 0xFF00, + i40e_aqc_opc_debug_set_mode = 0xFF01, i40e_aqc_opc_debug_read_reg = 0xFF03, i40e_aqc_opc_debug_write_reg = 0xFF04, i40e_aqc_opc_debug_modify_reg = 0xFF07, @@ -509,8 +517,7 @@ struct i40e_aqc_mac_address_read { #define I40E_AQC_SAN_ADDR_VALID 0x20 #define I40E_AQC_PORT_ADDR_VALID 0x40 #define I40E_AQC_WOL_ADDR_VALID 0x80 -#define I40E_AQC_MC_MAG_EN_VALID 0x100 -#define I40E_AQC_ADDR_VALID_MASK 0x1F0 +#define I40E_AQC_ADDR_VALID_MASK 0xf0 u8 reserved[6]; __le32 addr_high; __le32 addr_low; @@ -533,9 +540,7 @@ struct i40e_aqc_mac_address_write { #define I40E_AQC_WRITE_TYPE_LAA_ONLY 0x0000 #define I40E_AQC_WRITE_TYPE_LAA_WOL 0x4000 #define I40E_AQC_WRITE_TYPE_PORT 0x8000 -#define I40E_AQC_WRITE_TYPE_UPDATE_MC_MAG 0xC000 -#define I40E_AQC_WRITE_TYPE_MASK 0xC000 - +#define I40E_AQC_WRITE_TYPE_MASK 0xc000 __le16 mac_sah; __le32 mac_sal; u8 reserved[8]; @@ -1071,7 +1076,6 @@ struct i40e_aqc_set_vsi_promiscuous_mode __le16 seid; #define I40E_AQC_VSI_PROM_CMD_SEID_MASK 0x3FF __le16 vlan_tag; -#define I40E_AQC_SET_VSI_VLAN_MASK 0x0FFF #define I40E_AQC_SET_VSI_VLAN_VALID 0x8000 u8 reserved[8]; }; @@ -2066,12 +2070,6 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_star #define I40E_AQC_CEE_PFC_STATUS_MASK (0x7 << I40E_AQC_CEE_PFC_STATUS_SHIFT) #define I40E_AQC_CEE_APP_STATUS_SHIFT 0x8 #define I40E_AQC_CEE_APP_STATUS_MASK (0x7 << I40E_AQC_CEE_APP_STATUS_SHIFT) -#define I40E_AQC_CEE_FCOE_STATUS_SHIFT 0x8 -#define I40E_AQC_CEE_FCOE_STATUS_MASK (0x7 << I40E_AQC_CEE_FCOE_STATUS_SHIFT) -#define I40E_AQC_CEE_ISCSI_STATUS_SHIFT 0xA -#define I40E_AQC_CEE_ISCSI_STATUS_MASK (0x7 << I40E_AQC_CEE_ISCSI_STATUS_SHIFT) -#define I40E_AQC_CEE_FIP_STATUS_SHIFT 0x10 -#define I40E_AQC_CEE_FIP_STATUS_MASK (0x7 << I40E_AQC_CEE_FIP_STATUS_SHIFT) struct i40e_aqc_get_cee_dcb_cfg_v1_resp { u8 reserved1; u8 oper_num_tc; Modified: stable/10/sys/dev/ixl/i40e_common.c ============================================================================== --- stable/10/sys/dev/ixl/i40e_common.c Fri Dec 11 12:24:11 2015 (r292096) +++ stable/10/sys/dev/ixl/i40e_common.c Fri Dec 11 12:47:49 2015 (r292097) @@ -866,7 +866,7 @@ static enum i40e_media_type i40e_get_med return media; } -#define I40E_PF_RESET_WAIT_COUNT 110 +#define I40E_PF_RESET_WAIT_COUNT 200 /** * i40e_pf_reset - Reset the PF * @hw: pointer to the hardware structure @@ -1108,11 +1108,9 @@ u32 i40e_led_get(struct i40e_hw *hw) if (!gpio_val) continue; - /* ignore gpio LED src mode entries related to the activity - * LEDs - */ - current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) - >> I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT); + /* ignore gpio LED src mode entries related to the activity LEDs */ + current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) >> + I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT); switch (current_mode) { case I40E_COMBINED_ACTIVITY: case I40E_FILTER_ACTIVITY: @@ -1156,11 +1154,9 @@ void i40e_led_set(struct i40e_hw *hw, u3 if (!gpio_val) continue; - /* ignore gpio LED src mode entries related to the activity - * LEDs - */ - current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) - >> I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT); + /* ignore gpio LED src mode entries related to the activity LEDs */ + current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) >> + I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT); switch (current_mode) { case I40E_COMBINED_ACTIVITY: case I40E_FILTER_ACTIVITY: @@ -1529,6 +1525,7 @@ aq_get_link_info_exit: return status; } + /** * i40e_aq_set_phy_int_mask * @hw: pointer to the hw struct @@ -2816,13 +2813,12 @@ i40e_aq_erase_nvm_exit: #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_MFP_MODE_1 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 @@ -2840,7 +2836,6 @@ static void i40e_parse_discover_capabili struct i40e_aqc_list_capabilities_element_resp *cap; u32 valid_functions, num_functions; u32 number, logical_id, phys_id; - u8 major_rev; struct i40e_hw_capabilities *p; u32 i = 0; u16 id; @@ -2859,7 +2854,6 @@ static void i40e_parse_discover_capabili number = LE32_TO_CPU(cap->number); logical_id = LE32_TO_CPU(cap->logical_id); phys_id = LE32_TO_CPU(cap->phys_id); - major_rev = cap->major_rev; switch (id) { case I40E_DEV_FUNC_CAP_SWITCH_MODE: @@ -2934,21 +2928,9 @@ static void i40e_parse_discover_capabili case I40E_DEV_FUNC_CAP_MSIX_VF: p->num_msix_vectors_vf = number; break; - case I40E_DEV_FUNC_CAP_FLEX10: - if (major_rev == 1) { - if (number == 1) { - p->flex10_enable = TRUE; - p->flex10_capable = TRUE; - } - } else { - /* Capability revision >= 2 */ - if (number & 1) - p->flex10_enable = TRUE; - if (number & 2) - p->flex10_capable = TRUE; - } - p->flex10_mode = logical_id; - p->flex10_status = phys_id; + case I40E_DEV_FUNC_CAP_MFP_MODE_1: + if (number == 1) + p->mfp_mode_1 = TRUE; break; case I40E_DEV_FUNC_CAP_CEM: if (number == 1) @@ -2981,18 +2963,11 @@ static void i40e_parse_discover_capabili p->fd_filters_guaranteed = number; p->fd_filters_best_effort = logical_id; break; - case I40E_DEV_FUNC_CAP_WR_CSR_PROT: - p->wr_csr_prot = (u64)number; - p->wr_csr_prot |= (u64)logical_id << 32; - break; default: break; } } - if (p->fcoe) - i40e_debug(hw, I40E_DEBUG_ALL, "device is FCoE capable\n"); - /* Always disable FCoE if compiled without the I40E_FCOE_ENA flag */ p->fcoe = FALSE; @@ -4948,63 +4923,6 @@ void i40e_set_pci_config_data(struct i40 } /** - * i40e_aq_debug_dump - * @hw: pointer to the hardware structure - * @cluster_id: specific cluster to dump - * @table_id: table id within cluster - * @start_index: index of line in the block to read - * @buff_size: dump buffer size - * @buff: dump buffer - * @ret_buff_size: actual buffer size returned - * @ret_next_table: next block to read - * @ret_next_index: next index to read - * - * Dump internal FW/HW data for debug purposes. - * - **/ -enum i40e_status_code i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id, - u8 table_id, u32 start_index, u16 buff_size, - void *buff, u16 *ret_buff_size, - u8 *ret_next_table, u32 *ret_next_index, - struct i40e_asq_cmd_details *cmd_details) -{ - struct i40e_aq_desc desc; - struct i40e_aqc_debug_dump_internals *cmd = - (struct i40e_aqc_debug_dump_internals *)&desc.params.raw; - struct i40e_aqc_debug_dump_internals *resp = - (struct i40e_aqc_debug_dump_internals *)&desc.params.raw; - enum i40e_status_code status; - - if (buff_size == 0 || !buff) - return I40E_ERR_PARAM; - - i40e_fill_default_direct_cmd_desc(&desc, - i40e_aqc_opc_debug_dump_internals); - /* Indirect Command */ - desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF); - if (buff_size > I40E_AQ_LARGE_BUF) - desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB); - - cmd->cluster_id = cluster_id; - cmd->table_id = table_id; - cmd->idx = CPU_TO_LE32(start_index); - - desc.datalen = CPU_TO_LE16(buff_size); - - status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details); - if (!status) { - if (ret_buff_size != NULL) - *ret_buff_size = LE16_TO_CPU(desc.datalen); - if (ret_next_table != NULL) - *ret_next_table = resp->table_id; - if (ret_next_index != NULL) - *ret_next_index = LE32_TO_CPU(resp->idx); - } - - return status; -} - -/** * i40e_read_bw_from_alt_ram * @hw: pointer to the hardware structure * @max_bw: pointer for max_bw read Modified: stable/10/sys/dev/ixl/i40e_prototype.h ============================================================================== --- stable/10/sys/dev/ixl/i40e_prototype.h Fri Dec 11 12:24:11 2015 (r292096) +++ stable/10/sys/dev/ixl/i40e_prototype.h Fri Dec 11 12:47:49 2015 (r292097) @@ -445,9 +445,4 @@ enum i40e_status_code i40e_aq_add_rem_co u16 vsi_seid, u16 queue, bool is_add, struct i40e_control_filter_stats *stats, struct i40e_asq_cmd_details *cmd_details); -enum i40e_status_code i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id, - u8 table_id, u32 start_index, u16 buff_size, - void *buff, u16 *ret_buff_size, - u8 *ret_next_table, u32 *ret_next_index, - struct i40e_asq_cmd_details *cmd_details); #endif /* _I40E_PROTOTYPE_H_ */ Modified: stable/10/sys/dev/ixl/i40e_type.h ============================================================================== --- stable/10/sys/dev/ixl/i40e_type.h Fri Dec 11 12:24:11 2015 (r292096) +++ stable/10/sys/dev/ixl/i40e_type.h Fri Dec 11 12:47:49 2015 (r292097) @@ -287,17 +287,7 @@ struct i40e_hw_capabilities { bool dcb; bool fcoe; bool iscsi; /* Indicates iSCSI enabled */ - bool flex10_enable; - bool flex10_capable; - u32 flex10_mode; -#define I40E_FLEX10_MODE_UNKNOWN 0x0 -#define I40E_FLEX10_MODE_DCC 0x1 -#define I40E_FLEX10_MODE_DCI 0x2 - - u32 flex10_status; -#define I40E_FLEX10_STATUS_DCC_ERROR 0x1 -#define I40E_FLEX10_STATUS_VC_MODE 0x2 - + bool mfp_mode_1; bool mgmt_cem; bool ieee_1588; bool iwarp; @@ -326,7 +316,6 @@ struct i40e_hw_capabilities { u8 rx_buf_chain_len; u32 enabled_tcmap; u32 maxtc; - u64 wr_csr_prot; }; struct i40e_mac_info { @@ -573,7 +562,7 @@ struct i40e_hw { u32 debug_mask; }; -static INLINE bool i40e_is_vf(struct i40e_hw *hw) +static inline bool i40e_is_vf(struct i40e_hw *hw) { return hw->mac.type == I40E_MAC_VF; } @@ -1274,9 +1263,6 @@ struct i40e_hw_port_stats { /* flow director stats */ u64 fd_atr_match; u64 fd_sb_match; - u64 fd_atr_tunnel_match; - u32 fd_atr_status; - u32 fd_sb_status; /* EEE LPI */ u32 tx_lpi_status; u32 rx_lpi_status; Modified: stable/10/sys/dev/ixl/if_ixl.c ============================================================================== --- stable/10/sys/dev/ixl/if_ixl.c Fri Dec 11 12:24:11 2015 (r292096) +++ stable/10/sys/dev/ixl/if_ixl.c Fri Dec 11 12:47:49 2015 (r292097) @@ -47,7 +47,7 @@ /********************************************************************* * Driver version *********************************************************************/ -char ixl_driver_version[] = "1.3.6"; +char ixl_driver_version[] = "1.4.1"; /********************************************************************* * PCI Device ID Table @@ -69,6 +69,7 @@ static ixl_vendor_info_t ixl_vendor_info {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_B, 0, 0, 0}, {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_20G_KR2, 0, 0, 0}, /* required last entry */ {0, 0, 0, 0, 0} }; @@ -112,16 +113,17 @@ static void ixl_configure_legacy(struct static void ixl_free_pci_resources(struct ixl_pf *); static void ixl_local_timer(void *); static int ixl_setup_interface(device_t, struct ixl_vsi *); -static bool ixl_config_link(struct i40e_hw *); +static void ixl_link_event(struct ixl_pf *, struct i40e_arq_event_info *); static void ixl_config_rss(struct ixl_vsi *); static void ixl_set_queue_rx_itr(struct ixl_queue *); static void ixl_set_queue_tx_itr(struct ixl_queue *); static int ixl_set_advertised_speeds(struct ixl_pf *, int); -static void ixl_enable_rings(struct ixl_vsi *); -static void ixl_disable_rings(struct ixl_vsi *); -static void ixl_enable_intr(struct ixl_vsi *); -static void ixl_disable_intr(struct ixl_vsi *); +static int ixl_enable_rings(struct ixl_vsi *); +static int ixl_disable_rings(struct ixl_vsi *); +static void ixl_enable_intr(struct ixl_vsi *); +static void ixl_disable_intr(struct ixl_vsi *); +static void ixl_disable_rings_intr(struct ixl_vsi *); static void ixl_enable_adminq(struct i40e_hw *); static void ixl_disable_adminq(struct i40e_hw *); @@ -138,6 +140,7 @@ static void ixl_unregister_vlan(void *, static void ixl_setup_vlan_filters(struct ixl_vsi *); static void ixl_init_filters(struct ixl_vsi *); +static void ixl_reconfigure_filters(struct ixl_vsi *vsi); static void ixl_add_filter(struct ixl_vsi *, u8 *, s16 vlan); static void ixl_del_filter(struct ixl_vsi *, u8 *, s16 vlan); static void ixl_add_hw_filters(struct ixl_vsi *, int, int); @@ -145,6 +148,8 @@ static void ixl_del_hw_filters(struct ix static struct ixl_mac_filter * ixl_find_filter(struct ixl_vsi *, u8 *, s16); static void ixl_add_mc_filter(struct ixl_vsi *, u8 *); +static void ixl_free_mac_filters(struct ixl_vsi *vsi); + /* Sysctl debug interface */ static int ixl_debug_info(SYSCTL_HANDLER_ARGS); @@ -174,6 +179,7 @@ static void ixl_add_sysctls_eth_stats(st struct i40e_eth_stats *); static void ixl_update_stats_counters(struct ixl_pf *); static void ixl_update_eth_stats(struct ixl_vsi *); +static void ixl_update_vsi_stats(struct ixl_vsi *); static void ixl_pf_reset_stats(struct ixl_pf *); static void ixl_vsi_reset_stats(struct ixl_vsi *); static void ixl_stat_update48(struct i40e_hw *, u32, u32, bool, @@ -187,7 +193,21 @@ static int ixl_sysctl_phy_abilities(SYSC static int ixl_sysctl_sw_filter_list(SYSCTL_HANDLER_ARGS); static int ixl_sysctl_hw_res_alloc(SYSCTL_HANDLER_ARGS); static int ixl_sysctl_switch_config(SYSCTL_HANDLER_ARGS); -static int ixl_sysctl_dump_txd(SYSCTL_HANDLER_ARGS); +#endif + +#ifdef PCI_IOV +static int ixl_adminq_err_to_errno(enum i40e_admin_queue_err err); + +static int ixl_init_iov(device_t dev, uint16_t num_vfs, const nvlist_t*); +static void ixl_uninit_iov(device_t dev); +static int ixl_add_vf(device_t dev, uint16_t vfnum, const nvlist_t*); + +static void ixl_handle_vf_msg(struct ixl_pf *, + struct i40e_arq_event_info *); +static void ixl_handle_vflr(void *arg, int pending); + +static void ixl_reset_vf(struct ixl_pf *pf, struct ixl_vf *vf); +static void ixl_reinit_vf(struct ixl_pf *pf, struct ixl_vf *vf); #endif /********************************************************************* @@ -200,6 +220,11 @@ static device_method_t ixl_methods[] = { DEVMETHOD(device_attach, ixl_attach), DEVMETHOD(device_detach, ixl_detach), DEVMETHOD(device_shutdown, ixl_shutdown), +#ifdef PCI_IOV + DEVMETHOD(pci_init_iov, ixl_init_iov), + DEVMETHOD(pci_uninit_iov, ixl_uninit_iov), + DEVMETHOD(pci_add_vf, ixl_add_vf), +#endif {0, 0} }; @@ -212,10 +237,12 @@ DRIVER_MODULE(ixl, pci, ixl_driver, ixl_ MODULE_DEPEND(ixl, pci, 1, 1, 1); MODULE_DEPEND(ixl, ether, 1, 1, 1); + #ifdef DEV_NETMAP MODULE_DEPEND(ixl, netmap, 1, 1, 1); #endif /* DEV_NETMAP */ + /* ** Global reset mutex */ @@ -303,6 +330,10 @@ static char *ixl_fc_string[6] = { "Default" }; +static MALLOC_DEFINE(M_IXL, "ixl", "ixl driver allocations"); + +static uint8_t ixl_bcast_addr[ETHER_ADDR_LEN] = + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; /********************************************************************* * Device identification routine @@ -379,6 +410,10 @@ ixl_attach(device_t dev) struct ixl_vsi *vsi; u16 bus; int error = 0; +#ifdef PCI_IOV + nvlist_t *pf_schema, *vf_schema; + int iov_error; +#endif INIT_DEBUGOUT("ixl_attach: begin"); @@ -466,11 +501,6 @@ ixl_attach(device_t dev) SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "switch_config", CTLTYPE_STRING | CTLFLAG_RD, pf, 0, ixl_sysctl_switch_config, "A", "HW Switch Configuration"); - - SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "dump_desc", CTLTYPE_INT | CTLFLAG_WR, - pf, 0, ixl_sysctl_dump_txd, "I", "Desc dump"); #endif /* Save off the PCI information */ @@ -485,6 +515,8 @@ ixl_attach(device_t dev) hw->bus.device = pci_get_slot(dev); hw->bus.func = pci_get_function(dev); + pf->vc_debug_lvl = 1; + /* Do PCI setup - map BAR0, etc */ if (ixl_allocate_pci_resources(pf)) { device_printf(dev, "Allocation of PCI resources failed\n"); @@ -555,7 +587,8 @@ ixl_attach(device_t dev) } /* Set up host memory cache */ - error = i40e_init_lan_hmc(hw, vsi->num_queues, vsi->num_queues, 0, 0); + 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 failed: %d\n", error); goto err_get_cap; @@ -607,16 +640,8 @@ ixl_attach(device_t dev) } /* Determine link state */ - vsi->link_up = ixl_config_link(hw); - - /* Report if Unqualified modules are found */ - if ((vsi->link_up == FALSE) && - (pf->hw.phy.link_info.link_info & - I40E_AQ_MEDIA_AVAILABLE) && - (!(pf->hw.phy.link_info.an_info & - I40E_AQ_QUALIFIED_MODULE))) - device_printf(dev, "Link failed because " - "an unqualified module was detected\n"); + i40e_aq_get_link_info(hw, TRUE, NULL, NULL); + pf->link_up = i40e_get_link_status(hw); /* Setup OS specific network interface */ if (ixl_setup_interface(dev, vsi) != 0) { @@ -652,10 +677,31 @@ ixl_attach(device_t dev) vsi->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, ixl_unregister_vlan, vsi, EVENTHANDLER_PRI_FIRST); +#ifdef PCI_IOV + /* SR-IOV is only supported when MSI-X is in use. */ + if (pf->msix > 1) { + pf_schema = pci_iov_schema_alloc_node(); + vf_schema = pci_iov_schema_alloc_node(); + pci_iov_schema_add_unicast_mac(vf_schema, "mac-addr", 0, NULL); + pci_iov_schema_add_bool(vf_schema, "mac-anti-spoof", + IOV_SCHEMA_HASDEFAULT, TRUE); + pci_iov_schema_add_bool(vf_schema, "allow-set-mac", + IOV_SCHEMA_HASDEFAULT, FALSE); + pci_iov_schema_add_bool(vf_schema, "allow-promisc", + IOV_SCHEMA_HASDEFAULT, FALSE); + + iov_error = pci_iov_attach(dev, pf_schema, vf_schema); + if (iov_error != 0) + device_printf(dev, + "Failed to initialize SR-IOV (error=%d)\n", + iov_error); + } +#endif #ifdef DEV_NETMAP ixl_netmap_attach(vsi); #endif /* DEV_NETMAP */ + INIT_DEBUGOUT("ixl_attach: end"); return (0); @@ -691,6 +737,9 @@ ixl_detach(device_t dev) struct ixl_vsi *vsi = &pf->vsi; struct ixl_queue *que = vsi->queues; i40e_status status; +#ifdef PCI_IOV + int error; +#endif INIT_DEBUGOUT("ixl_detach: begin"); @@ -700,6 +749,14 @@ ixl_detach(device_t dev) return (EBUSY); } +#ifdef PCI_IOV + error = pci_iov_detach(dev); + if (error != 0) { + device_printf(dev, "SR-IOV in use; detach first.\n"); + return (error); + } +#endif + ether_ifdetach(vsi->ifp); if (vsi->ifp->if_drv_flags & IFF_DRV_RUNNING) { IXL_PF_LOCK(pf); @@ -737,8 +794,6 @@ ixl_detach(device_t dev) #ifdef DEV_NETMAP netmap_detach(vsi->ifp); #endif /* DEV_NETMAP */ - - ixl_free_pci_resources(pf); bus_generic_detach(dev); if_free(vsi->ifp); @@ -907,7 +962,7 @@ static int ixl_ioctl(struct ifnet * ifp, u_long command, caddr_t data) { struct ixl_vsi *vsi = ifp->if_softc; - struct ixl_pf *pf = (struct ixl_pf *)vsi->back; + struct ixl_pf *pf = vsi->back; struct ifreq *ifr = (struct ifreq *) data; #if defined(INET) || defined(INET6) struct ifaddr *ifa = (struct ifaddr *)data; @@ -1132,6 +1187,8 @@ ixl_init_locked(struct ixl_pf *pf) i40e_aq_set_default_vsi(hw, vsi->seid, NULL); + ixl_reconfigure_filters(vsi); + /* Set MTU in hardware*/ int aq_error = i40e_aq_set_mac_config(hw, vsi->max_frame_size, TRUE, 0, NULL); @@ -1226,6 +1283,11 @@ ixl_intr(void *arg) mask = rd32(hw, I40E_PFINT_ICR0_ENA); +#ifdef PCI_IOV + if (icr0 & I40E_PFINT_ICR0_VFLR_MASK) + taskqueue_enqueue(pf->tq, &pf->vflr_task); +#endif + if (icr0 & I40E_PFINT_ICR0_ADMINQ_MASK) { taskqueue_enqueue(pf->tq, &pf->adminq); return; @@ -1329,8 +1391,12 @@ ixl_msix_adminq(void *arg) mask &= ~I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK; } - if (reg & I40E_PFINT_ICR0_VFLR_MASK) +#ifdef PCI_IOV + if (reg & I40E_PFINT_ICR0_VFLR_MASK) { mask &= ~I40E_PFINT_ICR0_ENA_VFLR_MASK; + taskqueue_enqueue(pf->tq, &pf->vflr_task); + } +#endif reg = rd32(hw, I40E_PFINT_DYN_CTL0); reg = reg | I40E_PFINT_DYN_CTL0_CLEARPBA_MASK; @@ -1352,18 +1418,20 @@ static void ixl_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) { struct ixl_vsi *vsi = ifp->if_softc; - struct ixl_pf *pf = (struct ixl_pf *)vsi->back; + struct ixl_pf *pf = vsi->back; struct i40e_hw *hw = &pf->hw; INIT_DEBUGOUT("ixl_media_status: begin"); IXL_PF_LOCK(pf); + hw->phy.get_link_info = TRUE; + pf->link_up = i40e_get_link_status(hw); ixl_update_link_status(pf); ifmr->ifm_status = IFM_AVALID; ifmr->ifm_active = IFM_ETHER; - if (!vsi->link_up) { + if (!pf->link_up) { IXL_PF_UNLOCK(pf); return; } @@ -1753,15 +1821,14 @@ ixl_update_link_status(struct ixl_pf *pf struct ifnet *ifp = vsi->ifp; device_t dev = pf->dev; - - if (vsi->link_up){ + if (pf->link_up){ if (vsi->link_active == FALSE) { - i40e_aq_get_link_info(hw, TRUE, NULL, NULL); pf->fc = hw->fc.current_mode; if (bootverbose) { device_printf(dev,"Link is up %d Gbps %s," " Flow Control: %s\n", - ((vsi->link_speed == I40E_LINK_SPEED_40GB)? 40:10), + ((pf->link_speed == + I40E_LINK_SPEED_40GB)? 40:10), "Full Duplex", ixl_fc_string[pf->fc]); } vsi->link_active = TRUE; @@ -1770,10 +1837,12 @@ ixl_update_link_status(struct ixl_pf *pf ** 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"); + (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 */ @@ -1804,7 +1873,10 @@ ixl_stop(struct ixl_pf *pf) mtx_assert(&pf->pf_mtx, MA_OWNED); INIT_DEBUGOUT("ixl_stop: begin\n"); - ixl_disable_intr(vsi); + if (pf->num_vfs == 0) + ixl_disable_intr(vsi); + else + ixl_disable_rings_intr(vsi); ixl_disable_rings(vsi); /* Tell the stack that the interface is no longer active */ @@ -1857,6 +1929,11 @@ ixl_assign_vsi_legacy(struct ixl_pf *pf) taskqueue_start_threads(&que->tq, 1, PI_NET, "%s que", device_get_nameunit(dev)); TASK_INIT(&pf->adminq, 0, ixl_do_adminq, pf); + +#ifdef PCI_IOV + TASK_INIT(&pf->vflr_task, 0, ixl_handle_vflr, pf); +#endif + pf->tq = taskqueue_create_fast("ixl_adm", M_NOWAIT, taskqueue_thread_enqueue, &pf->tq); taskqueue_start_threads(&pf->tq, 1, PI_NET, "%s adminq", @@ -1902,6 +1979,11 @@ ixl_assign_vsi_msix(struct ixl_pf *pf) pf->admvec = vector; /* Tasklet for Admin Queue */ TASK_INIT(&pf->adminq, 0, ixl_do_adminq, pf); + +#ifdef PCI_IOV + TASK_INIT(&pf->vflr_task, 0, ixl_handle_vflr, pf); +#endif + pf->tq = taskqueue_create_fast("ixl_adm", M_NOWAIT, taskqueue_thread_enqueue, &pf->tq); taskqueue_start_threads(&pf->tq, 1, PI_NET, "%s adminq", @@ -2325,6 +2407,10 @@ ixl_add_ifmedia(struct ixl_vsi *vsi, u32 if (phy_type & (1 << I40E_PHY_TYPE_1000BASE_T)) ifmedia_add(&vsi->media, IFM_ETHER | IFM_1000_T, 0, NULL); + if (phy_type & (1 << I40E_PHY_TYPE_1000BASE_SX)) + ifmedia_add(&vsi->media, IFM_ETHER | IFM_1000_SX, 0, NULL); + if (phy_type & (1 << I40E_PHY_TYPE_1000BASE_LX)) + ifmedia_add(&vsi->media, IFM_ETHER | IFM_1000_LX, 0, NULL); if (phy_type & (1 << I40E_PHY_TYPE_10GBASE_CR1_CU) || phy_type & (1 << I40E_PHY_TYPE_10GBASE_KX4) || @@ -2465,17 +2551,32 @@ ixl_setup_interface(device_t dev, struct return (0); } -static bool -ixl_config_link(struct i40e_hw *hw) +/* +** Run when the Admin Queue gets a +** link transition interrupt. +*/ +static void +ixl_link_event(struct ixl_pf *pf, struct i40e_arq_event_info *e) { + struct i40e_hw *hw = &pf->hw; + struct i40e_aqc_get_link_status *status = + (struct i40e_aqc_get_link_status *)&e->desc.params.raw; bool check; - i40e_aq_get_link_info(hw, TRUE, NULL, NULL); + hw->phy.get_link_info = TRUE; check = i40e_get_link_status(hw); + pf->link_up = check; #ifdef IXL_DEBUG printf("Link is %s\n", check ? "up":"down"); #endif - return (check); + /* Report if Unqualified modules are found */ + if ((status->link_info & I40E_AQ_MEDIA_AVAILABLE) && + (!(status->an_info & I40E_AQ_QUALIFIED_MODULE)) && + (!(status->link_info & I40E_AQ_LINK_UP))) + device_printf(pf->dev, "Link failed because " + "an unqualified module was detected\n"); + + return; } /********************************************************************* @@ -2493,7 +2594,7 @@ ixl_switch_config(struct ixl_pf *pf) device_t dev = vsi->dev; struct i40e_aqc_get_switch_config_resp *sw_config; u8 aq_buf[I40E_AQ_LARGE_BUF]; - int ret = I40E_SUCCESS; + int ret; u16 next = 0; memset(&aq_buf, 0, sizeof(aq_buf)); @@ -2501,19 +2602,26 @@ ixl_switch_config(struct ixl_pf *pf) ret = i40e_aq_get_switch_config(hw, sw_config, sizeof(aq_buf), &next, NULL); if (ret) { - device_printf(dev,"aq_get_switch_config failed!!\n"); + device_printf(dev,"aq_get_switch_config failed (ret=%d)!!\n", + ret); return (ret); } #ifdef IXL_DEBUG - printf("Switch config: header reported: %d in structure, %d total\n", + device_printf(dev, + "Switch config: header reported: %d in structure, %d total\n", sw_config->header.num_reported, sw_config->header.num_total); - printf("type=%d seid=%d uplink=%d downlink=%d\n", - sw_config->element[0].element_type, - sw_config->element[0].seid, - sw_config->element[0].uplink_seid, - sw_config->element[0].downlink_seid); + for (int i = 0; i < sw_config->header.num_reported; i++) { + device_printf(dev, + "%d: type=%d seid=%d uplink=%d downlink=%d\n", i, + sw_config->element[i].element_type, + sw_config->element[i].seid, + sw_config->element[i].uplink_seid, + sw_config->element[i].downlink_seid); + } #endif /* Simplified due to a single VSI at the moment */ + vsi->uplink_seid = sw_config->element[0].uplink_seid; + vsi->downlink_seid = sw_config->element[0].downlink_seid; vsi->seid = sw_config->element[0].seid; return (ret); } @@ -2528,6 +2636,7 @@ ixl_switch_config(struct ixl_pf *pf) static int ixl_initialize_vsi(struct ixl_vsi *vsi) { + struct ixl_pf *pf = vsi->back; struct ixl_queue *que = vsi->queues; device_t dev = vsi->dev; struct i40e_hw *hw = vsi->hw; @@ -2536,6 +2645,8 @@ ixl_initialize_vsi(struct ixl_vsi *vsi) memset(&ctxt, 0, sizeof(ctxt)); ctxt.seid = vsi->seid; + if (pf->veb_seid != 0) + ctxt.uplink_seid = pf->veb_seid; ctxt.pf_num = hw->pf_id; err = i40e_aq_get_vsi_params(hw, &ctxt, NULL); if (err) { @@ -2577,6 +2688,8 @@ ixl_initialize_vsi(struct ixl_vsi *vsi) vsi->hw_filters_add = 0; vsi->hw_filters_del = 0; + ctxt.flags = htole16(I40E_AQ_VSI_TYPE_PF); + err = i40e_aq_update_vsi_params(hw, &ctxt, NULL); if (err) { device_printf(dev,"update vsi params failed %x!!\n", @@ -2597,7 +2710,7 @@ ixl_initialize_vsi(struct ixl_vsi *vsi) size = que->num_desc * sizeof(struct i40e_tx_desc); memset(&tctx, 0, sizeof(struct i40e_hmc_obj_txq)); tctx.new_context = 1; - tctx.base = (txr->dma.pa/128); + tctx.base = (txr->dma.pa/IXL_TX_CTX_BASE_UNITS); tctx.qlen = que->num_desc; tctx.fc_ena = 0; tctx.rdylist = vsi->info.qs_handle[0]; /* index is TC */ @@ -2627,7 +2740,7 @@ ixl_initialize_vsi(struct ixl_vsi *vsi) ixl_init_tx_ring(que); /* Next setup the HMC RX Context */ - if (vsi->max_frame_size <= 2048) + if (vsi->max_frame_size <= MCLBYTES) rxr->mbuf_sz = MCLBYTES; else rxr->mbuf_sz = MJUMPAGESIZE; @@ -2644,7 +2757,7 @@ ixl_initialize_vsi(struct ixl_vsi *vsi) rctx.dtype = 0; rctx.dsize = 1; /* do 32byte descriptors */ rctx.hsplit_0 = 0; /* no HDR split initially */ - rctx.base = (rxr->dma.pa/128); + rctx.base = (rxr->dma.pa/IXL_RX_CTX_BASE_UNITS); rctx.qlen = que->num_desc; rctx.tphrdesc_ena = 1; rctx.tphwdesc_ena = 1; @@ -2699,7 +2812,6 @@ ixl_free_vsi(struct ixl_vsi *vsi) { struct ixl_pf *pf = (struct ixl_pf *)vsi->back; struct ixl_queue *que = vsi->queues; - struct ixl_mac_filter *f; /* Free station queues */ for (int i = 0; i < vsi->num_queues; i++, que++) { @@ -2728,6 +2840,14 @@ ixl_free_vsi(struct ixl_vsi *vsi) free(vsi->queues, M_DEVBUF); /* Free VSI filter list */ + ixl_free_mac_filters(vsi); +} + +static void +ixl_free_mac_filters(struct ixl_vsi *vsi) +{ + struct ixl_mac_filter *f; + while (!SLIST_EMPTY(&vsi->ftl)) { f = SLIST_FIRST(&vsi->ftl); SLIST_REMOVE_HEAD(&vsi->ftl, next); @@ -2759,6 +2879,7 @@ ixl_setup_stations(struct ixl_pf *pf) vsi->hw = &pf->hw; vsi->id = 0; vsi->num_vlans = 0; + vsi->back = pf; /* Get memory for the station queues */ if (!(vsi->queues = @@ -3011,6 +3132,24 @@ ixl_set_queue_tx_itr(struct ixl_queue *q return; } +#define QUEUE_NAME_LEN 32 + +static void +ixl_add_vsi_sysctls(struct ixl_pf *pf, struct ixl_vsi *vsi, + struct sysctl_ctx_list *ctx, const char *sysctl_name) +{ + struct sysctl_oid *tree; + struct sysctl_oid_list *child; + struct sysctl_oid_list *vsi_list; + + tree = device_get_sysctl_tree(pf->dev); + child = SYSCTL_CHILDREN(tree); + vsi->vsi_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, sysctl_name, + CTLFLAG_RD, NULL, "VSI Number"); + vsi_list = SYSCTL_CHILDREN(vsi->vsi_node); + + ixl_add_sysctls_eth_stats(ctx, vsi_list, &vsi->eth_stats); +} static void ixl_add_hw_stats(struct ixl_pf *pf) @@ -3018,18 +3157,19 @@ ixl_add_hw_stats(struct ixl_pf *pf) device_t dev = pf->dev; struct ixl_vsi *vsi = &pf->vsi; struct ixl_queue *queues = vsi->queues; - struct i40e_eth_stats *vsi_stats = &vsi->eth_stats; struct i40e_hw_port_stats *pf_stats = &pf->stats; struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev); struct sysctl_oid *tree = device_get_sysctl_tree(dev); struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree); + struct sysctl_oid_list *vsi_list; - struct sysctl_oid *vsi_node, *queue_node; - struct sysctl_oid_list *vsi_list, *queue_list; + struct sysctl_oid *queue_node; + struct sysctl_oid_list *queue_list; struct tx_ring *txr; struct rx_ring *rxr; + char queue_namebuf[QUEUE_NAME_LEN]; /* Driver statistics */ SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "watchdog_events", @@ -3039,23 +3179,18 @@ ixl_add_hw_stats(struct ixl_pf *pf) CTLFLAG_RD, &pf->admin_irq, "Admin Queue IRQ Handled"); - /* VSI statistics */ -#define QUEUE_NAME_LEN 32 - char queue_namebuf[QUEUE_NAME_LEN]; - - // ERJ: Only one vsi now, re-do when >1 VSI enabled - // snprintf(vsi_namebuf, QUEUE_NAME_LEN, "vsi%d", vsi->info.stat_counter_idx); - vsi_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "vsi", - CTLFLAG_RD, NULL, "VSI-specific stats"); - vsi_list = SYSCTL_CHILDREN(vsi_node); + SYSCTL_ADD_INT(ctx, child, OID_AUTO, "vc_debug_level", + CTLFLAG_RW, &pf->vc_debug_lvl, 0, + "PF/VF Virtual Channel debug logging level"); - ixl_add_sysctls_eth_stats(ctx, vsi_list, vsi_stats); + ixl_add_vsi_sysctls(pf, &pf->vsi, ctx, "pf"); + vsi_list = SYSCTL_CHILDREN(pf->vsi.vsi_node); /* Queue statistics */ for (int q = 0; q < vsi->num_queues; q++) { snprintf(queue_namebuf, QUEUE_NAME_LEN, "que%d", q); - queue_node = SYSCTL_ADD_NODE(ctx, vsi_list, OID_AUTO, queue_namebuf, - CTLFLAG_RD, NULL, "Queue #"); + queue_node = SYSCTL_ADD_NODE(ctx, vsi_list, + OID_AUTO, queue_namebuf, CTLFLAG_RD, NULL, "Queue #"); queue_list = SYSCTL_CHILDREN(queue_node); txr = &(queues[q].txr); @@ -3378,8 +3513,7 @@ static void ixl_init_filters(struct ixl_vsi *vsi) { /* Add broadcast address */ - u8 bc[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - ixl_add_filter(vsi, bc, IXL_VLAN_ANY); + ixl_add_filter(vsi, ixl_bcast_addr, IXL_VLAN_ANY); } /* @@ -3408,6 +3542,13 @@ ixl_add_mc_filter(struct ixl_vsi *vsi, u return; } +static void +ixl_reconfigure_filters(struct ixl_vsi *vsi) +{ + + ixl_add_hw_filters(vsi, IXL_FILTER_USED, vsi->num_macs); +} + /* ** This routine adds macvlan filters *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201512111247.tBBClnLI053338>