]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net...
authorDavid S. Miller <davem@davemloft.net>
Wed, 8 Jan 2014 06:11:19 +0000 (01:11 -0500)
committerDavid S. Miller <davem@davemloft.net>
Wed, 8 Jan 2014 06:11:19 +0000 (01:11 -0500)
Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates

This series contains updates to i40e only.

Anjali adds more functionality to debugfs to assist development and
testing of admin queue commands.

Greg makes sure broadcast promiscuous is disabled by default, otherwise
VLAN tagged packets out of the assigned VLAN domain are received.  Also
provides a fix when the 8021q driver is loaded, so that VLAN 0 tagged
packets are accepted so that upper layers can interpret the priority
bits. Then provides a fix to let the VF to request the PF to set its
already assigned MAC address without generating an error.  Greg also
adds helper functions to enable or disable internal switch loopback
when VFs are created or destroyed via the sysfs interface.

Shannon provides most of the changes, where he adds code to ensure
that the hardware waits to make sure that the firmware is ready as well
after reset.  Also updates the code to use the new features in the
firmware.  Provides a fix while in MFP mode where resources are
reduced, so use a smaller range of test registers than when in SFP mode.
Moves the PF ID initialization code to earlier in the driver
initialization function since a few operations need the information
before the first PF reset is called.  Shannon adds a check for MAC
type before reading anything from the registers to ensure we dealing
with the correct MAC type.  Then reworks Shadow RAM read word/buffer
functions as to not block whole NVM resources for SR read operations.

Mitch lastly provides a fix to correctly setup ARQ descriptors in
the cleanup code.

Catherine bumps the driver version due to all the recent changes.

v2:
 - Added blank lines after local variable declarations to patch 01
   as suggested by David Miller
 - Used the suggested memset() line in patch 15 as suggested by David
   Miller
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/intel/i40e/i40e_adminq.c
drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
drivers/net/ethernet/intel/i40e/i40e_common.c
drivers/net/ethernet/intel/i40e/i40e_debugfs.c
drivers/net/ethernet/intel/i40e/i40e_diag.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_nvm.c
drivers/net/ethernet/intel/i40e/i40e_register.h
drivers/net/ethernet/intel/i40e/i40e_type.h
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c

index f75b5733f34c77474e6f699f36e1e744d347b558..2b320841a1082f5784767bbb025bccc7eed14f5e 100644 (file)
@@ -572,16 +572,18 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
        if (ret_code != I40E_SUCCESS)
                goto init_adminq_free_arq;
 
-       if (hw->aq.api_maj_ver != I40E_FW_API_VERSION_MAJOR ||
-           hw->aq.api_min_ver != I40E_FW_API_VERSION_MINOR) {
-               ret_code = I40E_ERR_FIRMWARE_API_VERSION;
-               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_EETRACK_LO, &eetrack_lo);
        i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_HI, &eetrack_hi);
        hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo;
 
+       if (hw->aq.api_maj_ver != I40E_FW_API_VERSION_MAJOR ||
+           hw->aq.api_min_ver > I40E_FW_API_VERSION_MINOR) {
+               ret_code = I40E_ERR_FIRMWARE_API_VERSION;
+               goto init_adminq_free_arq;
+       }
+
        ret_code = i40e_aq_set_hmc_resource_profile(hw,
                                                    I40E_HMC_PROFILE_DEFAULT,
                                                    0,
@@ -670,7 +672,7 @@ static bool i40e_asq_done(struct i40e_hw *hw)
        /* AQ designers suggest use of head for better
         * timing reliability than DD bit
         */
-       return (rd32(hw, hw->aq.asq.head) == hw->aq.asq.next_to_use);
+       return rd32(hw, hw->aq.asq.head) == hw->aq.asq.next_to_use;
 
 }
 
@@ -680,7 +682,7 @@ static bool i40e_asq_done(struct i40e_hw *hw)
  *  @desc: prefilled descriptor describing the command (non DMA mem)
  *  @buff: buffer to use for indirect commands
  *  @buff_size: size of buffer for indirect commands
- *  @opaque: pointer to info to be used in async cleanup
+ *  @cmd_details: pointer to command details structure
  *
  *  This is the main send command driver routine for the Admin Queue send
  *  queue.  It runs the queue, cleans the queue, etc
@@ -931,6 +933,11 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
         * size
         */
        bi = &hw->aq.arq.r.arq_bi[ntc];
+       memset((void *)desc, 0, sizeof(struct i40e_aq_desc));
+
+       desc->flags = cpu_to_le16(I40E_AQ_FLAG_BUF);
+       if (hw->aq.arq_buf_size > I40E_AQ_LARGE_BUF)
+               desc->flags |= cpu_to_le16(I40E_AQ_FLAG_LB);
        desc->datalen = cpu_to_le16((u16)bi->size);
        desc->params.external.addr_high = cpu_to_le32(upper_32_bits(bi->pa));
        desc->params.external.addr_low = cpu_to_le32(lower_32_bits(bi->pa));
@@ -955,20 +962,14 @@ clean_arq_element_out:
 
 static void i40e_resume_aq(struct i40e_hw *hw)
 {
-       u32 reg = 0;
-
        /* Registers are reset after PF reset */
        hw->aq.asq.next_to_use = 0;
        hw->aq.asq.next_to_clean = 0;
 
        i40e_config_asq_regs(hw);
-       reg = hw->aq.num_asq_entries | I40E_PF_ATQLEN_ATQENABLE_MASK;
-       wr32(hw, hw->aq.asq.len, reg);
 
        hw->aq.arq.next_to_use = 0;
        hw->aq.arq.next_to_clean = 0;
 
        i40e_config_arq_regs(hw);
-       reg = hw->aq.num_arq_entries | I40E_PF_ATQLEN_ATQENABLE_MASK;
-       wr32(hw, hw->aq.arq.len, reg);
 }
index 2859377abca14dd6bc07eb2b268906713f77a0c1..007508772cf05dafd31a4cc09fd72baa95061ac8 100644 (file)
@@ -35,7 +35,7 @@
  */
 
 #define I40E_FW_API_VERSION_MAJOR  0x0001
