Author: erj
Date: Thu May 12 18:20:36 2016
New Revision: 299549
URL: https://svnweb.freebsd.org/changeset/base/299549

Log:
  ixl: Update to 1.4.12-k.
  
  Changes by author:
  
  Eric Joyner           ixl: Remove substitution of EACCES for EPERM when 
perrno is set on an nvmupdate command return.
  Eric Joyner           ixl: Print message when hardware sends GRST interrupt.
  Eric Joyner           ixl: Fix kernel panic when driver fails to initialize 
admin queue.
  Eric Joyner           ixl: Print out messages when a non-handled other 
interrupt occurs.
  Eric Joyner           ixl: Fix spaces in a couple messages.
  Eric Joyner           ixl: Add lock around nvmupd command entry point and 
reconvert EPERM errors to EACCES.
  Anjali Singhai Jain   i40e-shared: Make some changes in the nvm read code
  Shannon Nelson                i40e-shared: AQ Add Run PHY Activity struct
  Shannon Nelson                i40e-shared: AQ Add Geneve cloud tunnel type
  Shannon Nelson                i40e-shared: AQ Add external power class to get 
link status response struct
  Shannon Nelson                i40e-shared: AQ Add shared resource flags for 
macvlan filters
  Shannon Nelson                i40e-shared: AQ Add set_switch_config
  Shannon Nelson                i40e-shared: AQ Add VXLAN-GPE tunnel type for 
cloud filter and tunnel commands
  Shannon Nelson                i40e-shared: AQ thermal sensor control struct
  Shannon Nelson                i40e-shared: Bump AQ minor version to 1.5 for 
FVL5 features
  Shannon Nelson                i40e-shared: add a little more to an NVM update 
debug message
  Carolyn Wyborny               i40e-shared: Fix for PHY NVM interaction problem
  Eric Joyner           i40e-shared: Add prototypes for private NVM write 
functions
  Eric Joyner           ixl/ixlv: Remove unused define from ixl.h.
  Eric Joyner           ixl: Add handling of EMP reset for nvm update purposes.
  Eric Joyner           ixl: Move addition of device sysctls to separate 
function.
  Eric Joyner           ixl: Fix up a couple error messages in ixl_attach().
  Eric Joyner           ixl: Update the hardware resource allocation debug 
sysctl.
  
  Differential Revision:  https://reviews.freebsd.org/D6211
  Reviewed by:    sbruno, kmacy, jeffrey.e.pie...@intel.com
  MFC after:      2 weeks
  Sponsored by:   Intel Corporation

Modified:
  head/sys/dev/ixl/i40e_adminq_cmd.h
  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/ixl.h
  head/sys/dev/ixl/ixl_pf.h

Modified: head/sys/dev/ixl/i40e_adminq_cmd.h
==============================================================================
--- head/sys/dev/ixl/i40e_adminq_cmd.h  Thu May 12 18:20:18 2016        
(r299548)
+++ head/sys/dev/ixl/i40e_adminq_cmd.h  Thu May 12 18:20:36 2016        
(r299549)
@@ -42,7 +42,7 @@
  */
 
 #define I40E_FW_API_VERSION_MAJOR      0x0001
