diff options
author | jfv <jfv@FreeBSD.org> | 2015-02-20 00:40:26 +0000 |
---|---|---|
committer | jfv <jfv@FreeBSD.org> | 2015-02-20 00:40:26 +0000 |
commit | c0ae6c2127580cca43ae3425615b6e3dd2459984 (patch) | |
tree | 0d2eabe4532288f43bc9fb3736f1d71a23810de1 /sys/dev/ixl | |
parent | 33cb11f04e6741b237ba24db15cc287a86d22fc8 (diff) | |
download | FreeBSD-src-c0ae6c2127580cca43ae3425615b6e3dd2459984.zip FreeBSD-src-c0ae6c2127580cca43ae3425615b6e3dd2459984.tar.gz |
Bring the XL710 drivers up to the SW3 release level.
MFC after: 1 week
Diffstat (limited to 'sys/dev/ixl')
-rwxr-xr-x | sys/dev/ixl/i40e_adminq.c | 5 | ||||
-rwxr-xr-x | sys/dev/ixl/i40e_adminq_cmd.h | 26 | ||||
-rwxr-xr-x | sys/dev/ixl/i40e_common.c | 98 | ||||
-rwxr-xr-x | sys/dev/ixl/i40e_lan_hmc.c | 25 | ||||
-rwxr-xr-x | sys/dev/ixl/i40e_prototype.h | 7 | ||||
-rwxr-xr-x | sys/dev/ixl/i40e_type.h | 25 | ||||
-rwxr-xr-x | sys/dev/ixl/if_ixl.c | 271 | ||||
-rw-r--r-- | sys/dev/ixl/if_ixlv.c | 84 | ||||
-rw-r--r-- | sys/dev/ixl/ixl.h | 7 | ||||
-rw-r--r-- | sys/dev/ixl/ixl_pf.h | 3 | ||||
-rwxr-xr-x | sys/dev/ixl/ixl_txrx.c | 9 | ||||
-rw-r--r-- | sys/dev/ixl/ixlvc.c | 9 |
12 files changed, 335 insertions, 234 deletions
diff --git a/sys/dev/ixl/i40e_adminq.c b/sys/dev/ixl/i40e_adminq.c index 2dc0807..d769c45 100755 --- a/sys/dev/ixl/i40e_adminq.c +++ b/sys/dev/ixl/i40e_adminq.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2013-2014, Intel Corporation + Copyright (c) 2013-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -614,7 +614,8 @@ enum i40e_status_code i40e_init_adminq(struct i40e_hw *hw) goto init_adminq_free_arq; /* get the NVM version info */ - i40e_read_nvm_word(hw, I40E_SR_NVM_IMAGE_VERSION, &hw->nvm.version); + i40e_read_nvm_word(hw, I40E_SR_NVM_DEV_STARTER_VERSION, + &hw->nvm.version); i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_LO, &eetrack_lo); i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_HI, &eetrack_hi); hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo; diff --git a/sys/dev/ixl/i40e_adminq_cmd.h b/sys/dev/ixl/i40e_adminq_cmd.h index 02a3ea2..57b3ee1 100755 --- a/sys/dev/ixl/i40e_adminq_cmd.h +++ b/sys/dev/ixl/i40e_adminq_cmd.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2013-2014, Intel Corporation + Copyright (c) 2013-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -42,7 +42,7 @@ */ #define I40E_FW_API_VERSION_MAJOR 0x0001 -#define I40E_FW_API_VERSION_MINOR 0x0002 +#define I40E_FW_API_VERSION_MINOR 0x0004 struct i40e_aq_desc { __le16 flags; @@ -140,12 +140,7 @@ 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, @@ -270,7 +265,6 @@ 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, @@ -282,8 +276,6 @@ 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, @@ -517,7 +509,8 @@ 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_ADDR_VALID_MASK 0xf0 +#define I40E_AQC_MC_MAG_EN_VALID 0x100 +#define I40E_AQC_ADDR_VALID_MASK 0x1F0 u8 reserved[6]; __le32 addr_high; __le32 addr_low; @@ -540,7 +533,9 @@ 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_MASK 0xc000 +#define I40E_AQC_WRITE_TYPE_UPDATE_MC_MAG 0xC000 +#define I40E_AQC_WRITE_TYPE_MASK 0xC000 + __le16 mac_sah; __le32 mac_sal; u8 reserved[8]; @@ -1076,6 +1071,7 @@ struct i40e_aqc_set_vsi_promiscuous_modes { __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]; }; @@ -2070,6 +2066,12 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_start); #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; diff --git a/sys/dev/ixl/i40e_common.c b/sys/dev/ixl/i40e_common.c index dfb60aa..f0f128e 100755 --- a/sys/dev/ixl/i40e_common.c +++ b/sys/dev/ixl/i40e_common.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2013-2014, Intel Corporation + Copyright (c) 2013-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -37,6 +37,7 @@ #include "i40e_prototype.h" #include "i40e_virtchnl.h" + /** * i40e_set_mac_type - Sets MAC type * @hw: pointer to the HW structure @@ -61,6 +62,7 @@ enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw) case I40E_DEV_ID_QSFP_B: case I40E_DEV_ID_QSFP_C: case I40E_DEV_ID_10G_BASE_T: + case I40E_DEV_ID_20G_KR2: hw->mac.type = I40E_MAC_XL710; break; case I40E_DEV_ID_VF: @@ -840,12 +842,15 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw) case I40E_PHY_TYPE_10GBASE_CR1: case I40E_PHY_TYPE_40GBASE_CR4: case I40E_PHY_TYPE_10GBASE_SFPP_CU: + case I40E_PHY_TYPE_40GBASE_AOC: + case I40E_PHY_TYPE_10GBASE_AOC: media = I40E_MEDIA_TYPE_DA; break; case I40E_PHY_TYPE_1000BASE_KX: case I40E_PHY_TYPE_10GBASE_KX4: case I40E_PHY_TYPE_10GBASE_KR: case I40E_PHY_TYPE_40GBASE_KR4: + case I40E_PHY_TYPE_20GBASE_KR2: media = I40E_MEDIA_TYPE_BACKPLANE; break; case I40E_PHY_TYPE_SGMII: @@ -1508,6 +1513,10 @@ enum i40e_status_code i40e_aq_get_link_info(struct i40e_hw *hw, else hw_link_info->lse_enable = FALSE; + if ((hw->aq.fw_maj_ver < 4 || (hw->aq.fw_maj_ver == 4 && + hw->aq.fw_min_ver < 40)) && hw_link_info->phy_type == 0xE) + hw_link_info->phy_type = I40E_PHY_TYPE_10GBASE_SFPP_CU; + /* save link status information */ if (link) i40e_memcpy(link, hw_link_info, sizeof(*hw_link_info), @@ -2807,12 +2816,13 @@ 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_MFP_MODE_1 0xF1 +#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 @@ -2830,6 +2840,7 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff, 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; @@ -2848,6 +2859,7 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff, 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: @@ -2922,9 +2934,21 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff, case I40E_DEV_FUNC_CAP_MSIX_VF: p->num_msix_vectors_vf = number; break; - case I40E_DEV_FUNC_CAP_MFP_MODE_1: - if (number == 1) - p->mfp_mode_1 = TRUE; + 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; break; case I40E_DEV_FUNC_CAP_CEM: if (number == 1) @@ -2957,11 +2981,18 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff, 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; @@ -4917,6 +4948,63 @@ void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status) } /** + * 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 diff --git a/sys/dev/ixl/i40e_lan_hmc.c b/sys/dev/ixl/i40e_lan_hmc.c index 078adef..0866ad1 100755 --- a/sys/dev/ixl/i40e_lan_hmc.c +++ b/sys/dev/ixl/i40e_lan_hmc.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2013-2014, Intel Corporation + Copyright (c) 2013-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -1218,7 +1218,7 @@ static enum i40e_status_code i40e_set_hmc_context(u8 *context_bytes, /** * i40e_hmc_get_object_va - retrieves an object's virtual address - * @hmc_info: pointer to i40e_hmc_info struct + * @hw: pointer to the hw structure * @object_base: pointer to u64 to get the va * @rsrc_type: the hmc resource type * @obj_idx: hmc object index @@ -1227,12 +1227,13 @@ static enum i40e_status_code i40e_set_hmc_context(u8 *context_bytes, * base pointer. This function is used for LAN Queue contexts. **/ static -enum i40e_status_code i40e_hmc_get_object_va(struct i40e_hmc_info *hmc_info, +enum i40e_status_code i40e_hmc_get_object_va(struct i40e_hw *hw, u8 **object_base, enum i40e_hmc_lan_rsrc_type rsrc_type, u32 obj_idx) { u32 obj_offset_in_sd, obj_offset_in_pd; + struct i40e_hmc_info *hmc_info = &hw->hmc; struct i40e_hmc_sd_entry *sd_entry; struct i40e_hmc_pd_entry *pd_entry; u32 pd_idx, pd_lmt, rel_pd_idx; @@ -1304,8 +1305,7 @@ enum i40e_status_code i40e_get_lan_tx_queue_context(struct i40e_hw *hw, enum i40e_status_code err; u8 *context_bytes; - err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, - I40E_HMC_LAN_TX, queue); + err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_TX, queue); if (err < 0) return err; @@ -1324,8 +1324,7 @@ enum i40e_status_code i40e_clear_lan_tx_queue_context(struct i40e_hw *hw, enum i40e_status_code err; u8 *context_bytes; - err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, - I40E_HMC_LAN_TX, queue); + err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_TX, queue); if (err < 0) return err; @@ -1345,8 +1344,7 @@ enum i40e_status_code i40e_set_lan_tx_queue_context(struct i40e_hw *hw, enum i40e_status_code err; u8 *context_bytes; - err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, - I40E_HMC_LAN_TX, queue); + err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_TX, queue); if (err < 0) return err; @@ -1367,8 +1365,7 @@ enum i40e_status_code i40e_get_lan_rx_queue_context(struct i40e_hw *hw, enum i40e_status_code err; u8 *context_bytes; - err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, - I40E_HMC_LAN_RX, queue); + err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_RX, queue); if (err < 0) return err; @@ -1387,8 +1384,7 @@ enum i40e_status_code i40e_clear_lan_rx_queue_context(struct i40e_hw *hw, enum i40e_status_code err; u8 *context_bytes; - err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, - I40E_HMC_LAN_RX, queue); + err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_RX, queue); if (err < 0) return err; @@ -1408,8 +1404,7 @@ enum i40e_status_code i40e_set_lan_rx_queue_context(struct i40e_hw *hw, enum i40e_status_code err; u8 *context_bytes; - err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, - I40E_HMC_LAN_RX, queue); + err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_RX, queue); if (err < 0) return err; diff --git a/sys/dev/ixl/i40e_prototype.h b/sys/dev/ixl/i40e_prototype.h index 2b72383..fc4907e 100755 --- a/sys/dev/ixl/i40e_prototype.h +++ b/sys/dev/ixl/i40e_prototype.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2013-2014, Intel Corporation + Copyright (c) 2013-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -445,4 +445,9 @@ enum i40e_status_code i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw, 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_ */ diff --git a/sys/dev/ixl/i40e_type.h b/sys/dev/ixl/i40e_type.h index 703fae1..7fe50e2 100755 --- a/sys/dev/ixl/i40e_type.h +++ b/sys/dev/ixl/i40e_type.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2013-2014, Intel Corporation + Copyright (c) 2013-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -57,6 +57,7 @@ #define I40E_DEV_ID_QSFP_B 0x1584 #define I40E_DEV_ID_QSFP_C 0x1585 #define I40E_DEV_ID_10G_BASE_T 0x1586 +#define I40E_DEV_ID_20G_KR2 0x1587 #define I40E_DEV_ID_VF 0x154C #define I40E_DEV_ID_VF_HV 0x1571 @@ -286,7 +287,17 @@ struct i40e_hw_capabilities { bool dcb; bool fcoe; bool iscsi; /* Indicates iSCSI enabled */ - bool mfp_mode_1; + 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 mgmt_cem; bool ieee_1588; bool iwarp; @@ -315,6 +326,7 @@ struct i40e_hw_capabilities { u8 rx_buf_chain_len; u32 enabled_tcmap; u32 maxtc; + u64 wr_csr_prot; }; struct i40e_mac_info { @@ -560,7 +572,11 @@ struct i40e_hw { /* debug mask */ u32 debug_mask; }; -#define i40e_is_vf(_hw) ((_hw)->mac.type == I40E_MAC_VF) + +static INLINE bool i40e_is_vf(struct i40e_hw *hw) +{ + return hw->mac.type == I40E_MAC_VF; +} struct i40e_driver_version { u8 major_version; @@ -1258,6 +1274,9 @@ 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; diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c index da3b38b..e631030 100755 --- a/sys/dev/ixl/if_ixl.c +++ b/sys/dev/ixl/if_ixl.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2013-2014, Intel Corporation + Copyright (c) 2013-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -32,9 +32,12 @@ ******************************************************************************/ /*$FreeBSD$*/ +#ifndef IXL_STANDALONE_BUILD #include "opt_inet.h" #include "opt_inet6.h" #include "opt_rss.h" +#endif + #include "ixl.h" #include "ixl_pf.h" @@ -45,7 +48,7 @@ /********************************************************************* * Driver version *********************************************************************/ -char ixl_driver_version[] = "1.3.1"; +char ixl_driver_version[] = "1.3.6"; /********************************************************************* * PCI Device ID Table @@ -99,7 +102,7 @@ static void ixl_update_link_status(struct ixl_pf *); static int ixl_allocate_pci_resources(struct ixl_pf *); static u16 ixl_get_bus_info(struct i40e_hw *, device_t); static int ixl_setup_stations(struct ixl_pf *); -static int ixl_setup_vsi(struct ixl_vsi *); +static int ixl_switch_config(struct ixl_pf *); static int ixl_initialize_vsi(struct ixl_vsi *); static int ixl_assign_vsi_msix(struct ixl_pf *); static int ixl_assign_vsi_legacy(struct ixl_pf *); @@ -499,48 +502,6 @@ ixl_attach(device_t dev) goto err_out; } - /* For now always do an initial CORE reset on first device */ - { - static int ixl_dev_count; - static int ixl_dev_track[32]; - u32 my_dev; - int i, found = FALSE; - u16 bus = pci_get_bus(dev); - - mtx_lock(&ixl_reset_mtx); - my_dev = (bus << 8) | hw->bus.device; - - for (i = 0; i < ixl_dev_count; i++) { - if (ixl_dev_track[i] == my_dev) - found = TRUE; - } - - if (!found) { - u32 reg; - - ixl_dev_track[ixl_dev_count] = my_dev; - ixl_dev_count++; - - INIT_DEBUGOUT("Initial CORE RESET\n"); - wr32(hw, I40E_GLGEN_RTRIG, I40E_GLGEN_RTRIG_CORER_MASK); - ixl_flush(hw); - i = 50; - do { - i40e_msec_delay(50); - reg = rd32(hw, I40E_GLGEN_RSTAT); - if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK)) - break; - } while (i--); - - /* paranoia */ - wr32(hw, I40E_PF_ATQLEN, 0); - wr32(hw, I40E_PF_ATQBAL, 0); - wr32(hw, I40E_PF_ATQBAH, 0); - i40e_clear_pxe_mode(hw); - } - mtx_unlock(&ixl_reset_mtx); - } - /* Set admin queue parameters */ hw->aq.num_arq_entries = IXL_AQ_LEN; hw->aq.num_asq_entries = IXL_AQ_LEN; @@ -630,13 +591,15 @@ ixl_attach(device_t dev) if (error) goto err_late; - i40e_msec_delay(75); - error = i40e_aq_set_link_restart_an(hw, TRUE, NULL); - if (error) { - device_printf(dev, "link restart failed, aq_err=%d\n", - pf->hw.aq.asq_last_status); + 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, "link restart failed, aq_err=%d\n", + pf->hw.aq.asq_last_status); } - + /* Determine link state */ vsi->link_up = ixl_config_link(hw); @@ -656,6 +619,18 @@ ixl_attach(device_t dev) goto err_late; } + error = ixl_switch_config(pf); + if (error) { + device_printf(dev, "Initial switch config failed: %d\n", error); + goto err_mac_hmc; + } + + /* Limit phy interrupts to link and modules failure */ + error = i40e_aq_set_phy_int_mask(hw, + I40E_AQ_EVENT_LINK_UPDOWN | I40E_AQ_EVENT_MODULE_QUAL_FAIL, NULL); + if (error) + device_printf(dev, "set phy mask failed: %d\n", error); + /* Get the bus configuration and set the shared code */ bus = ixl_get_bus_info(hw, dev); i40e_set_pci_config_data(hw, bus); @@ -665,13 +640,6 @@ ixl_attach(device_t dev) ixl_update_stats_counters(pf); ixl_add_hw_stats(pf); - /* Reset port's advertised speeds */ - if (!i40e_is_40G_device(hw->device_id)) { - 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 */ vsi->vlan_attach = EVENTHANDLER_REGISTER(vlan_config, ixl_register_vlan, vsi, EVENTHANDLER_PRI_FIRST); @@ -723,9 +691,12 @@ ixl_detach(device_t dev) return (EBUSY); } - IXL_PF_LOCK(pf); - ixl_stop(pf); - IXL_PF_UNLOCK(pf); + ether_ifdetach(vsi->ifp); + if (vsi->ifp->if_drv_flags & IFF_DRV_RUNNING) { + IXL_PF_LOCK(pf); + ixl_stop(pf); + IXL_PF_UNLOCK(pf); + } for (int i = 0; i < vsi->num_queues; i++, que++) { if (que->tq) { @@ -753,7 +724,6 @@ ixl_detach(device_t dev) if (vsi->vlan_detach != NULL) EVENTHANDLER_DEREGISTER(vlan_unconfig, vsi->vlan_detach); - ether_ifdetach(vsi->ifp); callout_drain(&pf->timer); @@ -1122,11 +1092,8 @@ ixl_init_locked(struct ixl_pf *pf) /* Set up RSS */ ixl_config_rss(vsi); - /* Setup the VSI */ - ixl_setup_vsi(vsi); - /* - ** Prepare the rings, hmc contexts, etc... + ** Prepare the VSI: rings, hmc contexts, etc... */ if (ixl_initialize_vsi(vsi)) { device_printf(dev, "initialize vsi failed!!\n"); @@ -1409,16 +1376,14 @@ ixl_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) ifmr->ifm_active |= IFM_1000_LX; break; /* 10 G */ + case I40E_PHY_TYPE_10GBASE_CR1: case I40E_PHY_TYPE_10GBASE_CR1_CU: case I40E_PHY_TYPE_10GBASE_SFPP_CU: + /* Using this until a real KR media type */ + case I40E_PHY_TYPE_10GBASE_KR: + case I40E_PHY_TYPE_10GBASE_KX4: 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; @@ -1439,6 +1404,16 @@ ixl_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) case I40E_PHY_TYPE_40GBASE_LR4: ifmr->ifm_active |= IFM_40G_LR4; break; + /* + ** Set these to CR4 because OS does not + ** have types available yet. + */ + case I40E_PHY_TYPE_40GBASE_KR4: + case I40E_PHY_TYPE_XLAUI: + case I40E_PHY_TYPE_XLPPI: + case I40E_PHY_TYPE_40GBASE_AOC: + ifmr->ifm_active |= IFM_40G_CR4; + break; default: ifmr->ifm_active |= IFM_UNKNOWN; break; @@ -1765,18 +1740,17 @@ ixl_update_link_status(struct ixl_pf *pf) struct i40e_hw *hw = &pf->hw; struct ifnet *ifp = vsi->ifp; device_t dev = pf->dev; - enum i40e_fc_mode fc; if (vsi->link_up){ if (vsi->link_active == FALSE) { i40e_aq_get_link_info(hw, TRUE, NULL, NULL); + pf->fc = hw->fc.current_mode; if (bootverbose) { - fc = hw->fc.current_mode; device_printf(dev,"Link is up %d Gbps %s," " Flow Control: %s\n", ((vsi->link_speed == I40E_LINK_SPEED_40GB)? 40:10), - "Full Duplex", ixl_fc_string[fc]); + "Full Duplex", ixl_fc_string[pf->fc]); } vsi->link_active = TRUE; /* @@ -2341,8 +2315,15 @@ ixl_add_ifmedia(struct ixl_vsi *vsi, u32 phy_type) ifmedia_add(&vsi->media, IFM_ETHER | IFM_1000_T, 0, NULL); if (phy_type & (1 << I40E_PHY_TYPE_10GBASE_CR1_CU) || + phy_type & (1 << I40E_PHY_TYPE_10GBASE_KX4) || + phy_type & (1 << I40E_PHY_TYPE_10GBASE_KR) || + phy_type & (1 << I40E_PHY_TYPE_10GBASE_AOC) || + phy_type & (1 << I40E_PHY_TYPE_XAUI) || + phy_type & (1 << I40E_PHY_TYPE_XFI) || + phy_type & (1 << I40E_PHY_TYPE_SFI) || phy_type & (1 << I40E_PHY_TYPE_10GBASE_SFPP_CU)) ifmedia_add(&vsi->media, IFM_ETHER | IFM_10G_TWINAX, 0, NULL); + if (phy_type & (1 << I40E_PHY_TYPE_10GBASE_SR)) ifmedia_add(&vsi->media, IFM_ETHER | IFM_10G_SR, 0, NULL); if (phy_type & (1 << I40E_PHY_TYPE_10GBASE_LR)) @@ -2350,9 +2331,15 @@ ixl_add_ifmedia(struct ixl_vsi *vsi, u32 phy_type) if (phy_type & (1 << I40E_PHY_TYPE_10GBASE_T)) ifmedia_add(&vsi->media, IFM_ETHER | IFM_10G_T, 0, NULL); - if (phy_type & (1 << I40E_PHY_TYPE_40GBASE_CR4_CU) || - phy_type & (1 << I40E_PHY_TYPE_40GBASE_CR4)) + if (phy_type & (1 << I40E_PHY_TYPE_40GBASE_CR4) || + phy_type & (1 << I40E_PHY_TYPE_40GBASE_CR4_CU) || + phy_type & (1 << I40E_PHY_TYPE_40GBASE_AOC) || + phy_type & (1 << I40E_PHY_TYPE_XLAUI) || + phy_type & (1 << I40E_PHY_TYPE_XLPPI) || + /* KR4 uses CR4 until the OS has the real media type */ + phy_type & (1 << I40E_PHY_TYPE_40GBASE_KR4)) ifmedia_add(&vsi->media, IFM_ETHER | IFM_40G_CR4, 0, NULL); + if (phy_type & (1 << I40E_PHY_TYPE_40GBASE_SR4)) ifmedia_add(&vsi->media, IFM_ETHER | IFM_40G_SR4, 0, NULL); if (phy_type & (1 << I40E_PHY_TYPE_40GBASE_LR4)) @@ -2370,7 +2357,7 @@ ixl_setup_interface(device_t dev, struct ixl_vsi *vsi) struct ifnet *ifp; struct i40e_hw *hw = vsi->hw; struct ixl_queue *que = vsi->queues; - struct i40e_aq_get_phy_abilities_resp abilities_resp; + struct i40e_aq_get_phy_abilities_resp abilities; enum i40e_status_code aq_error = 0; INIT_DEBUGOUT("ixl_setup_interface: begin"); @@ -2437,21 +2424,25 @@ ixl_setup_interface(device_t dev, struct ixl_vsi *vsi) ifmedia_init(&vsi->media, IFM_IMASK, ixl_media_change, ixl_media_status); - aq_error = i40e_aq_get_phy_capabilities(hw, FALSE, TRUE, &abilities_resp, NULL); + aq_error = i40e_aq_get_phy_capabilities(hw, + FALSE, TRUE, &abilities, NULL); + /* May need delay to detect fiber correctly */ 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); + TRUE, &abilities, NULL); + } + if (aq_error) { if (aq_error == I40E_ERR_UNKNOWN_PHY) device_printf(dev, "Unknown PHY type detected!\n"); else - ixl_add_ifmedia(vsi, abilities_resp.phy_type); - } else if (aq_error) { - device_printf(dev, "Error getting supported media types, err %d," - " AQ error %d\n", aq_error, hw->aq.asq_last_status); - } else - ixl_add_ifmedia(vsi, abilities_resp.phy_type); + device_printf(dev, + "Error getting supported media types, err %d," + " AQ error %d\n", aq_error, hw->aq.asq_last_status); + return (0); + } + + ixl_add_ifmedia(vsi, abilities.phy_type); /* Use autoselect media by default */ ifmedia_add(&vsi->media, IFM_ETHER | IFM_AUTO, 0, NULL); @@ -2477,20 +2468,23 @@ ixl_config_link(struct i40e_hw *hw) /********************************************************************* * - * Initialize this VSI + * Get Firmware Switch configuration + * - this will need to be more robust when more complex + * switch configurations are enabled. * **********************************************************************/ static int -ixl_setup_vsi(struct ixl_vsi *vsi) +ixl_switch_config(struct ixl_pf *pf) { - struct i40e_hw *hw = vsi->hw; + struct i40e_hw *hw = &pf->hw; + struct ixl_vsi *vsi = &pf->vsi; device_t dev = vsi->dev; struct i40e_aqc_get_switch_config_resp *sw_config; - struct i40e_vsi_context ctxt; u8 aq_buf[I40E_AQ_LARGE_BUF]; int ret = I40E_SUCCESS; u16 next = 0; + memset(&aq_buf, 0, sizeof(aq_buf)); sw_config = (struct i40e_aqc_get_switch_config_resp *)aq_buf; ret = i40e_aq_get_switch_config(hw, sw_config, sizeof(aq_buf), &next, NULL); @@ -2507,16 +2501,34 @@ ixl_setup_vsi(struct ixl_vsi *vsi) sw_config->element[0].uplink_seid, sw_config->element[0].downlink_seid); #endif - /* Save off this important value */ + /* Simplified due to a single VSI at the moment */ vsi->seid = sw_config->element[0].seid; + return (ret); +} + +/********************************************************************* + * + * Initialize the VSI: this handles contexts, which means things + * like the number of descriptors, buffer size, + * plus we init the rings thru this function. + * + **********************************************************************/ +static int +ixl_initialize_vsi(struct ixl_vsi *vsi) +{ + struct ixl_queue *que = vsi->queues; + device_t dev = vsi->dev; + struct i40e_hw *hw = vsi->hw; + struct i40e_vsi_context ctxt; + int err = 0; memset(&ctxt, 0, sizeof(ctxt)); ctxt.seid = vsi->seid; ctxt.pf_num = hw->pf_id; - ret = i40e_aq_get_vsi_params(hw, &ctxt, NULL); - if (ret) { - device_printf(dev,"get vsi params failed %x!!\n", ret); - return (ret); + err = i40e_aq_get_vsi_params(hw, &ctxt, NULL); + if (err) { + device_printf(dev,"get vsi params failed %x!!\n", err); + return (err); } #ifdef IXL_DEBUG printf("get_vsi_params: seid: %d, uplinkseid: %d, vsi_number: %d, " @@ -2553,29 +2565,12 @@ ixl_setup_vsi(struct ixl_vsi *vsi) vsi->hw_filters_add = 0; vsi->hw_filters_del = 0; - ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL); - if (ret) + 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); - return (ret); -} - - -/********************************************************************* - * - * Initialize the VSI: this handles contexts, which means things - * like the number of descriptors, buffer size, - * plus we init the rings thru this function. - * - **********************************************************************/ -static int -ixl_initialize_vsi(struct ixl_vsi *vsi) -{ - struct ixl_queue *que = vsi->queues; - device_t dev = vsi->dev; - struct i40e_hw *hw = vsi->hw; - int err = 0; - + return (err); + } for (int i = 0; i < vsi->num_queues; i++, que++) { struct tx_ring *txr = &que->txr; @@ -3216,7 +3211,7 @@ static void ixl_config_rss(struct ixl_vsi *vsi) set_hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP); if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6) set_hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER); - if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6_EX) + if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6_EX) set_hena |= ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6); if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6) set_hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP); @@ -3521,8 +3516,8 @@ ixl_add_hw_filters(struct ixl_vsi *vsi, int flags, int cnt) if (j > 0) { err = i40e_aq_add_macvlan(hw, vsi->seid, a, j, NULL); if (err) - device_printf(dev, "aq_add_macvlan err %d, aq_error %d\n", - err, 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; } @@ -4307,24 +4302,15 @@ ixl_set_flowcntl(SYSCTL_HANDLER_ARGS) struct ixl_pf *pf = (struct ixl_pf *)arg1; struct i40e_hw *hw = &pf->hw; device_t dev = pf->dev; - int requested_fc = 0, error = 0; + int error = 0; enum i40e_status_code aq_error = 0; u8 fc_aq_err = 0; - aq_error = i40e_aq_get_link_info(hw, TRUE, NULL, NULL); - if (aq_error) { - device_printf(dev, - "%s: Error retrieving link info from aq, %d\n", - __func__, aq_error); - return (EAGAIN); - } - - /* Read in new mode */ - requested_fc = hw->fc.current_mode; - error = sysctl_handle_int(oidp, &requested_fc, 0, req); + /* Get request */ + error = sysctl_handle_int(oidp, &pf->fc, 0, req); if ((error) || (req->newptr == NULL)) return (error); - if (requested_fc < 0 || requested_fc > 3) { + if (pf->fc < 0 || pf->fc > 3) { device_printf(dev, "Invalid fc mode; valid modes are 0 through 3\n"); return (EINVAL); @@ -4342,7 +4328,7 @@ ixl_set_flowcntl(SYSCTL_HANDLER_ARGS) } /* Set fc ability for port */ - hw->fc.requested_mode = requested_fc; + hw->fc.requested_mode = pf->fc; aq_error = i40e_set_fc(hw, &fc_aq_err, TRUE); if (aq_error) { device_printf(dev, @@ -4351,14 +4337,6 @@ ixl_set_flowcntl(SYSCTL_HANDLER_ARGS) return (EAGAIN); } - if (hw->fc.current_mode != hw->fc.requested_mode) { - device_printf(dev, "%s: FC set failure:\n", __func__); - device_printf(dev, "%s: Current: %s / Requested: %s\n", - __func__, - ixl_fc_string[hw->fc.current_mode], - ixl_fc_string[hw->fc.requested_mode]); - } - return (0); } @@ -4417,9 +4395,11 @@ ixl_set_advertised_speeds(struct ixl_pf *pf, int speeds) enum i40e_status_code aq_error = 0; /* Get current capability information */ - aq_error = i40e_aq_get_phy_capabilities(hw, FALSE, FALSE, &abilities, NULL); + aq_error = i40e_aq_get_phy_capabilities(hw, + FALSE, FALSE, &abilities, NULL); if (aq_error) { - device_printf(dev, "%s: Error getting phy capabilities %d," + device_printf(dev, + "%s: Error getting phy capabilities %d," " aq error: %d\n", __func__, aq_error, hw->aq.asq_last_status); return (EAGAIN); @@ -4444,7 +4424,8 @@ ixl_set_advertised_speeds(struct ixl_pf *pf, int speeds) /* Do aq command & restart link */ aq_error = i40e_aq_set_phy_config(hw, &config, NULL); if (aq_error) { - device_printf(dev, "%s: Error setting new phy config %d," + device_printf(dev, + "%s: Error setting new phy config %d," " aq error: %d\n", __func__, aq_error, hw->aq.asq_last_status); return (EAGAIN); diff --git a/sys/dev/ixl/if_ixlv.c b/sys/dev/ixl/if_ixlv.c index 523c7ce..f1e106e 100644 --- a/sys/dev/ixl/if_ixlv.c +++ b/sys/dev/ixl/if_ixlv.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2013-2014, Intel Corporation + Copyright (c) 2013-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -32,9 +32,12 @@ ******************************************************************************/ /*$FreeBSD$*/ +#ifndef IXL_STANDALONE_BUILD #include "opt_inet.h" #include "opt_inet6.h" #include "opt_rss.h" +#endif + #include "ixl.h" #include "ixlv.h" @@ -1819,8 +1822,7 @@ ixlv_msix_adminq(void *arg) { struct ixlv_sc *sc = arg; struct i40e_hw *hw = &sc->hw; - device_t dev = sc->dev; - u32 reg, mask, oldreg; + u32 reg, mask; reg = rd32(hw, I40E_VFINT_ICR01); mask = rd32(hw, I40E_VFINT_ICR0_ENA1); @@ -1829,43 +1831,6 @@ ixlv_msix_adminq(void *arg) reg |= I40E_PFINT_DYN_CTL0_CLEARPBA_MASK; wr32(hw, I40E_VFINT_DYN_CTL01, reg); - /* check for Admin queue errors */ - oldreg = reg = rd32(hw, hw->aq.arq.len); - if (reg & I40E_VF_ARQLEN_ARQVFE_MASK) { - device_printf(dev, "ARQ VF Error detected\n"); - reg &= ~I40E_VF_ARQLEN_ARQVFE_MASK; - } - if (reg & I40E_VF_ARQLEN_ARQOVFL_MASK) { - device_printf(dev, "ARQ Overflow Error detected\n"); - reg &= ~I40E_VF_ARQLEN_ARQOVFL_MASK; - } - if (reg & I40E_VF_ARQLEN_ARQCRIT_MASK) { - device_printf(dev, "ARQ Critical Error detected\n"); - reg &= ~I40E_VF_ARQLEN_ARQCRIT_MASK; - } - if (oldreg != reg) - wr32(hw, hw->aq.arq.len, reg); - - oldreg = reg = rd32(hw, hw->aq.asq.len); - if (reg & I40E_VF_ATQLEN_ATQVFE_MASK) { - device_printf(dev, "ASQ VF Error detected\n"); - reg &= ~I40E_VF_ATQLEN_ATQVFE_MASK; - } - if (reg & I40E_VF_ATQLEN_ATQOVFL_MASK) { - device_printf(dev, "ASQ Overflow Error detected\n"); - reg &= ~I40E_VF_ATQLEN_ATQOVFL_MASK; - } - if (reg & I40E_VF_ATQLEN_ATQCRIT_MASK) { - device_printf(dev, "ASQ Critical Error detected\n"); - reg &= ~I40E_VF_ATQLEN_ATQCRIT_MASK; - } - if (oldreg != reg) - wr32(hw, hw->aq.asq.len, reg); - - /* re-enable interrupt causes */ - wr32(hw, I40E_VFINT_ICR0_ENA1, mask); - wr32(hw, I40E_VFINT_DYN_CTL01, I40E_VFINT_DYN_CTL01_INTENA_MASK); - /* schedule task */ taskqueue_enqueue(sc->tq, &sc->aq_irq); return; @@ -2600,7 +2565,7 @@ ixlv_config_rss(struct ixlv_sc *sc) set_hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP); if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6) set_hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER); - if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6_EX) + if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6_EX) set_hena |= ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6); if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6) set_hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP); @@ -2752,8 +2717,10 @@ ixlv_do_adminq_locked(struct ixlv_sc *sc) struct i40e_hw *hw = &sc->hw; struct i40e_arq_event_info event; struct i40e_virtchnl_msg *v_msg; - i40e_status ret; + device_t dev = sc->dev; u16 result = 0; + u32 reg, oldreg; + i40e_status ret; IXLV_CORE_LOCK_ASSERT(sc); @@ -2771,6 +2738,39 @@ ixlv_do_adminq_locked(struct ixlv_sc *sc) bzero(event.msg_buf, IXL_AQ_BUF_SZ); } while (result); + /* check for Admin queue errors */ + oldreg = reg = rd32(hw, hw->aq.arq.len); + if (reg & I40E_VF_ARQLEN_ARQVFE_MASK) { + device_printf(dev, "ARQ VF Error detected\n"); + reg &= ~I40E_VF_ARQLEN_ARQVFE_MASK; + } + if (reg & I40E_VF_ARQLEN_ARQOVFL_MASK) { + device_printf(dev, "ARQ Overflow Error detected\n"); + reg &= ~I40E_VF_ARQLEN_ARQOVFL_MASK; + } + if (reg & I40E_VF_ARQLEN_ARQCRIT_MASK) { + device_printf(dev, "ARQ Critical Error detected\n"); + reg &= ~I40E_VF_ARQLEN_ARQCRIT_MASK; + } + if (oldreg != reg) + wr32(hw, hw->aq.arq.len, reg); + + oldreg = reg = rd32(hw, hw->aq.asq.len); + if (reg & I40E_VF_ATQLEN_ATQVFE_MASK) { + device_printf(dev, "ASQ VF Error detected\n"); + reg &= ~I40E_VF_ATQLEN_ATQVFE_MASK; + } + if (reg & I40E_VF_ATQLEN_ATQOVFL_MASK) { + device_printf(dev, "ASQ Overflow Error detected\n"); + reg &= ~I40E_VF_ATQLEN_ATQOVFL_MASK; + } + if (reg & I40E_VF_ATQLEN_ATQCRIT_MASK) { + device_printf(dev, "ASQ Critical Error detected\n"); + reg &= ~I40E_VF_ATQLEN_ATQCRIT_MASK; + } + if (oldreg != reg) + wr32(hw, hw->aq.asq.len, reg); + ixlv_enable_adminq_irq(hw); } diff --git a/sys/dev/ixl/ixl.h b/sys/dev/ixl/ixl.h index 39d9137..30e195f 100644 --- a/sys/dev/ixl/ixl.h +++ b/sys/dev/ixl/ixl.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2013-2014, Intel Corporation + Copyright (c) 2013-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -208,7 +208,9 @@ #define IXL_TX_BUF_SZ ((u32) 1514) #define IXL_AQ_BUF_SZ ((u32) 4096) #define IXL_RX_HDR 128 +/* Controls the length of the Admin Queue */ #define IXL_AQ_LEN 256 +#define IXL_AQ_LEN_MAX 1024 #define IXL_AQ_BUFSZ 4096 #define IXL_RX_LIMIT 512 #define IXL_RX_ITR 0 @@ -273,7 +275,7 @@ #define IXL_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx) #define IXL_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->mtx) -#if __FreeBSD_version >= 1100000 +#if __FreeBSD_version >= 1100036 #define IXL_SET_IPACKETS(vsi, count) (vsi)->ipackets = (count) #define IXL_SET_IERRORS(vsi, count) (vsi)->ierrors = (count) #define IXL_SET_OPACKETS(vsi, count) (vsi)->opackets = (count) @@ -469,7 +471,6 @@ struct ixl_vsi { u16 max_frame_size; u32 link_speed; bool link_up; - u32 fc; /* local flow ctrl setting */ /* MAC/VLAN Filter list */ struct ixl_ftl_head ftl; diff --git a/sys/dev/ixl/ixl_pf.h b/sys/dev/ixl/ixl_pf.h index 055c54f..7c3d3bb 100644 --- a/sys/dev/ixl/ixl_pf.h +++ b/sys/dev/ixl/ixl_pf.h @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2013-2014, Intel Corporation + Copyright (c) 2013-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -65,6 +65,7 @@ struct ixl_pf { struct taskqueue *tq; int advertised_speed; + int fc; /* local flow ctrl setting */ /* ** VSI - Stations: diff --git a/sys/dev/ixl/ixl_txrx.c b/sys/dev/ixl/ixl_txrx.c index 6a6ab7c..89b07d1 100755 --- a/sys/dev/ixl/ixl_txrx.c +++ b/sys/dev/ixl/ixl_txrx.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2013-2014, Intel Corporation + Copyright (c) 2013-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -38,12 +38,15 @@ ** both the BASE and the VF drivers. */ +#ifndef IXL_STANDALONE_BUILD #include "opt_inet.h" #include "opt_inet6.h" #include "opt_rss.h" +#endif + #include "ixl.h" -#ifdef RSS +#ifdef RSS #include <net/rss_config.h> #endif @@ -1371,7 +1374,7 @@ ixl_rx_discard(struct rx_ring *rxr, int i) #ifdef RSS /* -** ixl_ptype_to_hash: parse the packet type +** i40e_ptype_to_hash: parse the packet type ** to determine the appropriate hash. */ static inline int diff --git a/sys/dev/ixl/ixlvc.c b/sys/dev/ixl/ixlvc.c index aa81bc1..a0142ba 100644 --- a/sys/dev/ixl/ixlvc.c +++ b/sys/dev/ixl/ixlvc.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2013-2014, Intel Corporation + Copyright (c) 2013-2015, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -770,11 +770,16 @@ void ixlv_request_stats(struct ixlv_sc *sc) { struct i40e_virtchnl_queue_select vqs; + int error = 0; vqs.vsi_id = sc->vsi_res->vsi_id; /* Low priority, we don't need to error check */ - ixlv_send_pf_msg(sc, I40E_VIRTCHNL_OP_GET_STATS, + error = ixlv_send_pf_msg(sc, I40E_VIRTCHNL_OP_GET_STATS, (u8 *)&vqs, sizeof(vqs)); +#ifdef IXL_DEBUG + if (error) + device_printf(sc->dev, "Error sending stats request to PF: %d\n", error); +#endif } /* |