-#define I40E_FW_API_VERSION_MINOR  0x0000
+#define I40E_FW_API_VERSION_MINOR  0x0001
 
 struct i40e_aq_desc {
        __le16 flags;
@@ -137,10 +137,13 @@ enum i40e_admin_queue_opc {
        i40e_aqc_opc_set_ns_proxy_entry     = 0x0105,
 
        /* LAA */
-       i40e_aqc_opc_mng_laa                = 0x0106,
+       i40e_aqc_opc_mng_laa                = 0x0106,   /* AQ obsolete */
        i40e_aqc_opc_mac_address_read       = 0x0107,
        i40e_aqc_opc_mac_address_write      = 0x0108,
 
+       /* PXE */
+       i40e_aqc_opc_clear_pxe_mode         = 0x0110,
+
        /* internal switch commands */
        i40e_aqc_opc_get_switch_config         = 0x0200,
        i40e_aqc_opc_add_statistics            = 0x0201,
@@ -317,13 +320,15 @@ struct i40e_aqc_get_version {
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_get_version);
 
-/* Send driver version (direct 0x0002) */
+/* Send driver version (indirect 0x0002) */
 struct i40e_aqc_driver_version {
        u8     driver_major_ver;
        u8     driver_minor_ver;
        u8     driver_build_ver;
        u8     driver_subbuild_ver;
-       u8     reserved[12];
+       u8     reserved[4];
+       __le32 address_high;
+       __le32 address_low;
 };
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_driver_version);
@@ -479,7 +484,7 @@ struct i40e_aqc_mng_laa {
        u8     reserved2[6];
 };
 
-/* Manage MAC Address Read Command (0x0107) */
+/* Manage MAC Address Read Command (indirect 0x0107) */
 struct i40e_aqc_mac_address_read {
        __le16  command_flags;
 #define I40E_AQC_LAN_ADDR_VALID   0x10
@@ -517,6 +522,16 @@ struct i40e_aqc_mac_address_write {
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_mac_address_write);
 
+/* PXE commands (0x011x) */
+
+/* Clear PXE Command and response  (direct 0x0110) */
+struct i40e_aqc_clear_pxe {
+       u8      rx_cnt;
+       u8      reserved[15];
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_clear_pxe);
+
 /* Switch configuration commands (0x02xx) */
 
 /* Used by many indirect commands that only pass an seid and a buffer in the
@@ -639,13 +654,15 @@ struct i40e_aqc_switch_resource_alloc_element_resp {
        u8     reserved2[6];
 };
 
-/* Add VSI (indirect 0x210)
+/* Add VSI (indirect 0x0210)
  *    this indirect command uses struct i40e_aqc_vsi_properties_data
  *    as the indirect buffer (128 bytes)
  *
- * Update VSI (indirect 0x211) Get VSI (indirect 0x0212)
- *    use the generic i40e_aqc_switch_seid descriptor format
- *    use the same completion and data structure as Add VSI
+ * Update VSI (indirect 0x211)
+ *     uses the same data structure as Add VSI
+ *
+ * Get VSI (indirect 0x0212)
+ *     uses the same completion and data structure as Add VSI
  */
 struct i40e_aqc_add_get_update_vsi {
        __le16 uplink_seid;
@@ -1185,27 +1202,40 @@ struct i40e_aqc_add_remove_cloud_filters_element_data {
 #define I40E_AQC_ADD_CLOUD_FILTER_SHIFT                 0
 #define I40E_AQC_ADD_CLOUD_FILTER_MASK                  (0x3F << \
                                        I40E_AQC_ADD_CLOUD_FILTER_SHIFT)
+/* 0x0000 reserved */
 #define I40E_AQC_ADD_CLOUD_FILTER_OIP                   0x0001
-#define I40E_AQC_ADD_CLOUD_FILTER_OIP_GRE               0x0002
+/* 0x0002 reserved */
 #define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN            0x0003
-#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_GRE        0x0004
+#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID     0x0004
+/* 0x0005 reserved */
 #define I40E_AQC_ADD_CLOUD_FILTER_IMAC_TEN_ID           0x0006
-#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_VNL        0x0007
+/* 0x0007 reserved */
 /* 0x0008 reserved */
 #define I40E_AQC_ADD_CLOUD_FILTER_OMAC                  0x0009
 #define I40E_AQC_ADD_CLOUD_FILTER_IMAC                  0x000A
+#define I40E_AQC_ADD_CLOUD_FILTER_OMAC_TEN_ID_IMAC      0x000B
+#define I40E_AQC_ADD_CLOUD_FILTER_IIP                   0x000C
+
 #define I40E_AQC_ADD_CLOUD_FLAGS_TO_QUEUE               0x0080
 #define I40E_AQC_ADD_CLOUD_VNK_SHIFT                    6
 #define I40E_AQC_ADD_CLOUD_VNK_MASK                     0x00C0
 #define I40E_AQC_ADD_CLOUD_FLAGS_IPV4                   0
 #define I40E_AQC_ADD_CLOUD_FLAGS_IPV6                   0x0100
-       __le32 key_low;
-       __le32 key_high;
+
+#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_NVGRE_OMAC          1
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NGE                 2
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_IP                  3
+
+       __le32 tenant_id;
+       u8     reserved[4];
        __le16 queue_number;
 #define I40E_AQC_ADD_CLOUD_QUEUE_SHIFT                  0
 #define I40E_AQC_ADD_CLOUD_QUEUE_MASK                   (0x3F << \
                                        I40E_AQC_ADD_CLOUD_QUEUE_SHIFT)
-       u8     reserved[14];
+       u8     reserved2[14];
        /* response section */
        u8     allocation_result;
 #define I40E_AQC_ADD_CLOUD_FILTER_SUCCESS         0x0
@@ -1548,7 +1578,7 @@ struct i40e_aqc_module_desc {
 
 struct i40e_aq_get_phy_abilities_resp {
        __le32 phy_type;       /* bitmap using the above enum for offsets */
-       u8     link_speed;     /* bitmap using the above enum */
+       u8     link_speed;     /* bitmap using the above enum bit patterns */
        u8     abilities;
 #define I40E_AQ_PHY_FLAG_PAUSE_TX         0x01
 #define I40E_AQ_PHY_FLAG_PAUSE_RX         0x02
@@ -1582,6 +1612,10 @@ struct i40e_aq_set_phy_config { /* same bits as above in all */
        __le32 phy_type;
        u8     link_speed;
        u8     abilities;
+/* bits 0-2 use the values from get_phy_abilities_resp */
+#define I40E_AQ_PHY_ENABLE_LINK                0x08
+#define I40E_AQ_PHY_ENABLE_AN          0x10
+#define I40E_AQ_PHY_ENABLE_ATOMIC_LINK 0x20
        __le16 eee_capability;
        __le32 eeer;
        u8     low_power_ctrl;
@@ -1915,22 +1949,39 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_start);
 struct i40e_aqc_add_udp_tunnel {
        __le16 udp_port;
        u8     header_len; /* in DWords, 1 to 15 */
-       u8     protocol_index;
-#define I40E_AQC_TUNNEL_TYPE_MAC    0x0
-#define I40E_AQC_TUNNEL_TYPE_UDP    0x1
-#define I40E_AQC_TUNNEL_TYPE_VXLAN  0x2
-       u8     reserved[12];
+       u8     protocol_type;
+#define I40E_AQC_TUNNEL_TYPE_TEREDO    0x0
+#define I40E_AQC_TUNNEL_TYPE_VXLAN     0x2
+#define I40E_AQC_TUNNEL_TYPE_NGE       0x3
+       u8     variable_udp_length;
+#define I40E_AQC_TUNNEL_FIXED_UDP_LENGTH       0x0
+#define I40E_AQC_TUNNEL_VARIABLE_UDP_LENGTH    0x1
+       u8     udp_key_index;
+#define I40E_AQC_TUNNEL_KEY_INDEX_VXLAN                        0x0
+#define I40E_AQC_TUNNEL_KEY_INDEX_NGE                  0x1
+#define I40E_AQC_TUNNEL_KEY_INDEX_PROPRIETARY_UDP      0x2
+       u8     reserved[10];
 };
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_add_udp_tunnel);
 
+struct i40e_aqc_add_udp_tunnel_completion {
+       __le16 udp_port;
+       u8     filter_entry_index;
+       u8     multiple_pfs;
+#define I40E_AQC_SINGLE_PF     0x0
+#define I40E_AQC_MULTIPLE_PFS  0x1
+       u8     total_filters;
+       u8     reserved[11];
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_add_udp_tunnel_completion);
+
 /* remove UDP Tunnel command (0x0B01) */
 struct i40e_aqc_remove_udp_tunnel {
        u8     reserved[2];
        u8     index; /* 0 to 15 */
-       u8     pf_filters;
-       u8     total_filters;
-       u8     reserved2[11];
+       u8     reserved2[13];
 };
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_remove_udp_tunnel);
@@ -1938,28 +1989,32 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_remove_udp_tunnel);
 struct i40e_aqc_del_udp_tunnel_completion {
        __le16 udp_port;
        u8     index; /* 0 to 15 */
-       u8     multiple_entries;
-       u8     tunnels_used;
-       u8     reserved;
-       u8     tunnels_free;
-       u8     reserved1[9];
+       u8     multiple_pfs;
+       u8     total_filters_used;
+       u8     reserved1[11];
 };
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_del_udp_tunnel_completion);
 
 /* tunnel key structure 0x0B10 */