-#define I40E_FW_API_VERSION_MINOR      0x0004
+#define I40E_FW_API_VERSION_MINOR      0x0005
 
 struct i40e_aq_desc {
        __le16 flags;
@@ -153,6 +153,7 @@ enum i40e_admin_queue_opc {
        i40e_aqc_opc_remove_statistics          = 0x0202,
        i40e_aqc_opc_set_port_parameters        = 0x0203,
        i40e_aqc_opc_get_switch_resource_alloc  = 0x0204,
+       i40e_aqc_opc_set_switch_config          = 0x0205,
 
        i40e_aqc_opc_add_vsi                    = 0x0210,
        i40e_aqc_opc_update_vsi_parameters      = 0x0211,
@@ -228,6 +229,7 @@ enum i40e_admin_queue_opc {
        i40e_aqc_opc_get_phy_wol_caps           = 0x0621,
        i40e_aqc_opc_set_phy_debug              = 0x0622,
        i40e_aqc_opc_upload_ext_phy_fm          = 0x0625,
+       i40e_aqc_opc_run_phy_activity           = 0x0626,
 
        /* NVM commands */
        i40e_aqc_opc_nvm_read                   = 0x0701,
@@ -236,6 +238,7 @@ enum i40e_admin_queue_opc {
        i40e_aqc_opc_nvm_config_read            = 0x0704,
        i40e_aqc_opc_nvm_config_write           = 0x0705,
        i40e_aqc_opc_oem_post_update            = 0x0720,
+       i40e_aqc_opc_thermal_sensor             = 0x0721,
 
        /* virtualization commands */
        i40e_aqc_opc_send_msg_to_pf             = 0x0801,
@@ -686,6 +689,17 @@ struct i40e_aqc_switch_resource_alloc_el
 
 I40E_CHECK_STRUCT_LEN(0x10, i40e_aqc_switch_resource_alloc_element_resp);
 
+/* Set Switch Configuration (direct 0x0205) */
+struct i40e_aqc_set_switch_config {
+       __le16  flags;
+#define I40E_AQ_SET_SWITCH_CFG_PROMISC         0x0001
+#define I40E_AQ_SET_SWITCH_CFG_L2_FILTER       0x0002
+       __le16  valid_flags;
+       u8      reserved[12];
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_set_switch_config);
+
 /* Add VSI (indirect 0x0210)
  *    this indirect command uses struct i40e_aqc_vsi_properties_data
  *    as the indirect buffer (128 bytes)
@@ -908,7 +922,8 @@ struct i40e_aqc_add_veb {
                                        I40E_AQC_ADD_VEB_PORT_TYPE_SHIFT)
 #define I40E_AQC_ADD_VEB_PORT_TYPE_DEFAULT     0x2
 #define I40E_AQC_ADD_VEB_PORT_TYPE_DATA                0x4
-#define I40E_AQC_ADD_VEB_ENABLE_L2_FILTER      0x8
+#define I40E_AQC_ADD_VEB_ENABLE_L2_FILTER      0x8     /* deprecated */
+#define I40E_AQC_ADD_VEB_ENABLE_DISABLE_STATS  0x10
        u8      enable_tcs;
        u8      reserved[9];
 };
@@ -975,6 +990,7 @@ struct i40e_aqc_add_macvlan_element_data
 #define I40E_AQC_MACVLAN_ADD_HASH_MATCH                0x0002
 #define I40E_AQC_MACVLAN_ADD_IGNORE_VLAN       0x0004
 #define I40E_AQC_MACVLAN_ADD_TO_QUEUE          0x0008
+#define I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC    0x0010
        __le16  queue_number;
 #define I40E_AQC_MACVLAN_CMD_QUEUE_SHIFT       0
 #define I40E_AQC_MACVLAN_CMD_QUEUE_MASK                (0x7FF << \
@@ -1259,10 +1275,16 @@ struct i40e_aqc_add_remove_cloud_filters
 
 #define I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT              9
 #define I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK               0x1E00
-#define I40E_AQC_ADD_CLOUD_TNL_TYPE_XVLAN              0
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_VXLAN              0
 #define I40E_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC         1
-#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NGE                        2
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE             2
 #define I40E_AQC_ADD_CLOUD_TNL_TYPE_IP                 3
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_RESERVED           4
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_VXLAN_GPE          5
+
+#define I40E_AQC_ADD_CLOUD_FLAGS_SHARED_OUTER_MAC      0x2000
+#define I40E_AQC_ADD_CLOUD_FLAGS_SHARED_INNER_MAC      0x4000
+#define I40E_AQC_ADD_CLOUD_FLAGS_SHARED_OUTER_IP       0x8000
 
        __le32  tenant_id;
        u8      reserved[4];
@@ -1756,7 +1778,12 @@ struct i40e_aqc_get_link_status {
        u8      config;
 #define I40E_AQ_CONFIG_CRC_ENA         0x04
 #define I40E_AQ_CONFIG_PACING_MASK     0x78
-       u8      reserved[5];
+       u8      external_power_ability;
+#define I40E_AQ_LINK_POWER_CLASS_1     0x00
+#define I40E_AQ_LINK_POWER_CLASS_2     0x01
+#define I40E_AQ_LINK_POWER_CLASS_3     0x02
+#define I40E_AQ_LINK_POWER_CLASS_4     0x03
+       u8      reserved[4];
 };
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_get_link_status);
@@ -1824,6 +1851,18 @@ enum i40e_aq_phy_reg_type {
        I40E_AQC_PHY_REG_EXERNAL_MODULE = 0x3
 };
 
+/* Run PHY Activity (0x0626) */
+struct i40e_aqc_run_phy_activity {
+       __le16  activity_id;
+       u8      flags;
+       u8      reserved1;
+       __le32  control;
+       __le32  data;
+       u8      reserved2[4];
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_run_phy_activity);
+
 /* NVM Read command (indirect 0x0701)
  * NVM Erase commands (direct 0x0702)
  * NVM Update commands (indirect 0x0703)
@@ -1912,6 +1951,22 @@ struct i40e_aqc_nvm_oem_post_update_buff
 
 I40E_CHECK_STRUCT_LEN(0x28, i40e_aqc_nvm_oem_post_update_buffer);
 
+/* Thermal Sensor (indirect 0x0721)
+ *     read or set thermal sensor configs and values
+ *     takes a sensor and command specific data buffer, not detailed here
+ */
+struct i40e_aqc_thermal_sensor {
+       u8 sensor_action;
+#define I40E_AQ_THERMAL_SENSOR_READ_CONFIG     0
+#define I40E_AQ_THERMAL_SENSOR_SET_CONFIG      1
+#define I40E_AQ_THERMAL_SENSOR_READ_TEMP       2
+       u8 reserved[7];
+       __le32  addr_high;
+       __le32  addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_thermal_sensor);
+
 /* Send to PF command (indirect 0x0801) id is only used by PF
  * Send to VF command (indirect 0x0802) id is only used by PF
  * Send to Peer PF command (indirect 0x0803)
@@ -2184,6 +2239,7 @@ struct i40e_aqc_add_udp_tunnel {
 #define I40E_AQC_TUNNEL_TYPE_VXLAN     0x00
 #define I40E_AQC_TUNNEL_TYPE_NGE       0x01
 #define I40E_AQC_TUNNEL_TYPE_TEREDO    0x10
+#define I40E_AQC_TUNNEL_TYPE_VXLAN_GPE 0x11
        u8      reserved1[10];
 };
 

Modified: head/sys/dev/ixl/i40e_common.c
==============================================================================
--- head/sys/dev/ixl/i40e_common.c      Thu May 12 18:20:18 2016        
(r299548)
+++ head/sys/dev/ixl/i40e_common.c      Thu May 12 18:20:36 2016        
(r299549)
@@ -2393,14 +2393,15 @@ enum i40e_status_code i40e_update_link_i
        if (status)
                return status;
 
-       status = i40e_aq_get_phy_capabilities(hw, FALSE, false, &abilities,
-                                             NULL);
-       if (status)
-               return status;
-
-       memcpy(hw->phy.link_info.module_type, &abilities.module_type,
-               sizeof(hw->phy.link_info.module_type));
+       if (hw->phy.link_info.link_info & I40E_AQ_MEDIA_AVAILABLE) {
+               status = i40e_aq_get_phy_capabilities(hw, FALSE, false,
+                                                     &abilities, NULL);
+               if (status)
+                       return status;
 
+               memcpy(hw->phy.link_info.module_type, &abilities.module_type,
+                       sizeof(hw->phy.link_info.module_type));
+       }
        return status;
 }
 

Modified: head/sys/dev/ixl/i40e_nvm.c
==============================================================================
--- head/sys/dev/ixl/i40e_nvm.c Thu May 12 18:20:18 2016        (r299548)
+++ head/sys/dev/ixl/i40e_nvm.c Thu May 12 18:20:36 2016        (r299549)
@@ -208,7 +208,7 @@ static enum i40e_status_code i40e_poll_s
 }
 
 /**
- * i40e_read_nvm_word - Reads Shadow RAM
+ * i40e_read_nvm_word - Reads nvm word and acquire lock if necessary
  * @hw: pointer to the HW structure
  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
  * @data: word read from the Shadow RAM
@@ -225,6 +225,24 @@ enum i40e_status_code i40e_read_nvm_word
 }
 
 /**
+ * __i40e_read_nvm_word - Reads nvm word, assumes caller does the locking
+ * @hw: pointer to the HW structure
+ * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
+ * @data: word read from the Shadow RAM
+ *
+ * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
+ **/
+enum i40e_status_code __i40e_read_nvm_word(struct i40e_hw *hw,
+                                          u16 offset,
+                                          u16 *data)
+{
+       enum i40e_status_code ret_code = I40E_SUCCESS;
+
+       ret_code = i40e_read_nvm_word_srctl(hw, offset, data);
+       return ret_code;
+}
+
+/**
  * i40e_read_nvm_word_srctl - Reads Shadow RAM via SRCTL register
  * @hw: pointer to the HW structure
  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
@@ -296,7 +314,28 @@ enum i40e_status_code i40e_read_nvm_word
 }
 
 /**
- * i40e_read_nvm_buffer - Reads Shadow RAM buffer
+ * __i40e_read_nvm_buffer - Reads nvm buffer, caller must acquire lock
+ * @hw: pointer to the HW structure
+ * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
+ * @words: (in) number of words to read; (out) number of words actually read
+ * @data: words read from the Shadow RAM
+ *
+ * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
+ * method. The buffer read is preceded by the NVM ownership take
+ * and followed by the release.
+ **/
+enum i40e_status_code __i40e_read_nvm_buffer(struct i40e_hw *hw,
+                                            u16 offset,
+                                            u16 *words, u16 *data)
+{
+       enum i40e_status_code ret_code = I40E_SUCCESS;
+
+       ret_code = i40e_read_nvm_buffer_srctl(hw, offset, words, data);
+       return ret_code;
+}
+
+/**
+ * i40e_read_nvm_buffer - Reads Shadow RAM buffer and acuire lock if necessary
  * @hw: pointer to the HW structure
  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
  * @words: (in) number of words to read; (out) number of words actually read
@@ -506,7 +545,7 @@ enum i40e_status_code i40e_write_nvm_aq(
 }
 
 /**
- * i40e_write_nvm_word - Writes Shadow RAM word
+ * __i40e_write_nvm_word - Writes Shadow RAM word
  * @hw: pointer to the HW structure
  * @offset: offset of the Shadow RAM word to write
  * @data: word to write to the Shadow RAM
@@ -516,8 +555,8 @@ enum i40e_status_code i40e_write_nvm_aq(
  * reception) by caller. To commit SR to NVM update checksum function
  * should be called.
  **/
-enum i40e_status_code i40e_write_nvm_word(struct i40e_hw *hw, u32 offset,
-                                         void *data)
+enum i40e_status_code __i40e_write_nvm_word(struct i40e_hw *hw, u32 offset,
+                                           void *data)
 {
        DEBUGFUNC("i40e_write_nvm_word");
 
@@ -528,7 +567,7 @@ enum i40e_status_code i40e_write_nvm_wor
 }
 
 /**
- * i40e_write_nvm_buffer - Writes Shadow RAM buffer
+ * __i40e_write_nvm_buffer - Writes Shadow RAM buffer
  * @hw: pointer to the HW structure
  * @module_pointer: module pointer location in words from the NVM beginning
  * @offset: offset of the Shadow RAM buffer to write
@@ -540,9 +579,9 @@ enum i40e_status_code i40e_write_nvm_wor
  * on ARQ completion event reception by caller. To commit SR to NVM update
  * checksum function should be called.
  **/
-enum i40e_status_code i40e_write_nvm_buffer(struct i40e_hw *hw,
-                                           u8 module_pointer, u32 offset,
-                                           u16 words, void *data)
+enum i40e_status_code __i40e_write_nvm_buffer(struct i40e_hw *hw,
+                                             u8 module_pointer, u32 offset,
+                                             u16 words, void *data)
 {
        __le16 *le_word_ptr = (__le16 *)data;
        u16 *word_ptr = (u16 *)data;
@@ -589,15 +628,17 @@ enum i40e_status_code i40e_calc_nvm_chec
        data = (u16 *)vmem.va;
 
        /* read pointer to VPD area */
-       ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module);
+       ret_code = __i40e_read_nvm_word(hw, I40E_SR_VPD_PTR,
+                                       &vpd_module);
        if (ret_code != I40E_SUCCESS) {
                ret_code = I40E_ERR_NVM_CHECKSUM;
                goto i40e_calc_nvm_checksum_exit;
        }
 
        /* read pointer to PCIe Alt Auto-load module */
-       ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
-                                     &pcie_alt_module);
+       ret_code = __i40e_read_nvm_word(hw,
+                                       I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
+                                       &pcie_alt_module);
        if (ret_code != I40E_SUCCESS) {
                ret_code = I40E_ERR_NVM_CHECKSUM;
                goto i40e_calc_nvm_checksum_exit;
@@ -611,7 +652,7 @@ enum i40e_status_code i40e_calc_nvm_chec
                if ((i % I40E_SR_SECTOR_SIZE_IN_WORDS) == 0) {
                        u16 words = I40E_SR_SECTOR_SIZE_IN_WORDS;
 
-                       ret_code = i40e_read_nvm_buffer(hw, i, &words, data);
+                       ret_code = __i40e_read_nvm_buffer(hw, i, &words, data);
                        if (ret_code != I40E_SUCCESS) {
                                ret_code = I40E_ERR_NVM_CHECKSUM;
                                goto i40e_calc_nvm_checksum_exit;
@@ -686,13 +727,18 @@ enum i40e_status_code i40e_validate_nvm_
 
        DEBUGFUNC("i40e_validate_nvm_checksum");
 
-       ret_code = i40e_calc_nvm_checksum(hw, &checksum_local);
-       if (ret_code != I40E_SUCCESS)
+       if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE)
+               ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
+       if (!ret_code) {
+               ret_code = i40e_calc_nvm_checksum(hw, &checksum_local);
+               if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE)
+                       i40e_release_nvm(hw);
+               if (ret_code != I40E_SUCCESS)
+                       goto i40e_validate_nvm_checksum_exit;
+       } else {
                goto i40e_validate_nvm_checksum_exit;
+       }
 
-       /* Do not use i40e_read_nvm_word() because we do not want to take
-        * the synchronization semaphores twice here.
-        */
        i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
 
        /* Verify read checksum from EEPROM is the same as
@@ -788,10 +834,11 @@ enum i40e_status_code i40e_nvmupd_comman
        /* early check for status command and debug msgs */
        upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
 
-       i40e_debug(hw, I40E_DEBUG_NVM, "%s state %d nvm_release_on_hold %d\n",
+       i40e_debug(hw, I40E_DEBUG_NVM, "%s state %d nvm_release_on_hold %d cmd 
0x%08x config 0x%08x offset 0x%08x data_size 0x%08x\n",
                   i40e_nvm_update_state_str[upd_cmd],
                   hw->nvmupd_state,
-                  hw->aq.nvm_release_on_done);
+                  hw->aq.nvm_release_on_done,
+                  cmd->command, cmd->config, cmd->offset, cmd->data_size);
 
        if (upd_cmd == I40E_NVMUPD_INVALID) {
                *perrno = -EFAULT;
@@ -1059,6 +1106,7 @@ retry:
                break;
 
        case I40E_NVMUPD_CSUM_CON:
+               /* Assumes the caller has acquired the nvm */
                status = i40e_update_nvm_checksum(hw);
                if (status) {
                        *perrno = hw->aq.asq_last_status ?
@@ -1072,6 +1120,7 @@ retry:
                break;
 
        case I40E_NVMUPD_CSUM_LCB:
+               /* Assumes the caller has acquired the nvm */
                status = i40e_update_nvm_checksum(hw);
                if (status) {
                        *perrno = hw->aq.asq_last_status ?

Modified: head/sys/dev/ixl/i40e_prototype.h
==============================================================================
--- head/sys/dev/ixl/i40e_prototype.h   Thu May 12 18:20:18 2016        
(r299548)
+++ head/sys/dev/ixl/i40e_prototype.h   Thu May 12 18:20:36 2016        
(r299549)
@@ -413,9 +413,13 @@ enum i40e_status_code i40e_read_nvm_buff
 enum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module,
                                        u32 offset, u16 words, void *data,
                                        bool last_command);
-enum i40e_status_code i40e_write_nvm_word(struct i40e_hw *hw, u32 offset,
+enum i40e_status_code __i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
+                                          u16 *data);
+enum i40e_status_code __i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
+                                            u16 *words, u16 *data);
+enum i40e_status_code __i40e_write_nvm_word(struct i40e_hw *hw, u32 offset,
                                          void *data);
-enum i40e_status_code i40e_write_nvm_buffer(struct i40e_hw *hw, u8 module,
+enum i40e_status_code __i40e_write_nvm_buffer(struct i40e_hw *hw, u8 module,
                                            u32 offset, u16 words, void *data);
 enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 
*checksum);
 enum i40e_status_code i40e_update_nvm_checksum(struct i40e_hw *hw);

Modified: head/sys/dev/ixl/if_ixl.c
==============================================================================
--- head/sys/dev/ixl/if_ixl.c   Thu May 12 18:20:18 2016        (r299548)
+++ head/sys/dev/ixl/if_ixl.c   Thu May 12 18:20:36 2016        (r299549)
@@ -48,7 +48,7 @@
 /*********************************************************************
  *  Driver version
  *********************************************************************/
-char ixl_driver_version[] = "1.4.9-k";
+char ixl_driver_version[] = "1.4.12-k";
 
 /*********************************************************************
  *  PCI Device ID Table
@@ -154,11 +154,25 @@ static struct ixl_mac_filter *
 static void    ixl_add_mc_filter(struct ixl_vsi *, u8 *);
 static void    ixl_free_mac_filters(struct ixl_vsi *vsi);
 
+/* Sysctls*/
+static void    ixl_add_device_sysctls(struct ixl_pf *);
 
-/* Sysctl debug interface */
 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_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);
+static int     ixl_sysctl_hw_res_alloc(SYSCTL_HANDLER_ARGS);
+static int     ixl_sysctl_switch_config(SYSCTL_HANDLER_ARGS);
+#endif
+
 /* The MSI/X Interrupt handlers */
 static void    ixl_intr(void *);
 static void    ixl_msix_que(void *);
@@ -168,12 +182,6 @@ static void        ixl_handle_mdd_event(struct 
 /* Deferred interrupt tasklets */
 static void    ixl_do_adminq(void *, int);
 
-/* Sysctl handlers */
-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);
-
 /* Statistics */
 static void     ixl_add_hw_stats(struct ixl_pf *);
 static void    ixl_add_sysctls_mac_stats(struct sysctl_ctx_list *,
@@ -193,14 +201,6 @@ static void        ixl_stat_update32(struct i40
 /* NVM update */
 static int     ixl_handle_nvmupd_cmd(struct ixl_pf *, struct ifdrv *);
 
-#ifdef IXL_DEBUG_SYSCTL
-static int     ixl_sysctl_link_status(SYSCTL_HANDLER_ARGS);
-static int     ixl_sysctl_phy_abilities(SYSCTL_HANDLER_ARGS);
-static int     ixl_sysctl_sw_filter_list(SYSCTL_HANDLER_ARGS);
-static int     ixl_sysctl_hw_res_alloc(SYSCTL_HANDLER_ARGS);
-static int     ixl_sysctl_switch_config(SYSCTL_HANDLER_ARGS);
-#endif
-
 
 #ifdef PCI_IOV
 static int     ixl_adminq_err_to_errno(enum i40e_admin_queue_err err);
@@ -440,90 +440,6 @@ ixl_attach(device_t dev)
        /* Set up the timer callout */
        callout_init_mtx(&pf->timer, &pf->pf_mtx, 0);
 
-       /* Set up sysctls */
-       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-           OID_AUTO, "fc", CTLTYPE_INT | CTLFLAG_RW,
-           pf, 0, ixl_set_flowcntl, "I", "Flow Control");
-
-       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-           OID_AUTO, "advertise_speed", CTLTYPE_INT | CTLFLAG_RW,
-           pf, 0, ixl_set_advertise, "I", "Advertised Speed");
-
-       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-           OID_AUTO, "current_speed", CTLTYPE_STRING | CTLFLAG_RD,
-           pf, 0, ixl_current_speed, "A", "Current Port Speed");
-
-       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-           OID_AUTO, "fw_version", CTLTYPE_STRING | CTLFLAG_RD,
-           pf, 0, ixl_sysctl_show_fw, "A", "Firmware version");
-
-       SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
-           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-           OID_AUTO, "rx_itr", CTLFLAG_RW,
-           &ixl_rx_itr, IXL_ITR_8K, "RX ITR");
-
-       SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
-           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-           OID_AUTO, "dynamic_rx_itr", CTLFLAG_RW,
-           &ixl_dynamic_rx_itr, 0, "Dynamic RX ITR");
-
-       SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
-           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-           OID_AUTO, "tx_itr", CTLFLAG_RW,
-           &ixl_tx_itr, IXL_ITR_4K, "TX ITR");
-
-       SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
-           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-           OID_AUTO, "dynamic_tx_itr", CTLFLAG_RW,
-           &ixl_dynamic_tx_itr, 0, "Dynamic TX ITR");
-
-#ifdef IXL_DEBUG_SYSCTL
-       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-           OID_AUTO, "debug", CTLTYPE_INT|CTLFLAG_RW, pf, 0,
-           ixl_debug_info, "I", "Debug Information");
-
-       /* Debug shared-code message level */
-       SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
-           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-           OID_AUTO, "debug_mask", CTLFLAG_RW,
-           &pf->hw.debug_mask, 0, "Debug Message Level");
-
-       SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
-           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-           OID_AUTO, "vc_debug_level", CTLFLAG_RW, &pf->vc_debug_lvl,
-           0, "PF/VF Virtual Channel debug level");
-
-       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-           OID_AUTO, "link_status", CTLTYPE_STRING | CTLFLAG_RD,
-           pf, 0, ixl_sysctl_link_status, "A", "Current Link Status");
-
-       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-           OID_AUTO, "phy_abilities", CTLTYPE_STRING | CTLFLAG_RD,
-           pf, 0, ixl_sysctl_phy_abilities, "A", "PHY Abilities");
-
-       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-           OID_AUTO, "filter_list", CTLTYPE_STRING | CTLFLAG_RD,
-           pf, 0, ixl_sysctl_sw_filter_list, "A", "SW Filter List");
-
-       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
-           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-           OID_AUTO, "hw_res_alloc", CTLTYPE_STRING | CTLFLAG_RD,
-           pf, 0, ixl_sysctl_hw_res_alloc, "A", "HW Resource Allocation");
-
-       SYSCTL_ADD_PROC(device_get_sysctl_ctx(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");
-#endif
-
        /* Save off the PCI information */
        hw->vendor_id = pci_get_vendor(dev);
        hw->device_id = pci_get_device(dev);
@@ -549,7 +465,7 @@ ixl_attach(device_t dev)
        i40e_clear_hw(hw);
        error = i40e_pf_reset(hw);
        if (error) {
-               device_printf(dev, "PF reset failure %x\n", error);
+               device_printf(dev, "PF reset failure %d\n", error);
                error = EIO;
                goto err_out;
        }
@@ -560,24 +476,35 @@ ixl_attach(device_t dev)
        hw->aq.arq_buf_size = IXL_AQ_BUFSZ;
        hw->aq.asq_buf_size = IXL_AQ_BUFSZ;
 
+       /* Initialize mac filter list for VSI */
+       SLIST_INIT(&vsi->ftl);
+
        /* Initialize the shared code */
        error = i40e_init_shared_code(hw);
        if (error) {
-               device_printf(dev, "Unable to initialize the shared code\n");
+               device_printf(dev, "Unable to initialize shared code, error 
%d\n",
+                   error);
                error = EIO;
                goto err_out;
        }
 
        /* Set up the admin queue */
        error = i40e_init_adminq(hw);
-       if (error) {
+       if (error != 0 && error != I40E_ERR_FIRMWARE_API_VERSION) {
+               device_printf(dev, "Unable to initialize Admin Queue, error 
%d\n",
+                   error);
+               error = EIO;
+               goto err_out;
+       }
+       device_printf(dev, "%s\n", ixl_fw_version_str(hw));
+       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"
                    "You must install the most recent version of "
-                   " the network driver.\n");
+                   "the network driver.\n");
+               error = EIO;
                goto err_out;
        }
