svn commit: r299552 - head/sys/dev/ixl
Eric Joyner
erj at FreeBSD.org
Thu May 12 18:21:19 UTC 2016
Author: erj
Date: Thu May 12 18:21:17 2016
New Revision: 299552
URL: https://svnweb.freebsd.org/changeset/base/299552
Log:
ixl: Update to 1.4.17-k.
Changes:
Kiran Patil i40e-shared: APIs to Add/remove port mirroring rules
Shannon Nelson i40e-shared: add VEB stat control and remove L2 cloud filter
Eric Joyner ixl: Update NVM version information shown.
Eric Joyner ixl: Remove empty else block.
Eric Joyner ixl: Slightly re-work ixl_init_msix().
Eric Joyner ixl: Remove duplicate queue enablement.
Shannon Nelson i40e-shared: implement the API function for aq_set_switch_config
Eric Joyner ixl: Update nvm version string shown in sysctl.
Eric Joyner ixl/ixlv: Changes to PF/VF minor version checking/handling.
Eric Joyner ixlv: Reduce maximum wait time for responses to VF AQ messages.
Eric Joyner ixl/ixlv: Edit comments, comment out code, and edit spacing.
Eric Joyner ixl: Print log message when SR-IOV init is successful.
Eric Joyner ixl: Add Tx Flow Control filter from main PF VSI.
Eric Joyner ixlv: Add extra error message when ixlv_get_vf_config times out.
Eric Joyner ixl: Assign current MOCS optics the XLPPI media type.
Eric Joyner ixl: Remove conditional wait after link status event.
Eric Joyner ixl: Add line break and remove extraneous return statement.
Eric Joyner ixl: Allow 40G speeds in the advertise_speed sysctl.
Eric Joyner ixl: Add "CRC enable" field to link_status sysctl output.
Eric Joyner ixl: Move sbuf.h include out of IXL_DEBUG* defines.
Eric Joyner ixl: Move remaining debug sysctl funcs to IXL_DEBUG_SYSCTL define.
Eric Joyner ixl: Add cases for all remaining media types in shared code to media_status().
Differential Revision: https://reviews.freebsd.org/D6211
Reviewed by: sbruno, kmacy, jeffrey.e.pieper at intel.com
MFC after: 2 weeks
Sponsored by: Intel Corporation
Modified:
head/sys/dev/ixl/i40e_common.c
head/sys/dev/ixl/i40e_nvm.c
head/sys/dev/ixl/i40e_prototype.h
head/sys/dev/ixl/if_ixl.c
head/sys/dev/ixl/if_ixlv.c
head/sys/dev/ixl/ixl.h
head/sys/dev/ixl/ixl_pf.h
head/sys/dev/ixl/ixlv.h
head/sys/dev/ixl/ixlvc.c
Modified: head/sys/dev/ixl/i40e_common.c
==============================================================================
--- head/sys/dev/ixl/i40e_common.c Thu May 12 18:20:59 2016 (r299551)
+++ head/sys/dev/ixl/i40e_common.c Thu May 12 18:21:17 2016 (r299552)
@@ -2161,6 +2161,37 @@ enum i40e_status_code i40e_aq_set_vsi_br
}
/**
+ * i40e_aq_set_vsi_vlan_promisc - control the VLAN promiscuous setting
+ * @hw: pointer to the hw struct
+ * @seid: vsi number
+ * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum i40e_status_code i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw,
+ u16 seid, bool enable,
+ struct i40e_asq_cmd_details *cmd_details)
+{
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+ (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
+ enum i40e_status_code status;
+ u16 flags = 0;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_vsi_promiscuous_modes);
+ if (enable)
+ flags |= I40E_AQC_SET_VSI_PROMISC_VLAN;
+
+ cmd->promiscuous_flags = CPU_TO_LE16(flags);
+ cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_VLAN);
+ cmd->seid = CPU_TO_LE16(seid);
+
+ status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+ return status;
+}
+
+/**
* i40e_get_vsi_params - get VSI configuration info
* @hw: pointer to the hw struct
* @vsi_ctx: pointer to a vsi context struct
@@ -2263,6 +2294,34 @@ enum i40e_status_code i40e_aq_get_switch
}
/**
+ * i40e_aq_set_switch_config
+ * @hw: pointer to the hardware structure
+ * @flags: bit flag values to set
+ * @valid_flags: which bit flags to set
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Set switch configuration bits
+ **/
+enum i40e_status_code i40e_aq_set_switch_config(struct i40e_hw *hw,
+ u16 flags, u16 valid_flags,
+ struct i40e_asq_cmd_details *cmd_details)
+{
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_switch_config *scfg =
+ (struct i40e_aqc_set_switch_config *)&desc.params.raw;
+ enum i40e_status_code status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_switch_config);
+ scfg->flags = CPU_TO_LE16(flags);
+ scfg->valid_flags = CPU_TO_LE16(valid_flags);
+
+ status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+ return status;
+}
+
+/**
* i40e_aq_get_firmware_version
* @hw: pointer to the hw struct
* @fw_major_version: firmware major version
@@ -2437,8 +2496,8 @@ i40e_link_speed_exit:
* @downlink_seid: the VSI SEID
* @enabled_tc: bitmap of TCs to be enabled
* @default_port: TRUE for default port VSI, FALSE for control port
- * @enable_l2_filtering: TRUE to add L2 filter table rules to regular forwarding rules for cloud support
* @veb_seid: pointer to where to put the resulting VEB SEID
+ * @enable_stats: TRUE to turn on VEB stats
* @cmd_details: pointer to command details structure or NULL
*
* This asks the FW to add a VEB between the uplink and downlink
@@ -2446,8 +2505,8 @@ i40e_link_speed_exit:
**/
enum i40e_status_code i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
u16 downlink_seid, u8 enabled_tc,
- bool default_port, bool enable_l2_filtering,
- u16 *veb_seid,
+ bool default_port, u16 *veb_seid,
+ bool enable_stats,
struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aq_desc desc;
@@ -2474,8 +2533,9 @@ enum i40e_status_code i40e_aq_add_veb(st
else
veb_flags |= I40E_AQC_ADD_VEB_PORT_TYPE_DATA;
- if (enable_l2_filtering)
- veb_flags |= I40E_AQC_ADD_VEB_ENABLE_L2_FILTER;
+ /* reverse logic here: set the bitflag to disable the stats */
+ if (!enable_stats)
+ veb_flags |= I40E_AQC_ADD_VEB_ENABLE_DISABLE_STATS;
cmd->veb_flags = CPU_TO_LE16(veb_flags);
@@ -2580,7 +2640,8 @@ enum i40e_status_code i40e_aq_add_macvla
for (i = 0; i < count; i++)
if (I40E_IS_MULTICAST(mv_list[i].mac_addr))
- mv_list[i].flags |= I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC;
+ mv_list[i].flags |=
+ CPU_TO_LE16(I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC);
desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
if (buf_size > I40E_AQ_LARGE_BUF)
@@ -2635,6 +2696,137 @@ enum i40e_status_code i40e_aq_remove_mac
}
/**
+ * i40e_mirrorrule_op - Internal helper function to add/delete mirror rule
+ * @hw: pointer to the hw struct
+ * @opcode: AQ opcode for add or delete mirror rule
+ * @sw_seid: Switch SEID (to which rule refers)
+ * @rule_type: Rule Type (ingress/egress/VLAN)
+ * @id: Destination VSI SEID or Rule ID
+ * @count: length of the list
+ * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
+ * @cmd_details: pointer to command details structure or NULL
+ * @rule_id: Rule ID returned from FW
+ * @rule_used: Number of rules used in internal switch
+ * @rule_free: Number of rules free in internal switch
+ *
+ * Add/Delete a mirror rule to a specific switch. Mirror rules are supported for
+ * VEBs/VEPA elements only
+ **/
+static enum i40e_status_code i40e_mirrorrule_op(struct i40e_hw *hw,
+ u16 opcode, u16 sw_seid, u16 rule_type, u16 id,
+ u16 count, __le16 *mr_list,
+ struct i40e_asq_cmd_details *cmd_details,
+ u16 *rule_id, u16 *rules_used, u16 *rules_free)
+{
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_add_delete_mirror_rule *cmd =
+ (struct i40e_aqc_add_delete_mirror_rule *)&desc.params.raw;
+ struct i40e_aqc_add_delete_mirror_rule_completion *resp =
+ (struct i40e_aqc_add_delete_mirror_rule_completion *)&desc.params.raw;
+ enum i40e_status_code status;
+ u16 buf_size;
+
+ buf_size = count * sizeof(*mr_list);
+
+ /* prep the rest of the request */
+ i40e_fill_default_direct_cmd_desc(&desc, opcode);
+ cmd->seid = CPU_TO_LE16(sw_seid);
+ cmd->rule_type = CPU_TO_LE16(rule_type &
+ I40E_AQC_MIRROR_RULE_TYPE_MASK);
+ cmd->num_entries = CPU_TO_LE16(count);
+ /* Dest VSI for add, rule_id for delete */
+ cmd->destination = CPU_TO_LE16(id);
+ if (mr_list) {
+ desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF |
+ I40E_AQ_FLAG_RD));
+ if (buf_size > I40E_AQ_LARGE_BUF)
+ desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+ }
+
+ status = i40e_asq_send_command(hw, &desc, mr_list, buf_size,
+ cmd_details);
+ if (status == I40E_SUCCESS ||
+ hw->aq.asq_last_status == I40E_AQ_RC_ENOSPC) {
+ if (rule_id)
+ *rule_id = LE16_TO_CPU(resp->rule_id);
+ if (rules_used)
+ *rules_used = LE16_TO_CPU(resp->mirror_rules_used);
+ if (rules_free)
+ *rules_free = LE16_TO_CPU(resp->mirror_rules_free);
+ }
+ return status;
+}
+
+/**
+ * i40e_aq_add_mirrorrule - add a mirror rule
+ * @hw: pointer to the hw struct
+ * @sw_seid: Switch SEID (to which rule refers)
+ * @rule_type: Rule Type (ingress/egress/VLAN)
+ * @dest_vsi: SEID of VSI to which packets will be mirrored
+ * @count: length of the list
+ * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
+ * @cmd_details: pointer to command details structure or NULL
+ * @rule_id: Rule ID returned from FW
+ * @rule_used: Number of rules used in internal switch
+ * @rule_free: Number of rules free in internal switch
+ *
+ * Add mirror rule. Mirror rules are supported for VEBs or VEPA elements only
+ **/
+enum i40e_status_code i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
+ u16 rule_type, u16 dest_vsi, u16 count, __le16 *mr_list,
+ struct i40e_asq_cmd_details *cmd_details,
+ u16 *rule_id, u16 *rules_used, u16 *rules_free)
+{
+ if (!(rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS ||
+ rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS)) {
+ if (count == 0 || !mr_list)
+ return I40E_ERR_PARAM;
+ }
+
+ return i40e_mirrorrule_op(hw, i40e_aqc_opc_add_mirror_rule, sw_seid,
+ rule_type, dest_vsi, count, mr_list,
+ cmd_details, rule_id, rules_used, rules_free);
+}
+
+/**
+ * i40e_aq_delete_mirrorrule - delete a mirror rule
+ * @hw: pointer to the hw struct
+ * @sw_seid: Switch SEID (to which rule refers)
+ * @rule_type: Rule Type (ingress/egress/VLAN)
+ * @count: length of the list
+ * @rule_id: Rule ID that is returned in the receive desc as part of
+ * add_mirrorrule.
+ * @mr_list: list of mirrored VLAN IDs to be removed
+ * @cmd_details: pointer to command details structure or NULL
+ * @rule_used: Number of rules used in internal switch
+ * @rule_free: Number of rules free in internal switch
+ *
+ * Delete a mirror rule. Mirror rules are supported for VEBs/VEPA elements only
+ **/
+enum i40e_status_code i40e_aq_delete_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
+ u16 rule_type, u16 rule_id, u16 count, __le16 *mr_list,
+ struct i40e_asq_cmd_details *cmd_details,
+ u16 *rules_used, u16 *rules_free)
+{
+ /* Rule ID has to be valid except rule_type: INGRESS VLAN mirroring */
+ if (rule_type != I40E_AQC_MIRROR_RULE_TYPE_VLAN) {
+ if (!rule_id)
+ return I40E_ERR_PARAM;
+ } else {
+ /* count and mr_list shall be valid for rule_type INGRESS VLAN
+ * mirroring. For other rule_type, count and rule_type should
+ * not matter.
+ */
+ if (count == 0 || !mr_list)
+ return I40E_ERR_PARAM;
+ }
+
+ return i40e_mirrorrule_op(hw, i40e_aqc_opc_delete_mirror_rule, sw_seid,
+ rule_type, rule_id, count, mr_list,
+ cmd_details, NULL, rules_used, rules_free);
+}
+
+/**
* i40e_aq_add_vlan - Add VLAN ids to the HW filtering
* @hw: pointer to the hw struct
* @seid: VSI for the vlan filters
Modified: head/sys/dev/ixl/i40e_nvm.c
==============================================================================
--- head/sys/dev/ixl/i40e_nvm.c Thu May 12 18:20:59 2016 (r299551)
+++ head/sys/dev/ixl/i40e_nvm.c Thu May 12 18:21:17 2016 (r299552)
@@ -54,7 +54,7 @@ enum i40e_status_code i40e_read_nvm_aq(s
* once per NVM initialization, e.g. inside the i40e_init_shared_code().
* Please notice that the NVM term is used here (& in all methods covered
* in this file) as an equivalent of the FLASH part mapped into the SR.
- * We are accessing FLASH always thru the Shadow RAM.
+ * We are accessing FLASH always through the Shadow RAM.
**/
enum i40e_status_code i40e_init_nvm(struct i40e_hw *hw)
{
@@ -373,7 +373,7 @@ enum i40e_status_code i40e_read_nvm_buff
DEBUGFUNC("i40e_read_nvm_buffer_srctl");
- /* Loop thru the selected region */
+ /* Loop through the selected region */
for (word = 0; word < *words; word++) {
index = offset + word;
ret_code = i40e_read_nvm_word_srctl(hw, index, &data[word]);
Modified: head/sys/dev/ixl/i40e_prototype.h
==============================================================================
--- head/sys/dev/ixl/i40e_prototype.h Thu May 12 18:20:59 2016 (r299551)
+++ head/sys/dev/ixl/i40e_prototype.h Thu May 12 18:21:17 2016 (r299552)
@@ -153,6 +153,9 @@ enum i40e_status_code i40e_aq_set_vsi_mc
enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
u16 seid, bool enable, u16 vid,
struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw,
+ u16 seid, bool enable,
+ struct i40e_asq_cmd_details *cmd_details);
enum i40e_status_code i40e_aq_get_vsi_params(struct i40e_hw *hw,
struct i40e_vsi_context *vsi_ctx,
struct i40e_asq_cmd_details *cmd_details);
@@ -161,8 +164,8 @@ enum i40e_status_code i40e_aq_update_vsi
struct i40e_asq_cmd_details *cmd_details);
enum i40e_status_code i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
u16 downlink_seid, u8 enabled_tc,
- bool default_port, bool enable_l2_filtering,
- u16 *pveb_seid,
+ bool default_port, u16 *pveb_seid,
+ bool enable_stats,
struct i40e_asq_cmd_details *cmd_details);
enum i40e_status_code i40e_aq_get_veb_parameters(struct i40e_hw *hw,
u16 veb_seid, u16 *switch_id, bool *floating,
@@ -175,6 +178,15 @@ enum i40e_status_code i40e_aq_add_macvla
enum i40e_status_code i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 vsi_id,
struct i40e_aqc_remove_macvlan_element_data *mv_list,
u16 count, struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
+ u16 rule_type, u16 dest_vsi, u16 count, __le16 *mr_list,
+ struct i40e_asq_cmd_details *cmd_details,
+ u16 *rule_id, u16 *rules_used, u16 *rules_free);
+enum i40e_status_code i40e_aq_delete_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
+ u16 rule_type, u16 rule_id, u16 count, __le16 *mr_list,
+ struct i40e_asq_cmd_details *cmd_details,
+ u16 *rules_used, u16 *rules_free);
+
enum i40e_status_code i40e_aq_add_vlan(struct i40e_hw *hw, u16 vsi_id,
struct i40e_aqc_add_remove_vlan_element_data *v_list,
u8 count, struct i40e_asq_cmd_details *cmd_details);
@@ -188,6 +200,9 @@ enum i40e_status_code i40e_aq_get_switch
struct i40e_aqc_get_switch_config_resp *buf,
u16 buf_size, u16 *start_seid,
struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_aq_set_switch_config(struct i40e_hw *hw,
+ u16 flags, u16 valid_flags,
+ struct i40e_asq_cmd_details *cmd_details);
enum i40e_status_code i40e_aq_request_resource(struct i40e_hw *hw,
enum i40e_aq_resources_ids resource,
enum i40e_aq_resource_access_type access,
Modified: head/sys/dev/ixl/if_ixl.c
==============================================================================
--- head/sys/dev/ixl/if_ixl.c Thu May 12 18:20:59 2016 (r299551)
+++ head/sys/dev/ixl/if_ixl.c Thu May 12 18:21:17 2016 (r299552)
@@ -48,7 +48,7 @@
/*********************************************************************
* Driver version
*********************************************************************/
-char ixl_driver_version[] = "1.4.13-k";
+char ixl_driver_version[] = "1.4.17-k";
/*********************************************************************
* PCI Device ID Table
@@ -157,15 +157,15 @@ static void ixl_free_mac_filters(struct
/* Sysctls*/
static void ixl_add_device_sysctls(struct ixl_pf *);
-static int ixl_debug_info(SYSCTL_HANDLER_ARGS);
-static void ixl_print_debug_info(struct ixl_pf *);
-
static int ixl_set_flowcntl(SYSCTL_HANDLER_ARGS);
static int ixl_set_advertise(SYSCTL_HANDLER_ARGS);
static int ixl_current_speed(SYSCTL_HANDLER_ARGS);
static int ixl_sysctl_show_fw(SYSCTL_HANDLER_ARGS);
#ifdef IXL_DEBUG_SYSCTL
+static int ixl_debug_info(SYSCTL_HANDLER_ARGS);
+static void ixl_print_debug_info(struct ixl_pf *);
+
static int ixl_sysctl_link_status(SYSCTL_HANDLER_ARGS);
static int ixl_sysctl_phy_abilities(SYSCTL_HANDLER_ARGS);
static int ixl_sysctl_sw_filter_list(SYSCTL_HANDLER_ARGS);
@@ -359,8 +359,9 @@ ixl_probe(device_t dev)
char device_name[256];
static bool lock_init = FALSE;
+#if 0
INIT_DEBUGOUT("ixl_probe: begin");
-
+#endif
pci_vendor_id = pci_get_vendor(dev);
if (pci_vendor_id != I40E_INTEL_VENDOR_ID)
return (ENXIO);
@@ -412,7 +413,7 @@ ixl_attach(device_t dev)
{
struct ixl_pf *pf;
struct i40e_hw *hw;
- struct ixl_vsi *vsi;
+ struct ixl_vsi *vsi;
u16 bus;
int error = 0;
#ifdef PCI_IOV
@@ -496,7 +497,8 @@ ixl_attach(device_t dev)
error = EIO;
goto err_out;
}
- device_printf(dev, "%s\n", ixl_fw_version_str(hw));
+ ixl_print_nvm_version(pf);
+
if (error == I40E_ERR_FIRMWARE_API_VERSION) {
device_printf(dev, "The driver for the device stopped "
"because the NVM image is newer than expected.\n"
@@ -631,10 +633,12 @@ ixl_attach(device_t dev)
IOV_SCHEMA_HASDEFAULT, FALSE);
iov_error = pci_iov_attach(dev, pf_schema, vf_schema);
- if (iov_error != 0)
+ if (iov_error != 0) {
device_printf(dev,
"Failed to initialize SR-IOV (error=%d)\n",
iov_error);
+ } else
+ device_printf(dev, "SR-IOV ready\n");
}
#endif
@@ -1085,7 +1089,6 @@ ixl_init_locked(struct ixl_pf *pf)
device_printf(dev, "LLA address"
"change failed!!\n");
return;
- } else {
}
}
@@ -1227,7 +1230,7 @@ ixl_reset(struct ixl_pf *pf)
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);
+ device_printf(dev, "init: LAN HMC config failed; status code %d\n", error);
error = EIO;
goto err_out;
}
@@ -1253,7 +1256,7 @@ ixl_reset(struct ixl_pf *pf)
// XXX: (Rebuild VSIs?)
- // Firmware delay workaround
+ /* 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);
@@ -1265,20 +1268,6 @@ ixl_reset(struct ixl_pf *pf)
}
}
- // [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);
@@ -1598,6 +1587,9 @@ ixl_media_status(struct ifnet * ifp, str
case I40E_PHY_TYPE_1000BASE_LX:
ifmr->ifm_active |= IFM_1000_LX;
break;
+ case I40E_PHY_TYPE_1000BASE_T_OPTICAL:
+ ifmr->ifm_active |= IFM_OTHER;
+ break;
/* 10 G */
case I40E_PHY_TYPE_10GBASE_SFPP_CU:
ifmr->ifm_active |= IFM_10G_TWINAX;
@@ -1611,6 +1603,11 @@ ixl_media_status(struct ifnet * ifp, str
case I40E_PHY_TYPE_10GBASE_T:
ifmr->ifm_active |= IFM_10G_T;
break;
+ case I40E_PHY_TYPE_XAUI:
+ case I40E_PHY_TYPE_XFI:
+ case I40E_PHY_TYPE_10GBASE_AOC:
+ ifmr->ifm_active |= IFM_OTHER;
+ break;
/* 40 G */
case I40E_PHY_TYPE_40GBASE_CR4:
case I40E_PHY_TYPE_40GBASE_CR4_CU:
@@ -1622,10 +1619,16 @@ ixl_media_status(struct ifnet * ifp, str
case I40E_PHY_TYPE_40GBASE_LR4:
ifmr->ifm_active |= IFM_40G_LR4;
break;
+ case I40E_PHY_TYPE_XLAUI:
+ ifmr->ifm_active |= IFM_OTHER;
+ break;
#ifndef IFM_ETH_XTYPE
case I40E_PHY_TYPE_1000BASE_KX:
ifmr->ifm_active |= IFM_1000_CX;
break;
+ case I40E_PHY_TYPE_SGMII:
+ ifmr->ifm_active |= IFM_OTHER;
+ break;
case I40E_PHY_TYPE_10GBASE_CR1_CU:
case I40E_PHY_TYPE_10GBASE_CR1:
ifmr->ifm_active |= IFM_10G_TWINAX;
@@ -1636,14 +1639,21 @@ ixl_media_status(struct ifnet * ifp, str
case I40E_PHY_TYPE_10GBASE_KR:
ifmr->ifm_active |= IFM_10G_SR;
break;
+ case I40E_PHY_TYPE_SFI:
+ ifmr->ifm_active |= IFM_OTHER;
+ break;
case I40E_PHY_TYPE_40GBASE_KR4:
case I40E_PHY_TYPE_XLPPI:
+ case I40E_PHY_TYPE_40GBASE_AOC:
ifmr->ifm_active |= IFM_40G_SR4;
break;
#else
case I40E_PHY_TYPE_1000BASE_KX:
ifmr->ifm_active |= IFM_1000_KX;
break;
+ case I40E_PHY_TYPE_SGMII:
+ ifmr->ifm_active |= IFM_1000_SGMII;
+ break;
/* ERJ: What's the difference between these? */
case I40E_PHY_TYPE_10GBASE_CR1_CU:
case I40E_PHY_TYPE_10GBASE_CR1:
@@ -1655,6 +1665,9 @@ ixl_media_status(struct ifnet * ifp, str
case I40E_PHY_TYPE_10GBASE_KR:
ifmr->ifm_active |= IFM_10G_KR;
break;
+ case I40E_PHY_TYPE_SFI:
+ ifmr->ifm_active |= IFM_10G_SFI;
+ break;
/* Our single 20G media type */
case I40E_PHY_TYPE_20GBASE_KR2:
ifmr->ifm_active |= IFM_20G_KR2;
@@ -1663,9 +1676,11 @@ ixl_media_status(struct ifnet * ifp, str
ifmr->ifm_active |= IFM_40G_KR4;
break;
case I40E_PHY_TYPE_XLPPI:
+ case I40E_PHY_TYPE_40GBASE_AOC:
ifmr->ifm_active |= IFM_40G_XLPPI;
break;
#endif
+ /* Unknown to driver */
default:
ifmr->ifm_active |= IFM_UNKNOWN;
break;
@@ -2066,8 +2081,6 @@ ixl_stop_locked(struct ixl_pf *pf)
/* Tell the stack that the interface is no longer active */
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
- return;
}
@@ -2100,7 +2113,7 @@ ixl_assign_vsi_legacy(struct ixl_pf *pf)
ixl_intr, pf, &pf->tag);
if (error) {
pf->res = NULL;
- device_printf(dev, "Failed to register legacy/msi handler");
+ device_printf(dev, "Failed to register legacy/msi handler\n");
return (error);
}
bus_describe_intr(dev, pf->res, pf->tag, "irq0");
@@ -2261,7 +2274,7 @@ ixl_init_msix(struct ixl_pf *pf)
/* Override by tuneable */
if (ixl_enable_msix == 0)
- goto msi;
+ goto no_msix;
/*
** When used in a virtualized environment
@@ -2292,7 +2305,7 @@ ixl_init_msix(struct ixl_pf *pf)
/* May not be enabled */
device_printf(pf->dev,
"Unable to map MSIX table\n");
- goto msi;
+ goto no_msix;
}
available = pci_msix_count(dev);
@@ -2300,13 +2313,13 @@ ixl_init_msix(struct ixl_pf *pf)
bus_release_resource(dev, SYS_RES_MEMORY,
rid, pf->msix_mem);
pf->msix_mem = NULL;
- goto msi;
+ goto no_msix;
}
/* Figure out a reasonable auto config value */
queues = (mp_ncpus > (available - 1)) ? (available - 1) : mp_ncpus;
- /* Override with hardcoded value if it's less than autoconfig count */
+ /* Override with tunable value if tunable is less than autoconfig count */
if ((ixl_max_queues != 0) && (ixl_max_queues <= queues))
queues = ixl_max_queues;
else if ((ixl_max_queues != 0) && (ixl_max_queues > queues))
@@ -2363,22 +2376,20 @@ ixl_init_msix(struct ixl_pf *pf)
#endif
return (vectors);
}
-msi:
- vectors = pci_msi_count(dev);
+no_msix:
+ vectors = pci_msi_count(dev);
pf->vsi.num_queues = 1;
- pf->msix = 1;
ixl_max_queues = 1;
ixl_enable_msix = 0;
- if (vectors == 1 && pci_alloc_msi(dev, &vectors) == 0)
+ if (vectors == 1 && pci_alloc_msi(dev, &vectors) == 0)
device_printf(pf->dev, "Using an MSI interrupt\n");
else {
- pf->msix = 0;
+ vectors = 0;
device_printf(pf->dev, "Using a Legacy interrupt\n");
}
return (vectors);
}
-
/*
* Plumb MSIX vectors
*/
@@ -2489,14 +2500,6 @@ ixl_configure_legacy(struct ixl_pf *pf)
| (IXL_QUEUE_EOL << I40E_QINT_TQCTL_NEXTQ_INDX_SHIFT);
wr32(hw, I40E_QINT_TQCTL(0), reg);
- /* Next enable the queue pair */
- reg = rd32(hw, I40E_QTX_ENA(0));
- reg |= I40E_QTX_ENA_QENA_REQ_MASK;
- wr32(hw, I40E_QTX_ENA(0), reg);
-
- reg = rd32(hw, I40E_QRX_ENA(0));
- reg |= I40E_QRX_ENA_QENA_REQ_MASK;
- wr32(hw, I40E_QRX_ENA(0), reg);
}
@@ -2544,7 +2547,7 @@ ixl_allocate_pci_resources(struct ixl_pf
&rid, RF_ACTIVE);
if (!(pf->pci_mem)) {
- device_printf(dev, "Unable to allocate bus resource: memory\n");
+ device_printf(dev, "Unable to allocate bus resource: PCI memory\n");
return (ENXIO);
}
@@ -2834,11 +2837,6 @@ ixl_link_event(struct ixl_pf *pf, struct
struct i40e_aqc_get_link_status *status =
(struct i40e_aqc_get_link_status *)&e->desc.params.raw;
- /* Firmware workaround: may need to wait for link to actually come up... */
- if (!pf->link_up && (status->link_info & I40E_AQ_SIGNAL_DETECT)) {
- device_printf(dev, "%s: Waiting...\n", __func__);
- i40e_msec_delay(4000);
- }
/* Request link status from adapter */
hw->phy.get_link_info = TRUE;
@@ -2946,6 +2944,7 @@ 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;
+ /* This VSI is assigned 64 queues (we may not use all of them) */
ctxt.info.tc_mapping[0] = 0x0c00;
/* Set VLAN receive stripping mode */
@@ -3784,12 +3783,20 @@ ixl_setup_vlan_filters(struct ixl_vsi *v
/*
** Initialize filter list and add filters that the hardware
** needs to know about.
+**
+** Requires VSI's filter list & seid to be set before calling.
*/
static void
ixl_init_filters(struct ixl_vsi *vsi)
{
/* Add broadcast address */
ixl_add_filter(vsi, ixl_bcast_addr, IXL_VLAN_ANY);
+
+ /*
+ * Prevent Tx flow control frames from being sent out by
+ * non-firmware transmitters.
+ */
+ i40e_add_filter_to_drop_tx_flow_control_frames(vsi->hw, vsi->seid);
}
/*
@@ -4580,71 +4587,6 @@ ixl_do_adminq(void *context, int pending
IXL_PF_UNLOCK(pf);
}
-static int
-ixl_debug_info(SYSCTL_HANDLER_ARGS)
-{
- struct ixl_pf *pf;
- int error, input = 0;
-
- error = sysctl_handle_int(oidp, &input, 0, req);
-
- if (error || !req->newptr)
- return (error);
-
- if (input == 1) {
- pf = (struct ixl_pf *)arg1;
- ixl_print_debug_info(pf);
- }
-
- return (error);
-}
-
-static void
-ixl_print_debug_info(struct ixl_pf *pf)
-{
- struct i40e_hw *hw = &pf->hw;
- struct ixl_vsi *vsi = &pf->vsi;
- struct ixl_queue *que = vsi->queues;
- struct rx_ring *rxr = &que->rxr;
- struct tx_ring *txr = &que->txr;
- u32 reg;
-
-
- printf("Queue irqs = %jx\n", (uintmax_t)que->irqs);
- printf("AdminQ irqs = %jx\n", (uintmax_t)pf->admin_irq);
- printf("RX next check = %x\n", rxr->next_check);
- printf("RX not ready = %jx\n", (uintmax_t)rxr->not_done);
- printf("RX packets = %jx\n", (uintmax_t)rxr->rx_packets);
- printf("TX desc avail = %x\n", txr->avail);
-
- reg = rd32(hw, I40E_GLV_GORCL(0xc));
- printf("RX Bytes = %x\n", reg);
- reg = rd32(hw, I40E_GLPRT_GORCL(hw->port));
- printf("Port RX Bytes = %x\n", reg);
- reg = rd32(hw, I40E_GLV_RDPC(0xc));
- printf("RX discard = %x\n", reg);
- reg = rd32(hw, I40E_GLPRT_RDPC(hw->port));
- printf("Port RX discard = %x\n", reg);
-
- reg = rd32(hw, I40E_GLV_TEPC(0xc));
- printf("TX errors = %x\n", reg);
- reg = rd32(hw, I40E_GLV_GOTCL(0xc));
- printf("TX Bytes = %x\n", reg);
-
- reg = rd32(hw, I40E_GLPRT_RUC(hw->port));
- printf("RX undersize = %x\n", reg);
- reg = rd32(hw, I40E_GLPRT_RFC(hw->port));
- printf("RX fragments = %x\n", reg);
- reg = rd32(hw, I40E_GLPRT_ROC(hw->port));
- printf("RX oversize = %x\n", reg);
- reg = rd32(hw, I40E_GLPRT_RLEC(hw->port));
- printf("RX length error = %x\n", reg);
- reg = rd32(hw, I40E_GLPRT_MRFC(hw->port));
- printf("mac remote fault = %x\n", reg);
- reg = rd32(hw, I40E_GLPRT_MLFC(hw->port));
- printf("mac local fault = %x\n", reg);
-}
-
/**
* Update VSI-specific ethernet statistics counters.
**/
@@ -5047,6 +4989,8 @@ ixl_set_advertised_speeds(struct ixl_pf
config.eeer = abilities.eeer_val;
config.low_power_ctrl = abilities.d3_lpan;
/* Translate into aq cmd link_speed */
+ if (speeds & 0x10)
+ config.link_speed |= I40E_LINK_SPEED_40GB;
if (speeds & 0x8)
config.link_speed |= I40E_LINK_SPEED_20GB;
if (speeds & 0x4)
@@ -5081,12 +5025,13 @@ ixl_set_advertised_speeds(struct ixl_pf
/*
** Control link advertise speed:
** Flags:
-** 0x1 - advertise 100 Mb
-** 0x2 - advertise 1G
-** 0x4 - advertise 10G
-** 0x8 - advertise 20G
+** 0x1 - advertise 100 Mb
+** 0x2 - advertise 1G
+** 0x4 - advertise 10G
+** 0x8 - advertise 20G
+** 0x10 - advertise 40G
**
-** Does not work on 40G devices.
+** Set to 0 to disable link
*/
static int
ixl_set_advertise(SYSCTL_HANDLER_ARGS)
@@ -5097,44 +5042,50 @@ ixl_set_advertise(SYSCTL_HANDLER_ARGS)
int requested_ls = 0;
int error = 0;
- /*
- ** FW doesn't support changing advertised speed
- ** for 40G devices; speed is always 40G.
- */
- if (i40e_is_40G_device(hw->device_id))
- return (ENODEV);
-
/* Read in new mode */
requested_ls = pf->advertised_speed;
error = sysctl_handle_int(oidp, &requested_ls, 0, req);
if ((error) || (req->newptr == NULL))
return (error);
/* Check for sane value */
- if (requested_ls < 0x1 || requested_ls > 0xE) {
+ if (requested_ls > 0x10) {
device_printf(dev, "Invalid advertised speed; "
- "valid modes are 0x1 through 0xE\n");
+ "valid modes are 0x1 through 0x10\n");
return (EINVAL);
}
/* Then check for validity based on adapter type */
switch (hw->device_id) {
case I40E_DEV_ID_10G_BASE_T:
case I40E_DEV_ID_10G_BASE_T4:
- if (requested_ls & 0x8) {
+ /* BaseT */
+ if (requested_ls & ~(0x7)) {
device_printf(dev,
- "20Gbs speed not supported on this device.\n");
+ "Only 100M/1G/10G speeds supported on this device.\n");
return (EINVAL);
}
break;
case I40E_DEV_ID_20G_KR2:
case I40E_DEV_ID_20G_KR2_A:
- if (requested_ls & 0x1) {
+ /* 20G */
+ if (requested_ls & ~(0xE)) {
+ device_printf(dev,
+ "Only 1G/10G/20G speeds supported on this device.\n");
+ return (EINVAL);
+ }
+ break;
+ case I40E_DEV_ID_KX_B:
+ case I40E_DEV_ID_QSFP_A:
+ case I40E_DEV_ID_QSFP_B:
+ /* 40G */
+ if (requested_ls & ~(0x10)) {
device_printf(dev,
- "100Mbs speed not supported on this device.\n");
+ "Only 40G speeds supported on this device.\n");
return (EINVAL);
}
break;
default:
- if (requested_ls & ~0x6) {
+ /* 10G (1G) */
+ if (requested_ls & ~(0x6)) {
device_printf(dev,
"Only 1/10Gbs speeds are supported on this device.\n");
return (EINVAL);
@@ -5231,18 +5182,14 @@ ixl_sysctl_show_fw(SYSCTL_HANDLER_ARGS)
{
struct ixl_pf *pf = (struct ixl_pf *)arg1;
struct i40e_hw *hw = &pf->hw;
- char buf[32];
+ struct sbuf *sbuf;
- snprintf(buf, sizeof(buf),
- "f%d.%d a%d.%d n%02x.%02x e%08x",
- hw->aq.fw_maj_ver, hw->aq.fw_min_ver,
- hw->aq.api_maj_ver, hw->aq.api_min_ver,
- (hw->nvm.version & IXL_NVM_VERSION_HI_MASK) >>
- IXL_NVM_VERSION_HI_SHIFT,
- (hw->nvm.version & IXL_NVM_VERSION_LO_MASK) >>
- IXL_NVM_VERSION_LO_SHIFT,
- hw->nvm.eetrack);
- return (sysctl_handle_string(oidp, buf, strlen(buf), req));
+ sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
+ ixl_nvm_version_str(hw, sbuf);
+ sbuf_finish(sbuf);
+ sbuf_delete(sbuf);
+
+ return 0;
}
static int
@@ -5323,11 +5270,12 @@ ixl_sysctl_link_status(SYSCTL_HANDLER_AR
"AN info : %#04x\n"
"Ext info : %#04x\n"
"Max Frame: %d\n"
- "Pacing : %#04x",
+ "Pacing : %#04x\n"
+ "CRC En? : %d",
link_status.phy_type, link_status.link_speed,
link_status.link_info, link_status.an_info,
link_status.ext_info, link_status.max_frame_size,
- link_status.pacing);
+ link_status.pacing, link_status.crc_enable);
return (sysctl_handle_string(oidp, buf, strlen(buf), req));
}
@@ -5650,6 +5598,72 @@ ixl_sysctl_switch_config(SYSCTL_HANDLER_
return (error);
}
+
+static int
+ixl_debug_info(SYSCTL_HANDLER_ARGS)
+{
+ struct ixl_pf *pf;
+ int error, input = 0;
+
+ error = sysctl_handle_int(oidp, &input, 0, req);
+
+ if (error || !req->newptr)
+ return (error);
+
+ if (input == 1) {
+ pf = (struct ixl_pf *)arg1;
+ ixl_print_debug_info(pf);
+ }
+
+ return (error);
+}
+
+static void
+ixl_print_debug_info(struct ixl_pf *pf)
+{
+ struct i40e_hw *hw = &pf->hw;
+ struct ixl_vsi *vsi = &pf->vsi;
+ struct ixl_queue *que = vsi->queues;
+ struct rx_ring *rxr = &que->rxr;
+ struct tx_ring *txr = &que->txr;
+ u32 reg;
+
+
+ printf("Queue irqs = %jx\n", (uintmax_t)que->irqs);
+ printf("AdminQ irqs = %jx\n", (uintmax_t)pf->admin_irq);
+ printf("RX next check = %x\n", rxr->next_check);
+ printf("RX not ready = %jx\n", (uintmax_t)rxr->not_done);
+ printf("RX packets = %jx\n", (uintmax_t)rxr->rx_packets);
+ printf("TX desc avail = %x\n", txr->avail);
+
+ reg = rd32(hw, I40E_GLV_GORCL(0xc));
+ printf("RX Bytes = %x\n", reg);
+ reg = rd32(hw, I40E_GLPRT_GORCL(hw->port));
+ printf("Port RX Bytes = %x\n", reg);
+ reg = rd32(hw, I40E_GLV_RDPC(0xc));
+ printf("RX discard = %x\n", reg);
+ reg = rd32(hw, I40E_GLPRT_RDPC(hw->port));
+ printf("Port RX discard = %x\n", reg);
+
+ reg = rd32(hw, I40E_GLV_TEPC(0xc));
+ printf("TX errors = %x\n", reg);
+ reg = rd32(hw, I40E_GLV_GOTCL(0xc));
+ printf("TX Bytes = %x\n", reg);
+
+ reg = rd32(hw, I40E_GLPRT_RUC(hw->port));
+ printf("RX undersize = %x\n", reg);
+ reg = rd32(hw, I40E_GLPRT_RFC(hw->port));
+ printf("RX fragments = %x\n", reg);
+ reg = rd32(hw, I40E_GLPRT_ROC(hw->port));
+ printf("RX oversize = %x\n", reg);
+ reg = rd32(hw, I40E_GLPRT_RLEC(hw->port));
+ printf("RX length error = %x\n", reg);
+ reg = rd32(hw, I40E_GLPRT_MRFC(hw->port));
+ printf("mac remote fault = %x\n", reg);
+ reg = rd32(hw, I40E_GLPRT_MLFC(hw->port));
+ printf("mac local fault = %x\n", reg);
+}
+
#endif /* IXL_DEBUG_SYSCTL */
#ifdef PCI_IOV
@@ -5991,7 +6005,6 @@ ixl_vc_opcode_str(uint16_t op)
static int
ixl_vc_opcode_level(uint16_t opcode)
{
-
switch (opcode) {
case I40E_VIRTCHNL_OP_GET_STATS:
return (10);
@@ -6047,6 +6060,8 @@ ixl_vf_version_msg(struct ixl_pf *pf, st
return;
}
+ vf->version = ((struct i40e_virtchnl_version_info *)msg)->minor;
+
reply.major = I40E_VIRTCHNL_VERSION_MAJOR;
reply.minor = I40E_VIRTCHNL_VERSION_MINOR;
ixl_send_vf_msg(pf, vf, I40E_VIRTCHNL_OP_VERSION, I40E_SUCCESS, &reply,
@@ -6075,7 +6090,11 @@ ixl_vf_get_resources_msg(struct ixl_pf *
{
struct i40e_virtchnl_vf_resource reply;
- if (msg_size != 0) {
+ if ((vf->version == 0 && msg_size != 0) ||
+ (vf->version == 1 && msg_size != 4)) {
+ device_printf(pf->dev, "Invalid GET_VF_RESOURCES message size,"
+ " for VF version %d.%d\n", I40E_VIRTCHNL_VERSION_MAJOR,
+ vf->version);
i40e_send_vf_nack(pf, vf, I40E_VIRTCHNL_OP_GET_VF_RESOURCES,
I40E_ERR_PARAM);
return;
@@ -6083,7 +6102,12 @@ ixl_vf_get_resources_msg(struct ixl_pf *
bzero(&reply, sizeof(reply));
- reply.vf_offload_flags = I40E_VIRTCHNL_VF_OFFLOAD_L2;
+ if (vf->version == I40E_VIRTCHNL_VERSION_MINOR_NO_VF_CAPS)
+ reply.vf_offload_flags = I40E_VIRTCHNL_VF_OFFLOAD_L2 |
+ I40E_VIRTCHNL_VF_OFFLOAD_RSS_REG |
+ I40E_VIRTCHNL_VF_OFFLOAD_VLAN;
+ else
+ reply.vf_offload_flags = *(u32 *)msg;
reply.num_vsis = 1;
reply.num_queue_pairs = vf->vsi.num_queues;
@@ -6976,7 +7000,7 @@ ixl_iov_init(device_t dev, uint16_t num_
sysctl_ctx_init(&pf->vfs[i].ctx);
ret = i40e_aq_add_veb(hw, pf_vsi->uplink_seid, pf_vsi->seid,
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-head
mailing list