+
 struct i40e_aqc_tunnel_key_structure {
-       __le16     key1_off;
-       __le16     key1_len;
-       __le16     key2_off;
-       __le16     key2_len;
-       __le16     flags;
+       u8      key1_off;
+       u8      key2_off;
+       u8      key1_len;  /* 0 to 15 */
+       u8      key2_len;  /* 0 to 15 */
+       u8      flags;
 #define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDE 0x01
 /* response flags */
 #define I40E_AQC_TUNNEL_KEY_STRUCT_SUCCESS    0x01
 #define I40E_AQC_TUNNEL_KEY_STRUCT_MODIFIED   0x02
 #define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDDEN 0x03
-       u8         resreved[6];
+       u8      network_key_index;
+#define I40E_AQC_NETWORK_KEY_INDEX_VXLAN               0x0
+#define I40E_AQC_NETWORK_KEY_INDEX_NGE                 0x1
+#define I40E_AQC_NETWORK_KEY_INDEX_FLEX_MAC_IN_UDP     0x2
+#define I40E_AQC_NETWORK_KEY_INDEX_GRE                 0x3
+       u8      reserved[10];
 };
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_tunnel_key_structure);
@@ -2053,6 +2108,7 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_modify_reg);
 #define I40E_AQ_CLUSTER_ID_DCB         8
 #define I40E_AQ_CLUSTER_ID_EMP_MEM     9
 #define I40E_AQ_CLUSTER_ID_PKT_BUF     10
+#define I40E_AQ_CLUSTER_ID_ALTRAM      11
 
 struct i40e_aqc_debug_dump_internals {
        u8     cluster_id;
index 7cd59cefcc3b2c6a4cf3064a48fbc667ae9a87a7..d564910b4f587df7c31d9b1fc1cd426bdc73d5c0 100644 (file)
@@ -180,14 +180,6 @@ i40e_status i40e_init_shared_code(struct i40e_hw *hw)
        i40e_status status = 0;
        u32 reg;
 
-       hw->phy.get_link_info = true;
-
-       /* Determine port number */
-       reg = rd32(hw, I40E_PFGEN_PORTNUM);
-       reg = ((reg & I40E_PFGEN_PORTNUM_PORT_NUM_MASK) >>
-              I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT);
-       hw->port = (u8)reg;
-
        i40e_set_mac_type(hw);
 
        switch (hw->mac.type) {
@@ -198,6 +190,21 @@ i40e_status i40e_init_shared_code(struct i40e_hw *hw)
                break;
        }
 
+       hw->phy.get_link_info = true;
+
+       /* Determine port number */
+       reg = rd32(hw, I40E_PFGEN_PORTNUM);
+       reg = ((reg & I40E_PFGEN_PORTNUM_PORT_NUM_MASK) >>
+              I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT);
+       hw->port = (u8)reg;
+
+       /* Determine the PF number based on the PCI fn */
+       reg = rd32(hw, I40E_GLPCI_CAPSUP);
+       if (reg & I40E_GLPCI_CAPSUP_ARI_EN_MASK)
+               hw->pf_id = (u8)((hw->bus.device << 3) | hw->bus.func);
+       else
+               hw->pf_id = (u8)hw->bus.func;
+
        status = i40e_init_nvm(hw);
        return status;
 }