-       device_printf(dev, "%s\n", ixl_fw_version_str(hw));
 
         if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
            hw->aq.api_min_ver > I40E_FW_API_VERSION_MINOR)
@@ -633,9 +560,6 @@ ixl_attach(device_t dev)
                goto err_mac_hmc;
        }
 
-       /* Initialize mac filter list for VSI */
-       SLIST_INIT(&vsi->ftl);
-
        if (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
            (hw->aq.fw_maj_ver < 4)) {
                i40e_msec_delay(75);
@@ -680,7 +604,9 @@ ixl_attach(device_t dev)
        /* Initialize taskqueues */
        ixl_init_taskqueues(pf);
 
-       /* Initialize statistics */
+       /* Initialize statistics & add sysctls */
+       ixl_add_device_sysctls(pf);
+
        ixl_pf_reset_stats(pf);
        ixl_update_stats_counters(pf);
        ixl_add_hw_stats(pf);
@@ -1558,7 +1484,8 @@ ixl_msix_adminq(void *arg)
 {
        struct ixl_pf   *pf = arg;
        struct i40e_hw  *hw = &pf->hw;
-       u32             reg, mask;
+       u32             reg, mask, rstat_reg;
+       bool            do_task = FALSE;
 
        ++pf->admin_irq;
 
@@ -1566,12 +1493,52 @@ ixl_msix_adminq(void *arg)
        mask = rd32(hw, I40E_PFINT_ICR0_ENA);
 
        /* Check on the cause */
-       if (reg & I40E_PFINT_ICR0_ADMINQ_MASK)
-               mask &= ~I40E_PFINT_ICR0_ENA_ADMINQ_MASK;
+       if (reg & I40E_PFINT_ICR0_ADMINQ_MASK) {
+               mask &= ~I40E_PFINT_ICR0_ADMINQ_MASK;
+               do_task = TRUE;
+       }
 
        if (reg & I40E_PFINT_ICR0_MAL_DETECT_MASK) {
                ixl_handle_mdd_event(pf);
-               mask &= ~I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK;
+               mask &= ~I40E_PFINT_ICR0_MAL_DETECT_MASK;
+       }
+
+       if (reg & I40E_PFINT_ICR0_GRST_MASK) {
+               device_printf(pf->dev, "Reset Requested!\n");
+               rstat_reg = rd32(hw, I40E_GLGEN_RSTAT);
+               rstat_reg = (rstat_reg & I40E_GLGEN_RSTAT_RESET_TYPE_MASK)
+                   >> I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT;
+               device_printf(pf->dev, "Reset type: ");
+               switch (rstat_reg) {
+               /* These others might be handled similarly to an EMPR reset */
+               case I40E_RESET_CORER:
+                       printf("CORER\n");
+                       break;
+               case I40E_RESET_GLOBR:
+                       printf("GLOBR\n");
+                       break;
+               case I40E_RESET_EMPR:
+                       printf("EMPR\n");
+                       atomic_set_int(&pf->state, IXL_PF_STATE_EMPR_RESETTING);
+                       break;
+               default:
+                       printf("?\n");
+                       break;
+               }
+               // overload admin queue task to check reset progress?
+               do_task = TRUE;
+       }
+
+       if (reg & I40E_PFINT_ICR0_ECC_ERR_MASK) {
+               device_printf(pf->dev, "ECC Error detected!\n");
+       }
+
+       if (reg & I40E_PFINT_ICR0_HMC_ERR_MASK) {
+               device_printf(pf->dev, "HMC Error detected!\n");
+       }
+
+       if (reg & I40E_PFINT_ICR0_PCI_EXCEPTION_MASK) {
+               device_printf(pf->dev, "PCI Exception detected!\n");
        }
 
 #ifdef PCI_IOV
@@ -1585,8 +1552,8 @@ ixl_msix_adminq(void *arg)
        reg = reg | I40E_PFINT_DYN_CTL0_CLEARPBA_MASK;
        wr32(hw, I40E_PFINT_DYN_CTL0, reg);
 
-       taskqueue_enqueue(pf->tq, &pf->adminq);
-       return;
+       if (do_task)
+               taskqueue_enqueue(pf->tq, &pf->adminq);
 }
 
 /*********************************************************************
@@ -2330,7 +2297,7 @@ ixl_init_msix(struct ixl_pf *pf)
                if (!pf->msix_mem) {
                /* May not be enabled */
                device_printf(pf->dev,
-                   "Unable to map MSIX table \n");
+                   "Unable to map MSIX table\n");
                goto msi;
        }
 
@@ -2435,7 +2402,7 @@ ixl_configure_msix(struct ixl_pf *pf)
 
        reg = I40E_PFINT_ICR0_ENA_ECC_ERR_MASK |
            I40E_PFINT_ICR0_ENA_GRST_MASK |
-           I40E_PFINT_ICR0_HMC_ERR_MASK |
+           I40E_PFINT_ICR0_ENA_HMC_ERR_MASK |
            I40E_PFINT_ICR0_ENA_ADMINQ_MASK |
            I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK |
            I40E_PFINT_ICR0_ENA_VFLR_MASK |
@@ -2583,7 +2550,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: memory\n");
                return (ENXIO);
        }
 
@@ -3128,6 +3095,9 @@ ixl_free_vsi(struct ixl_vsi *vsi)
        struct ixl_queue        *que = vsi->queues;
 
        /* Free station queues */
+       if (!vsi->queues)
+               goto free_filters;
+
        for (int i = 0; i < vsi->num_queues; i++, que++) {
                struct tx_ring *txr = &que->txr;
                struct rx_ring *rxr = &que->rxr;
@@ -3153,6 +3123,7 @@ ixl_free_vsi(struct ixl_vsi *vsi)
        }
        free(vsi->queues, M_DEVBUF);
 
+free_filters:
        /* Free VSI filter list */
        ixl_free_mac_filters(vsi);
 }