@@ -335,6 +342,7 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
 i40e_status i40e_pf_reset(struct i40e_hw *hw)
 {
        u32 cnt = 0;
+       u32 cnt1 = 0;
        u32 reg = 0;
        u32 grst_del;
 
@@ -355,12 +363,24 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)
                return I40E_ERR_RESET_FAILED;
        }
 
-       /* Determine the PF number based on the PCI fn */
-       reg = rd32(hw, I40E_GLPCI_CAPSUP);
-       if (reg & I40E_GLPCI_CAPSUP_ARI_EN_MASK)
-               hw->pf_id = (u8)((hw->bus.device << 3) | hw->bus.func);
-       else
-               hw->pf_id = (u8)hw->bus.func;
+       /* Now Wait for the FW to be ready */
+       for (cnt1 = 0; cnt1 < I40E_PF_RESET_WAIT_COUNT; cnt1++) {
+               reg = rd32(hw, I40E_GLNVM_ULD);
+               reg &= (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
+                       I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK);
+               if (reg == (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
+                           I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK)) {
+                       hw_dbg(hw, "Core and Global modules ready %d\n", cnt1);
+                       break;
+               }
+               usleep_range(10000, 20000);
+       }
+       if (!(reg & (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
+                    I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK))) {
+               hw_dbg(hw, "wait for FW Reset complete timedout\n");
+               hw_dbg(hw, "I40E_GLNVM_ULD = 0x%x\n", reg);
+               return I40E_ERR_RESET_FAILED;
+       }
 
        /* If there was a Global Reset in progress when we got here,
         * we don't need to do the PF Reset
@@ -386,6 +406,7 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)
        }
 
        i40e_clear_pxe_mode(hw);
+
        return 0;
 }
 
@@ -1718,7 +1739,7 @@ i40e_status i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
 
        cmd->udp_port = cpu_to_le16(udp_port);
        cmd->header_len = header_len;
-       cmd->protocol_index = protocol_index;
+       cmd->protocol_type = protocol_index;
 
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
index 45bdccae1fb0a1a6f36e37bda35682d75ab431d7..125f758a03ac241131f56355e4a2e21f57ca7077 100644 (file)
@@ -1523,6 +1523,118 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
                } else {
                        dev_info(&pf->pdev->dev, "clear_stats vsi [seid] or clear_stats pf\n");
                }
+       } else if (strncmp(cmd_buf, "send aq_cmd", 11) == 0) {
+               struct i40e_aq_desc *desc;
+               i40e_status ret;
+
+               desc = kzalloc(sizeof(struct i40e_aq_desc), GFP_KERNEL);
+               if (!desc)
+                       goto command_write_done;
+               cnt = sscanf(&cmd_buf[11],
+                            "%hx %hx %hx %hx %x %x %x %x %x %x",
+                            &desc->flags,
+                            &desc->opcode, &desc->datalen, &desc->retval,
+                            &desc->cookie_high, &desc->cookie_low,
+                            &desc->params.internal.param0,
+                            &desc->params.internal.param1,
+                            &desc->params.internal.param2,
+                            &desc->params.internal.param3);
+               if (cnt != 10) {
+                       dev_info(&pf->pdev->dev,
+                                "send aq_cmd: bad command string, cnt=%d\n",
+                                cnt);
+                       kfree(desc);
+                       desc = NULL;
+                       goto command_write_done;
+               }
+               ret = i40e_asq_send_command(&pf->hw, desc, NULL, 0, NULL);
+               if (!ret) {
+                       dev_info(&pf->pdev->dev, "AQ command sent Status : Success\n");
+               } else if (ret == I40E_ERR_ADMIN_QUEUE_ERROR) {
+                       dev_info(&pf->pdev->dev,
+                                "AQ command send failed Opcode %x AQ Error: %d\n",
+                                desc->opcode, pf->hw.aq.asq_last_status);
+               } else {
+                       dev_info(&pf->pdev->dev,
+                                "AQ command send failed Opcode %x Status: %d\n",
+                                desc->opcode, ret);
+               }
+               dev_info(&pf->pdev->dev,
+                        "AQ desc WB 0x%04x 0x%04x 0x%04x 0x%04x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
+                        desc->flags, desc->opcode, desc->datalen, desc->retval,
+                        desc->cookie_high, desc->cookie_low,
+                        desc->params.internal.param0,
+                        desc->params.internal.param1,
+                        desc->params.internal.param2,
+                        desc->params.internal.param3);
+               kfree(desc);
+               desc = NULL;
+       } else if (strncmp(cmd_buf, "send indirect aq_cmd", 20) == 0) {
+               struct i40e_aq_desc *desc;
+               i40e_status ret;
+               u16 buffer_len;
+               u8 *buff;
+
+               desc = kzalloc(sizeof(struct i40e_aq_desc), GFP_KERNEL);
+               if (!desc)
+                       goto command_write_done;
+               cnt = sscanf(&cmd_buf[20],
+                            "%hx %hx %hx %hx %x %x %x %x %x %x %hd",
+                            &desc->flags,
+                            &desc->opcode, &desc->datalen, &desc->retval,
+                            &desc->cookie_high, &desc->cookie_low,
+                            &desc->params.internal.param0,
+                            &desc->params.internal.param1,
+                            &desc->params.internal.param2,
+                            &desc->params.internal.param3,
+                            &buffer_len);
+               if (cnt != 11) {
+                       dev_info(&pf->pdev->dev,
+                                "send indirect aq_cmd: bad command string, cnt=%d\n",
+                                cnt);
+                       kfree(desc);
+                       desc = NULL;
+                       goto command_write_done;
+               }
+               /* Just stub a buffer big enough in case user messed up */
+               if (buffer_len == 0)
+                       buffer_len = 1280;
+
+               buff = kzalloc(buffer_len, GFP_KERNEL);
+               if (!buff) {
+                       kfree(desc);
+                       desc = NULL;
+                       goto command_write_done;
+               }
+               desc->flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
+               ret = i40e_asq_send_command(&pf->hw, desc, buff,
+                                           buffer_len, NULL);
+               if (!ret) {
+                       dev_info(&pf->pdev->dev, "AQ command sent Status : Success\n");
+               } else if (ret == I40E_ERR_ADMIN_QUEUE_ERROR) {
+                       dev_info(&pf->pdev->dev,
+                                "AQ command send failed Opcode %x AQ Error: %d\n",
+                                desc->opcode, pf->hw.aq.asq_last_status);
+               } else {
+                       dev_info(&pf->pdev->dev,
+                                "AQ command send failed Opcode %x Status: %d\n",
+                                desc->opcode, ret);
+               }
+               dev_info(&pf->pdev->dev,
+                        "AQ desc WB 0x%04x 0x%04x 0x%04x 0x%04x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
+                        desc->flags, desc->opcode, desc->datalen, desc->retval,
+                        desc->cookie_high, desc->cookie_low,
+                        desc->params.internal.param0,
+                        desc->params.internal.param1,
+                        desc->params.internal.param2,
+                        desc->params.internal.param3);
+               print_hex_dump(KERN_INFO, "AQ buffer WB: ",
+                              DUMP_PREFIX_OFFSET, 16, 1,
+                              buff, buffer_len, true);
+               kfree(buff);
+               buff = NULL;
+               kfree(desc);
+               desc = NULL;
        } else if ((strncmp(cmd_buf, "add fd_filter", 13) == 0) ||
                   (strncmp(cmd_buf, "rem fd_filter", 13) == 0)) {
                struct i40e_fdir_data fd_data;
@@ -1774,6 +1886,8 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
                dev_info(&pf->pdev->dev, "  pfr\n");
                dev_info(&pf->pdev->dev, "  corer\n");
                dev_info(&pf->pdev->dev, "  globr\n");
+               dev_info(&pf->pdev->dev, "  send aq_cmd <flags> <opcode> <datalen> <retval> <cookie_h> <cookie_l> <param0> <param1> <param2> <param3>\n");
+               dev_info(&pf->pdev->dev, "  send indirect aq_cmd <flags> <opcode> <datalen> <retval> <cookie_h> <cookie_l> <param0> <param1> <param2> <param3> <buffer_len>\n");
                dev_info(&pf->pdev->dev, "  add fd_filter <dest q_index> <flex_off> <pctype> <dest_vsi> <dest_ctl> <fd_status> <cnt_index> <fd_id> <packet_len> <packet>\n");
                dev_info(&pf->pdev->dev, "  rem fd_filter <dest q_index> <flex_off> <pctype> <dest_vsi> <dest_ctl> <fd_status> <cnt_index> <fd_id> <packet_len> <packet>\n");
                dev_info(&pf->pdev->dev, "  lldp start\n");
index 98c1ef563bf03e0ff0176521d86af12b46daad78..6a1657e62418e67dd5601f3a8d9397e66a7c20bf 100644 (file)
@@ -70,9 +70,9 @@ struct i40e_diag_reg_test_info i40e_reg_list[] = {
        /* offset               mask         elements   stride */
        {I40E_QTX_CTL(0),       0x0000FFBF,   4, I40E_QTX_CTL(1) - I40E_QTX_CTL(0)},
        {I40E_PFINT_ITR0(0),    0x00000FFF,   3, I40E_PFINT_ITR0(1) - I40E_PFINT_ITR0(0)},
-       {I40E_PFINT_ITRN(0, 0), 0x00000FFF,  64, I40E_PFINT_ITRN(0, 1) - I40E_PFINT_ITRN(0, 0)},
-       {I40E_PFINT_ITRN(1, 0), 0x00000FFF,  64, I40E_PFINT_ITRN(1, 1) - I40E_PFINT_ITRN(1, 0)},
-       {I40E_PFINT_ITRN(2, 0), 0x00000FFF,  64, I40E_PFINT_ITRN(2, 1) - I40E_PFINT_ITRN(2, 0)},
+       {I40E_PFINT_ITRN(0, 0), 0x00000FFF,   8, I40E_PFINT_ITRN(0, 1) - I40E_PFINT_ITRN(0, 0)},
+       {I40E_PFINT_ITRN(1, 0), 0x00000FFF,   8, I40E_PFINT_ITRN(1, 1) - I40E_PFINT_ITRN(1, 0)},
+       {I40E_PFINT_ITRN(2, 0), 0x00000FFF,   8, I40E_PFINT_ITRN(2, 1) - I40E_PFINT_ITRN(2, 0)},
        {I40E_PFINT_STAT_CTL0,  0x0000000C,   1, 0},
        {I40E_PFINT_LNKLST0,    0x00001FFF,   1, 0},
        {I40E_PFINT_LNKLSTN(0), 0x000007FF,  64, I40E_PFINT_LNKLSTN(1) - I40E_PFINT_LNKLSTN(0)},
index 483126cceade8257fb622eb562c55fd28dae3194..f736c44704125364ca544f53ebb0c5e2637f0ee7 100644 (file)
@@ -39,7 +39,7 @@ static const char i40e_driver_string[] =
 
 #define DRV_VERSION_MAJOR 0
 #define DRV_VERSION_MINOR 3
-#define DRV_VERSION_BUILD 14
+#define DRV_VERSION_BUILD 25
 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
             __stringify(DRV_VERSION_MINOR) "." \
             __stringify(DRV_VERSION_BUILD)    DRV_KERN
@@ -1509,11 +1509,6 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                                cpu_to_le16((u16)(f->vlan ==
                                            I40E_VLAN_ANY ? 0 : f->vlan));
 
-                       /* vlan0 as wild card to allow packets from all vlans */
-                       if (f->vlan == I40E_VLAN_ANY ||
-                           (vsi->netdev && !(vsi->netdev->features &
-                                             NETIF_F_HW_VLAN_CTAG_FILTER)))
-                               cmd_flags |= I40E_AQC_MACVLAN_DEL_IGNORE_VLAN;
                        cmd_flags |= I40E_AQC_MACVLAN_DEL_PERFECT_MATCH;
                        del_list[num_del].flags = cmd_flags;
                        num_del++;
@@ -1579,12 +1574,6 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                        add_list[num_add].queue_number = 0;
 
                        cmd_flags |= I40E_AQC_MACVLAN_ADD_PERFECT_MATCH;
-
-                       /* vlan0 as wild card to allow packets from all vlans */
-                       if (f->vlan == I40E_VLAN_ANY || (vsi->netdev &&
-                           !(vsi->netdev->features &
-                                                NETIF_F_HW_VLAN_CTAG_FILTER)))
-                               cmd_flags |= I40E_AQC_MACVLAN_ADD_IGNORE_VLAN;
                        add_list[num_add].flags = cpu_to_le16(cmd_flags);
                        num_add++;
 
@@ -1650,6 +1639,13 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                        dev_info(&pf->pdev->dev,
                                 "set uni promisc failed, err %d, aq_err %d\n",
                                 aq_ret, pf->hw.aq.asq_last_status);
+               aq_ret = i40e_aq_set_vsi_broadcast(&vsi->back->hw,
+                                                  vsi->seid,
+                                                  cur_promisc, NULL);
+               if (aq_ret)
+                       dev_info(&pf->pdev->dev,
+                                "set brdcast promisc failed, err %d, aq_err %d\n",
+                                aq_ret, pf->hw.aq.asq_last_status);
        }
 
        clear_bit(__I40E_CONFIG_BUSY, &vsi->state);
@@ -3987,13 +3983,6 @@ static int i40e_open(struct net_device *netdev)
        if (err)
                goto err_up_complete;
 
-       if ((vsi->type == I40E_VSI_MAIN) || (vsi->type == I40E_VSI_VMDQ2)) {
-               err = i40e_aq_set_vsi_broadcast(&pf->hw, vsi->seid, true, NULL);
-               if (err)
-                       netdev_info(netdev,
-                                   "couldn't set broadcast err %d aq_err %d\n",
-                                   err, pf->hw.aq.asq_last_status);
-       }
 #ifdef CONFIG_I40E_VXLAN
        vxlan_get_rx_port(netdev);
 #endif
@@ -6067,6 +6056,7 @@ static const struct net_device_ops i40e_netdev_ops = {
  **/
 static int i40e_config_netdev(struct i40e_vsi *vsi)
 {
+       u8 brdcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
        struct i40e_pf *pf = vsi->back;
        struct i40e_hw *hw = &pf->hw;
        struct i40e_netdev_priv *np;
@@ -6116,6 +6106,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
                random_ether_addr(mac_addr);
                i40e_add_filter(vsi, mac_addr, I40E_VLAN_ANY, false, false);
        }
+       i40e_add_filter(vsi, brdcast, I40E_VLAN_ANY, false, false);
 
        memcpy(netdev->dev_addr, mac_addr, ETH_ALEN);
        memcpy(netdev->perm_addr, mac_addr, ETH_ALEN);
index 97e1bb30ef8a1edae549e23e5b34875685302f1e..e2da0a2784dd63417a453832b16e07e6463b90bd 100644 (file)
@@ -166,15 +166,15 @@ static i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
 }
 
 /**
- *  i40e_read_nvm_srctl - Reads Shadow RAM.
+ *  i40e_read_nvm_word - Reads Shadow RAM
  *  @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 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
  **/
-static i40e_status i40e_read_nvm_srctl(struct i40e_hw *hw, u16 offset,
-                                                u16 *data)
+i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
+                                        u16 *data)
 {
        i40e_status ret_code = I40E_ERR_TIMEOUT;
        u32 sr_reg;
@@ -210,29 +210,6 @@ read_nvm_exit:
        return ret_code;
 }
 