@@ -4538,9 +4509,34 @@ ixl_do_adminq(void *context, int pending
        struct i40e_arq_event_info      event;
        i40e_status                     ret;
        device_t                        dev = pf->dev;
-       u32                             loop = 0;
+       u32                             reg, loop = 0;
        u16                             opcode, result;
 
+       // XXX: Possibly inappropriate overload
+       if (pf->state & IXL_PF_STATE_EMPR_RESETTING) {
+               int count = 0;
+               // ERJ: Typically finishes within 3-4 seconds
+               while (count++ < 100) {
+                       reg = rd32(hw, I40E_GLGEN_RSTAT);
+                       reg = reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK;
+                       if (reg) {
+                               i40e_msec_delay(100);
+                       } else {
+                               break;
+                       }
+               }
+               device_printf(dev, "EMPR reset wait count: %d\n", count);
+
+               device_printf(dev, "Rebuilding HW structs...\n");
+               // XXX: I feel like this could cause a kernel panic some time 
in the future
+               ixl_stop(pf);
+               ixl_init(pf);
+
+               atomic_clear_int(&pf->state, IXL_PF_STATE_EMPR_RESETTING);
+               return;
+       }
+
+       // Actually do Admin Queue handling
        event.buf_len = IXL_AQ_BUF_SZ;
        event.msg_buf = malloc(event.buf_len,
            M_DEVBUF, M_NOWAIT | M_ZERO);
@@ -4830,6 +4826,96 @@ ixl_stat_update32(struct i40e_hw *hw, u3
                *stat = (u32)((new_data + ((u64)1 << 32)) - *offset);
 }
 
+static void
+ixl_add_device_sysctls(struct ixl_pf *pf)
+{
+       device_t dev = pf->dev;
+
+       /* Set up sysctls */
+       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+           OID_AUTO, "fc", CTLTYPE_INT | CTLFLAG_RW,
+           pf, 0, ixl_set_flowcntl, "I", "Flow Control");
+
+       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+           OID_AUTO, "advertise_speed", CTLTYPE_INT | CTLFLAG_RW,
+           pf, 0, ixl_set_advertise, "I", "Advertised Speed");
+
+       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+           OID_AUTO, "current_speed", CTLTYPE_STRING | CTLFLAG_RD,
+           pf, 0, ixl_current_speed, "A", "Current Port Speed");
+
+       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+           OID_AUTO, "fw_version", CTLTYPE_STRING | CTLFLAG_RD,
+           pf, 0, ixl_sysctl_show_fw, "A", "Firmware version");
+
+       SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+           OID_AUTO, "rx_itr", CTLFLAG_RW,
+           &ixl_rx_itr, IXL_ITR_8K, "RX ITR");
+
+       SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+           OID_AUTO, "dynamic_rx_itr", CTLFLAG_RW,
+           &ixl_dynamic_rx_itr, 0, "Dynamic RX ITR");
+
+       SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+           OID_AUTO, "tx_itr", CTLFLAG_RW,
+           &ixl_tx_itr, IXL_ITR_4K, "TX ITR");
+
+       SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+           OID_AUTO, "dynamic_tx_itr", CTLFLAG_RW,
+           &ixl_dynamic_tx_itr, 0, "Dynamic TX ITR");
+
+#ifdef IXL_DEBUG_SYSCTL
+       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+           OID_AUTO, "debug", CTLTYPE_INT|CTLFLAG_RW, pf, 0,
+           ixl_debug_info, "I", "Debug Information");
+
+       /* Debug shared-code message level */
+       SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+           OID_AUTO, "debug_mask", CTLFLAG_RW,
+           &pf->hw.debug_mask, 0, "Debug Message Level");
+
+       SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+           OID_AUTO, "vc_debug_level", CTLFLAG_RW, &pf->vc_debug_lvl,
+           0, "PF/VF Virtual Channel debug level");
+
+       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+           OID_AUTO, "link_status", CTLTYPE_STRING | CTLFLAG_RD,
+           pf, 0, ixl_sysctl_link_status, "A", "Current Link Status");
+
+       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+           OID_AUTO, "phy_abilities", CTLTYPE_STRING | CTLFLAG_RD,
+           pf, 0, ixl_sysctl_phy_abilities, "A", "PHY Abilities");
+
+       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+           OID_AUTO, "filter_list", CTLTYPE_STRING | CTLFLAG_RD,
+           pf, 0, ixl_sysctl_sw_filter_list, "A", "SW Filter List");
+
+       SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+           SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+           OID_AUTO, "hw_res_alloc", CTLTYPE_STRING | CTLFLAG_RD,
+           pf, 0, ixl_sysctl_hw_res_alloc, "A", "HW Resource Allocation");
+
+       SYSCTL_ADD_PROC(device_get_sysctl_ctx(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");
+#endif
+}
+
 /*
 ** Set flow control using sysctl:
 **     0 - off
@@ -5185,12 +5271,32 @@ ixl_handle_nvmupd_cmd(struct ixl_pf *pf,
 
        nvma = (struct i40e_nvm_access *)ifd->ifd_data;
 
-       status = i40e_nvmupd_command(hw, nvma, nvma->data, &perrno);
+       if (pf->state & IXL_PF_STATE_EMPR_RESETTING) {
+               int count = 0;
+               while (count++ < 100) {
+                       i40e_msec_delay(100);
+                       if (!(pf->state & IXL_PF_STATE_EMPR_RESETTING))
+                               break;
+               }
+               // device_printf(dev, "ioctl EMPR reset wait count %d\n", 
count);
+       }
+
+       if (!(pf->state & IXL_PF_STATE_EMPR_RESETTING)) {
+               IXL_PF_LOCK(pf);
+               status = i40e_nvmupd_command(hw, nvma, nvma->data, &perrno);
+               IXL_PF_UNLOCK(pf);
+       } else {
+               perrno = -EBUSY;
+       }
+
        if (status)
                device_printf(dev, "i40e_nvmupd_command status %d, perrno %d\n",
                    status, perrno);
 
-       /* Convert EPERM error code for tools */
+       /*
+        * -EPERM is actually ERESTART, which the kernel interprets as it 
needing
+        * to run this ioctl again. So use -EACCES for -EPERM instead.
+        */
        if (perrno == -EPERM)
                return (-EACCES);
        else
@@ -5315,6 +5421,41 @@ ixl_res_alloc_cmp(const void *a, const v
        return ((int)one->resource_type - (int)two->resource_type);
 }
 
+/*
+ * Longest string length: 25 
+ */
+static char *
+ixl_switch_res_type_string(u8 type)
+{
+       static char * ixl_switch_res_type_strings[0x14] = {
+               "VEB",
+               "VSI",
+               "Perfect Match MAC address",
+               "S-tag",
+               "(Reserved)",
+               "Multicast hash entry",
+               "Unicast hash entry",
+               "VLAN",
+               "VSI List entry",
+               "(Reserved)",
+               "VLAN Statistic Pool",
+               "Mirror Rule",
+               "Queue Set",
+               "Inner VLAN Forward filter",
+               "(Reserved)",
+               "Inner MAC",
+               "IP",
+               "GRE/VN1 Key",
+               "VN2 Key",
+               "Tunneling Port"
+       };
+
+       if (type < 0x14)
+               return ixl_switch_res_type_strings[type];
+       else
+               return "(Reserved)";
+}
+
 static int
 ixl_sysctl_hw_res_alloc(SYSCTL_HANDLER_ARGS)
 {
@@ -5354,12 +5495,20 @@ ixl_sysctl_hw_res_alloc(SYSCTL_HANDLER_A
        sbuf_cat(buf, "\n");
        sbuf_printf(buf, "# of entries: %d\n", num_entries);
        sbuf_printf(buf,
+#if 0
            "Type | Guaranteed | Total | Used   | Un-allocated\n"
            "     | (this)     | (all) | (this) | (all)       \n");
+#endif
+           "                     Type | Guaranteed | Total | Used   | 
Un-allocated\n"
+           "                          | (this)     | (all) | (this) | (all)    
   \n");
        for (int i = 0; i < num_entries; i++) {
                sbuf_printf(buf,
+#if 0
                    "%#4x | %10d   %5d   %6d   %12d",
                    resp[i].resource_type,
+#endif
+                   "%25s | %10d   %5d   %6d   %12d",
+                   ixl_switch_res_type_string(resp[i].resource_type),
                    resp[i].guaranteed,
                    resp[i].total,
                    resp[i].used,
@@ -5379,36 +5528,48 @@ ixl_sysctl_hw_res_alloc(SYSCTL_HANDLER_A
 /*
 ** Caller must init and delete sbuf; this function will clear and
 ** finish it for caller.
+**
+** XXX: Cannot use the SEID for this, since there is no longer a 
+** fixed mapping between SEID and element type.
 */
 static char *
-ixl_switch_element_string(struct sbuf *s, u16 seid, bool uplink)
+ixl_switch_element_string(struct sbuf *s,
+    struct i40e_aqc_switch_config_element_resp *element)
 {
        sbuf_clear(s);
 
-       if (seid == 0 && uplink)
-               sbuf_cat(s, "Network");
-       else if (seid == 0)
-               sbuf_cat(s, "Host");
-       else if (seid == 1)
+       switch (element->element_type) {
+       case I40E_AQ_SW_ELEM_TYPE_MAC:
+               sbuf_printf(s, "MAC %3d", element->element_info);
+               break;
+       case I40E_AQ_SW_ELEM_TYPE_PF:
+               sbuf_printf(s, "PF  %3d", element->element_info);
+               break;
+       case I40E_AQ_SW_ELEM_TYPE_VF:
+               sbuf_printf(s, "VF  %3d", element->element_info);
+               break;
+       case I40E_AQ_SW_ELEM_TYPE_EMP:

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to