-/**
- *  i40e_read_nvm_word - Reads Shadow RAM word.
- *  @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 16 bit word from the Shadow RAM. Each read is preceded
- *  with the NVM ownership taking and followed by the release.
- **/
-i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
-                                        u16 *data)
-{
-       i40e_status ret_code = 0;
-
-       ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
-       if (!ret_code) {
-               ret_code = i40e_read_nvm_srctl(hw, offset, data);
-               i40e_release_nvm(hw);
-       }
-
-       return ret_code;
-}
-
 /**
  *  i40e_read_nvm_buffer - Reads Shadow RAM buffer.
  *  @hw: pointer to the HW structure.
@@ -250,30 +227,18 @@ i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
 {
        i40e_status ret_code = 0;
        u16 index, word;
-       u32 time;
 
-       ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
-       if (!ret_code) {
-               /* Loop thru the selected region. */
-               for (word = 0; word < *words; word++) {
-                       index = offset + word;
-                       ret_code = i40e_read_nvm_srctl(hw, index, &data[word]);
-                       if (ret_code)
-                               break;
-                       /* Check if we didn't exceeded the semaphore timeout. */
-                       time = rd32(hw, I40E_GLVFGEN_TIMER);
-                       if (time >= hw->nvm.hw_semaphore_timeout) {
-                               ret_code = I40E_ERR_TIMEOUT;
-                               hw_dbg(hw, "NVM read error: timeout.\n");
-                               break;
-                       }
-               }
-               /* Update the number of words read from the Shadow RAM. */
-               *words = word;
-               /* Release the NVM ownership. */
-               i40e_release_nvm(hw);
+       /* Loop thru the selected region. */
+       for (word = 0; word < *words; word++) {
+               index = offset + word;
+               ret_code = i40e_read_nvm_word(hw, index, &data[word]);
+               if (ret_code)
+                       break;
        }
 
+       /* Update the number of words read from the Shadow RAM. */
+       *words = word;
+
        return ret_code;
 }
 
@@ -297,14 +262,14 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
        u32 i = 0;
 
        /* read pointer to VPD area */
-       ret_code = i40e_read_nvm_srctl(hw, I40E_SR_VPD_PTR, &vpd_module);
+       ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module);
        if (ret_code) {
                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_srctl(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
+       ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
                                       &pcie_alt_module);
        if (ret_code) {
                ret_code = I40E_ERR_NVM_CHECKSUM;
@@ -331,7 +296,7 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
                                break;
                }
 
-               ret_code = i40e_read_nvm_srctl(hw, (u16)i, &word);
+               ret_code = i40e_read_nvm_word(hw, (u16)i, &word);
                if (ret_code) {
                        ret_code = I40E_ERR_NVM_CHECKSUM;
                        goto i40e_calc_nvm_checksum_exit;
@@ -371,7 +336,7 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
        /* Do not use i40e_read_nvm_word() because we do not want to take
         * the synchronization semaphores twice here.
         */
-       i40e_read_nvm_srctl(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
+       i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
 
        /* Verify read checksum from EEPROM is the same as
         * calculated checksum
index 2394c66870f4f672aae7e223554f6ce2345847fe..d188ec03aff2b25c07b35327d6df897617636d21 100644 (file)
 #define I40E_GLNVM_SRDATA_WRDATA_MASK (0xFFFF << I40E_GLNVM_SRDATA_WRDATA_SHIFT)
 #define I40E_GLNVM_SRDATA_RDDATA_SHIFT 16
 #define I40E_GLNVM_SRDATA_RDDATA_MASK (0xFFFF << I40E_GLNVM_SRDATA_RDDATA_SHIFT)
+#define I40E_GLNVM_ULD 0x000B6008
+#define I40E_GLNVM_ULD_CONF_PCIR_DONE_SHIFT 0
+#define I40E_GLNVM_ULD_CONF_PCIR_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIR_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PCIRTL_DONE_SHIFT 1
+#define I40E_GLNVM_ULD_CONF_PCIRTL_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIRTL_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_LCB_DONE_SHIFT 2
+#define I40E_GLNVM_ULD_CONF_LCB_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_LCB_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_CORE_DONE_SHIFT 3
+#define I40E_GLNVM_ULD_CONF_CORE_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_CORE_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_GLOBAL_DONE_SHIFT 4
+#define I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_GLOBAL_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_POR_DONE_SHIFT 5
+#define I40E_GLNVM_ULD_CONF_POR_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_POR_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_SHIFT 6
+#define I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_SHIFT 7
+#define I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_EMP_DONE_SHIFT 8
+#define I40E_GLNVM_ULD_CONF_EMP_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_EMP_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PCIALT_DONE_SHIFT 9
+#define I40E_GLNVM_ULD_CONF_PCIALT_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIALT_DONE_SHIFT)
+
 #define I40E_GLPCI_BYTCTH 0x0009C484
 #define I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_SHIFT 0
 #define I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_MASK (0xFFFFFFFF << I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_SHIFT)
index 7bbcc7165d24352df192d0c1f53e40f8a74d9e13..bcf03177356867b01aea6898eb702fff50d48b7a 100644 (file)
@@ -53,9 +53,6 @@
                                         (d) == I40E_QSFP_B_DEVICE_ID  || \
                                         (d) == I40E_QSFP_C_DEVICE_ID)
 
-#define I40E_FW_API_VERSION_MAJOR  0x0001
-#define I40E_FW_API_VERSION_MINOR  0x0000
-
 #define I40E_MAX_VSI_QP                        16
 #define I40E_MAX_VF_VSI                        3
 #define I40E_MAX_CHAINED_RX_BUFFERS    5
@@ -92,7 +89,7 @@ typedef void (*I40E_ADMINQ_CALLBACK)(struct i40e_hw *, struct i40e_aq_desc *);
 #define I40E_QTX_CTL_VF_QUEUE  0x0
 #define I40E_QTX_CTL_PF_QUEUE  0x2
 
-/* debug masks */
+/* debug masks - set these bits in hw->debug_mask to control output */
 enum i40e_debug_mask {
        I40E_DEBUG_INIT                 = 0x00000001,
        I40E_DEBUG_RELEASE              = 0x00000002,
@@ -106,10 +103,10 @@ enum i40e_debug_mask {
        I40E_DEBUG_DCB                  = 0x00000400,
        I40E_DEBUG_DIAG                 = 0x00000800,
 
-       I40E_DEBUG_AQ_MESSAGE           = 0x01000000, /* for i40e_debug() */
+       I40E_DEBUG_AQ_MESSAGE           = 0x01000000,
        I40E_DEBUG_AQ_DESCRIPTOR        = 0x02000000,
        I40E_DEBUG_AQ_DESC_BUFFER       = 0x04000000,
-       I40E_DEBUG_AQ_COMMAND           = 0x06000000, /* for i40e_debug_aq() */
+       I40E_DEBUG_AQ_COMMAND           = 0x06000000,
        I40E_DEBUG_AQ                   = 0x0F000000,
 
        I40E_DEBUG_USER                 = 0xF0000000,
@@ -523,7 +520,7 @@ enum i40e_rx_desc_status_bits {
 
 #define I40E_RXD_QW1_STATUS_TSYNVALID_SHIFT  I40E_RX_DESC_STATUS_TSYNVALID_SHIFT
 #define I40E_RXD_QW1_STATUS_TSYNVALID_MASK     (0x1UL << \
-                                            I40E_RXD_QW1_STATUS_TSYNVALID_SHIFT)
+                                        I40E_RXD_QW1_STATUS_TSYNVALID_SHIFT)
 
 enum i40e_rx_desc_fltstat_values {
        I40E_RX_DESC_FLTSTAT_NO_DATA    = 0,
index 55ec2db71fa1a21f9587772b57cbf9a8582bf26b..efb9a242d2750b73e00d2f0e31f0933b67c6a46d 100644 (file)
@@ -369,7 +369,6 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
 {
        struct i40e_mac_filter *f = NULL;
        struct i40e_pf *pf = vf->pf;
-       struct i40e_hw *hw = &pf->hw;
        struct i40e_vsi *vsi;
        int ret = 0;
 
@@ -383,6 +382,7 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
                goto error_alloc_vsi_res;
        }
        if (type == I40E_VSI_SRIOV) {
+               u8 brdcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
                vf->lan_vsi_index = vsi->idx;
                vf->lan_vsi_id = vsi->id;
                dev_info(&pf->pdev->dev,
@@ -398,6 +398,14 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
                        i40e_vsi_add_pvid(vsi, vf->port_vlan_id);
                f = i40e_add_filter(vsi, vf->default_lan_addr.addr,
                                    vf->port_vlan_id, true, false);
+               if (!f)
+                       dev_info(&pf->pdev->dev,
+                                "Could not allocate VF MAC addr\n");
+               f = i40e_add_filter(vsi, brdcast, vf->port_vlan_id,
+                                   true, false);
+               if (!f)
+                       dev_info(&pf->pdev->dev,
+                                "Could not allocate VF broadcast filter\n");
        }
 
        if (!f) {
@@ -413,15 +421,6 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
                goto error_alloc_vsi_res;
        }
 
-       /* accept bcast pkts. by default */
-       ret = i40e_aq_set_vsi_broadcast(hw, vsi->seid, true, NULL);
-       if (ret) {
-               dev_err(&pf->pdev->dev,
-                       "set vsi bcast failed for vf %d, vsi %d, aq_err %d\n",
-                       vf->vf_id, vsi->idx, pf->hw.aq.asq_last_status);
-               ret = -EINVAL;
-       }
-
 error_alloc_vsi_res:
        return ret;
 }
@@ -717,6 +716,76 @@ static bool i40e_vfs_are_assigned(struct i40e_pf *pf)
 
        return false;
 }
+#ifdef CONFIG_PCI_IOV
+
+/**
+ * i40e_enable_pf_switch_lb
+ * @pf: pointer to the pf structure
+ *
+ * enable switch loop back or die - no point in a return value
+ **/
+static void i40e_enable_pf_switch_lb(struct i40e_pf *pf)
+{
+       struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+       struct i40e_vsi_context ctxt;
+       int aq_ret;
+
+       ctxt.seid = pf->main_vsi_seid;
+       ctxt.pf_num = pf->hw.pf_id;
+       ctxt.vf_num = 0;
+       aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
+       if (aq_ret) {
+               dev_info(&pf->pdev->dev,
+                        "%s couldn't get pf vsi config, err %d, aq_err %d\n",
+                        __func__, aq_ret, pf->hw.aq.asq_last_status);
+               return;
+       }
+       ctxt.flags = I40E_AQ_VSI_TYPE_PF;
+       ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
+       ctxt.info.switch_id |= cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
+
+       aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
+       if (aq_ret) {
+               dev_info(&pf->pdev->dev,
+                        "%s: update vsi switch failed, aq_err=%d\n",
+                        __func__, vsi->back->hw.aq.asq_last_status);
+       }
+}
+#endif
+
+/**
+ * i40e_disable_pf_switch_lb
+ * @pf: pointer to the pf structure
+ *
+ * disable switch loop back or die - no point in a return value
+ **/
+static void i40e_disable_pf_switch_lb(struct i40e_pf *pf)
+{
+       struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+       struct i40e_vsi_context ctxt;
+       int aq_ret;
+
+       ctxt.seid = pf->main_vsi_seid;
+       ctxt.pf_num = pf->hw.pf_id;
+       ctxt.vf_num = 0;
+       aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
+       if (aq_ret) {
+               dev_info(&pf->pdev->dev,
+                        "%s couldn't get pf vsi config, err %d, aq_err %d\n",
+                        __func__, aq_ret, pf->hw.aq.asq_last_status);
+               return;
+       }
+       ctxt.flags = I40E_AQ_VSI_TYPE_PF;
+       ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
+       ctxt.info.switch_id &= ~cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
+
+       aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
+       if (aq_ret) {
+               dev_info(&pf->pdev->dev,
+                        "%s: update vsi switch failed, aq_err=%d\n",
+                        __func__, vsi->back->hw.aq.asq_last_status);
+       }
+}
 
 /**
  * i40e_free_vfs
@@ -760,10 +829,11 @@ void i40e_free_vfs(struct i40e_pf *pf)
                        bit_idx = (hw->func_caps.vf_base_id + vf_id) % 32;
                        wr32(hw, I40E_GLGEN_VFLRSTAT(reg_idx), (1 << bit_idx));
                }
-       }
-       else
+               i40e_disable_pf_switch_lb(pf);
+       } else {
                dev_warn(&pf->pdev->dev,
                         "unable to disable SR-IOV because VFs are assigned.\n");
+       }
 
        /* Re-enable interrupt 0. */
        i40e_irq_dynamic_enable_icr0(pf);
@@ -817,6 +887,7 @@ static int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs)
        pf->vf = vfs;
        pf->num_alloc_vfs = num_alloc_vfs;
 
+       i40e_enable_pf_switch_lb(pf);
 err_alloc:
        if (ret)
                i40e_free_vfs(pf);
@@ -1349,10 +1420,13 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf, u8 *macaddr)
                   is_zero_ether_addr(macaddr)) {
                dev_err(&pf->pdev->dev, "invalid VF MAC addr %pM\n", macaddr);
                ret = I40E_ERR_INVALID_MAC_ADDR;
-       } else if (vf->pf_set_mac && !is_multicast_ether_addr(macaddr)) {
+       } else if (vf->pf_set_mac && !is_multicast_ether_addr(macaddr) &&
+                  !ether_addr_equal(macaddr, vf->default_lan_addr.addr)) {
                /* If the host VMM administrator has set the VF MAC address
                 * administratively via the ndo_set_vf_mac command then deny
                 * permission to the VF to add or delete unicast MAC addresses.
+                * The VF may request to set the MAC address filter already
+                * assigned to it so do not return an error in that case.
                 */
                dev_err(&pf->pdev->dev,
                        "VF attempting to override administratively set MAC address\nPlease reload the VF driver to resume normal operation\n");