Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next...
authorJakub Kicinski <kuba@kernel.org>
Tue, 8 Aug 2023 23:41:30 +0000 (16:41 -0700)
committerJakub Kicinski <kuba@kernel.org>
Tue, 8 Aug 2023 23:41:30 +0000 (16:41 -0700)
Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2023-08-07 (ice)

This series contains updates to ice driver only.

Wojciech allows for LAG interfaces to be used for bridge offloads.

Marcin tracks additional metadata for filtering rules to aid in proper
differentiation of similar rules. He also renames some flags that
do not entirely describe their representation.

Karol and Jan add additional waiting for firmware load on devices that
require it.

Przemek refactors RSS implementation to clarify/simplify configurations.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  ice: clean up __ice_aq_get_set_rss_lut()
  ice: add FW load wait
  ice: Add get C827 PHY index function
  ice: Rename enum ice_pkt_flags values
  ice: Add direction metadata
  ice: Accept LAG netdevs in bridge offloads
====================

Link: https://lore.kernel.org/r/20230807204835.3129164-1-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
14 files changed:
drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
drivers/net/ethernet/intel/ice/ice_common.c
drivers/net/ethernet/intel/ice/ice_common.h
drivers/net/ethernet/intel/ice/ice_eswitch_br.c
drivers/net/ethernet/intel/ice/ice_hw_autogen.h
drivers/net/ethernet/intel/ice/ice_lib.c
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_protocol_type.h
drivers/net/ethernet/intel/ice/ice_ptp_hw.h
drivers/net/ethernet/intel/ice/ice_switch.c
drivers/net/ethernet/intel/ice/ice_switch.h
drivers/net/ethernet/intel/ice/ice_tc_lib.c
drivers/net/ethernet/intel/ice/ice_type.h
drivers/net/ethernet/intel/ice/ice_virtchnl.c

index c0ad34b..29f7a98 100644 (file)
@@ -1404,6 +1404,7 @@ struct ice_aqc_get_link_topo {
        struct ice_aqc_link_topo_addr addr;
        u8 node_part_num;
 #define ICE_AQC_GET_LINK_TOPO_NODE_NR_PCA9575  0x21
+#define ICE_AQC_GET_LINK_TOPO_NODE_NR_C827     0x31
        u8 rsvd[9];
 };
 
@@ -1793,11 +1794,10 @@ struct ice_aqc_lldp_filter_ctrl {
        u8 reserved2[12];
 };
 
+#define ICE_AQC_RSS_VSI_VALID BIT(15)
+
 /* Get/Set RSS key (indirect 0x0B04/0x0B02) */
 struct ice_aqc_get_set_rss_key {
-#define ICE_AQC_GSET_RSS_KEY_VSI_VALID BIT(15)
-#define ICE_AQC_GSET_RSS_KEY_VSI_ID_S  0
-#define ICE_AQC_GSET_RSS_KEY_VSI_ID_M  (0x3FF << ICE_AQC_GSET_RSS_KEY_VSI_ID_S)
        __le16 vsi_id;
        u8 reserved[6];
        __le32 addr_high;
@@ -1815,35 +1815,33 @@ struct ice_aqc_get_set_rss_keys {
        u8 extended_hash_key[ICE_AQC_GET_SET_RSS_KEY_DATA_HASH_KEY_SIZE];
 };
 
-/* Get/Set RSS LUT (indirect 0x0B05/0x0B03) */
-struct ice_aqc_get_set_rss_lut {
-#define ICE_AQC_GSET_RSS_LUT_VSI_VALID BIT(15)
-#define ICE_AQC_GSET_RSS_LUT_VSI_ID_S  0
-#define ICE_AQC_GSET_RSS_LUT_VSI_ID_M  (0x3FF << ICE_AQC_GSET_RSS_LUT_VSI_ID_S)
-       __le16 vsi_id;
-#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_S      0
-#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_M      \
-                               (0x3 << ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_S)
-
-#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_VSI     0
-#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF      1
-#define ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL  2
+enum ice_lut_type {
+       ICE_LUT_VSI = 0,
+       ICE_LUT_PF = 1,
+       ICE_LUT_GLOBAL = 2,
+};
 
-#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S       2
-#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M       \
-                               (0x3 << ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S)
+enum ice_lut_size {
+       ICE_LUT_VSI_SIZE = 64,
+       ICE_LUT_GLOBAL_SIZE = 512,
+       ICE_LUT_PF_SIZE = 2048,
+};
 
-#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128     128
-#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128_FLAG 0
-#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512     512
-#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512_FLAG 1
-#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K      2048
-#define ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K_FLAG         2
+/* enum ice_aqc_lut_flags combines constants used to fill
+ * &ice_aqc_get_set_rss_lut ::flags, which is an amalgamation of global LUT ID,
+ * LUT size and LUT type, last of which does not need neither shift nor mask.
+ */
+enum ice_aqc_lut_flags {
+       ICE_AQC_LUT_SIZE_SMALL = 0, /* size = 64 or 128 */
+       ICE_AQC_LUT_SIZE_512 = BIT(2),
+       ICE_AQC_LUT_SIZE_2K = BIT(3),
 
-#define ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_S       4
-#define ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_M       \
-                               (0xF << ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_S)
+       ICE_AQC_LUT_GLOBAL_IDX = GENMASK(7, 4),
+};
 
+/* Get/Set RSS LUT (indirect 0x0B05/0x0B03) */
+struct ice_aqc_get_set_rss_lut {
+       __le16 vsi_id;
        __le16 flags;
        __le32 reserved;
        __le32 addr_high;
index dade0a5..a86255b 100644 (file)
@@ -5,6 +5,7 @@
 #include "ice_sched.h"
 #include "ice_adminq_cmd.h"
 #include "ice_flow.h"
+#include "ice_ptp_hw.h"
 
 #define ICE_PF_RESET_WAIT_COUNT        300
 
@@ -2662,6 +2663,67 @@ ice_parse_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
 }
 
 /**
+ * ice_aq_get_netlist_node
+ * @hw: pointer to the hw struct
+ * @cmd: get_link_topo AQ structure
+ * @node_part_number: output node part number if node found
+ * @node_handle: output node handle parameter if node found
+ */
+static int
+ice_aq_get_netlist_node(struct ice_hw *hw, struct ice_aqc_get_link_topo *cmd,
+                       u8 *node_part_number, u16 *node_handle)
+{
+       struct ice_aq_desc desc;
+
+       ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo);
+       desc.params.get_link_topo = *cmd;
+
+       if (ice_aq_send_cmd(hw, &desc, NULL, 0, NULL))
+               return -EIO;
+
+       if (node_handle)
+               *node_handle = le16_to_cpu(desc.params.get_link_topo.addr.handle);
+       if (node_part_number)
+               *node_part_number = desc.params.get_link_topo.node_part_num;
+
+       return 0;
+}
+
+/**
+ * ice_is_pf_c827 - check if pf contains c827 phy
+ * @hw: pointer to the hw struct
+ */
+bool ice_is_pf_c827(struct ice_hw *hw)
+{
+       struct ice_aqc_get_link_topo cmd = {};
+       u8 node_part_number;
+       u16 node_handle;
+       int status;
+
+       if (hw->mac_type != ICE_MAC_E810)
+               return false;
+
+       if (hw->device_id != ICE_DEV_ID_E810C_QSFP)
+               return true;
+
+       cmd.addr.topo_params.node_type_ctx =
+               FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_TYPE_M, ICE_AQC_LINK_TOPO_NODE_TYPE_PHY) |
+               FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_CTX_M, ICE_AQC_LINK_TOPO_NODE_CTX_PORT);
+       cmd.addr.topo_params.index = 0;
+
+       status = ice_aq_get_netlist_node(hw, &cmd, &node_part_number,
+                                        &node_handle);
+
+       if (status || node_part_number != ICE_AQC_GET_LINK_TOPO_NODE_NR_C827)
+               return false;
+
+       if (node_handle == E810C_QSFP_C827_0_HANDLE || node_handle == E810C_QSFP_C827_1_HANDLE)
+               return true;
+
+       return false;
+}
+
+/**
  * ice_aq_list_caps - query function/device capabilities
  * @hw: pointer to the HW struct
  * @buf: a buffer to hold the capabilities
@@ -3877,6 +3939,34 @@ ice_aq_sff_eeprom(struct ice_hw *hw, u16 lport, u8 bus_addr,
        return status;
 }
 
+static enum ice_lut_size ice_lut_type_to_size(enum ice_lut_type type)
+{
+       switch (type) {
+       case ICE_LUT_VSI:
+               return ICE_LUT_VSI_SIZE;
+       case ICE_LUT_GLOBAL:
+               return ICE_LUT_GLOBAL_SIZE;
+       case ICE_LUT_PF:
+               return ICE_LUT_PF_SIZE;
+       }
+       WARN_ONCE(1, "incorrect type passed");
+       return ICE_LUT_VSI_SIZE;
+}
+
+static enum ice_aqc_lut_flags ice_lut_size_to_flag(enum ice_lut_size size)
+{
+       switch (size) {
+       case ICE_LUT_VSI_SIZE:
+               return ICE_AQC_LUT_SIZE_SMALL;
+       case ICE_LUT_GLOBAL_SIZE:
+               return ICE_AQC_LUT_SIZE_512;
+       case ICE_LUT_PF_SIZE:
+               return ICE_AQC_LUT_SIZE_2K;
+       }
+       WARN_ONCE(1, "incorrect size passed");
+       return 0;
+}
+
 /**
  * __ice_aq_get_set_rss_lut
  * @hw: pointer to the hardware structure
@@ -3886,95 +3976,44 @@ ice_aq_sff_eeprom(struct ice_hw *hw, u16 lport, u8 bus_addr,
  * Internal function to get (0x0B05) or set (0x0B03) RSS look up table
  */
 static int
-__ice_aq_get_set_rss_lut(struct ice_hw *hw, struct ice_aq_get_set_rss_lut_params *params, bool set)
-{
-       u16 flags = 0, vsi_id, lut_type, lut_size, glob_lut_idx, vsi_handle;
-       struct ice_aqc_get_set_rss_lut *cmd_resp;
+__ice_aq_get_set_rss_lut(struct ice_hw *hw,
+                        struct ice_aq_get_set_rss_lut_params *params, bool set)
+{
+       u16 opcode, vsi_id, vsi_handle = params->vsi_handle, glob_lut_idx = 0;
+       enum ice_lut_type lut_type = params->lut_type;
+       struct ice_aqc_get_set_rss_lut *desc_params;
+       enum ice_aqc_lut_flags flags;
+       enum ice_lut_size lut_size;
        struct ice_aq_desc desc;
-       int status;
-       u8 *lut;
+       u8 *lut = params->lut;
 
-       if (!params)
-               return -EINVAL;
 
-       vsi_handle = params->vsi_handle;
-       lut = params->lut;
-
-       if (!ice_is_vsi_valid(hw, vsi_handle) || !lut)
+       if (!lut || !ice_is_vsi_valid(hw, vsi_handle))
                return -EINVAL;
 
-       lut_size = params->lut_size;
-       lut_type = params->lut_type;
-       glob_lut_idx = params->global_lut_id;
-       vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
-
-       cmd_resp = &desc.params.get_set_rss_lut;
+       lut_size = ice_lut_type_to_size(lut_type);
+       if (lut_size > params->lut_size)
+               return -EINVAL;
+       else if (set && lut_size != params->lut_size)
+               return -EINVAL;
 
-       if (set) {
-               ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_rss_lut);
+       opcode = set ? ice_aqc_opc_set_rss_lut : ice_aqc_opc_get_rss_lut;
+       ice_fill_dflt_direct_cmd_desc(&desc, opcode);
+       if (set)
                desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
-       } else {
-               ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_rss_lut);
-       }
 
-       cmd_resp->vsi_id = cpu_to_le16(((vsi_id <<
-                                        ICE_AQC_GSET_RSS_LUT_VSI_ID_S) &
-                                       ICE_AQC_GSET_RSS_LUT_VSI_ID_M) |
-                                      ICE_AQC_GSET_RSS_LUT_VSI_VALID);
-
-       switch (lut_type) {
-       case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_VSI:
-       case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF:
-       case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL:
-               flags |= ((lut_type << ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_S) &
-                         ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_M);
-               break;
-       default:
-               status = -EINVAL;
-               goto ice_aq_get_set_rss_lut_exit;
-       }
-
-       if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL) {
-               flags |= ((glob_lut_idx << ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_S) &
-                         ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_M);
-
-               if (!set)
-                       goto ice_aq_get_set_rss_lut_send;
-       } else if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF) {
-               if (!set)
-                       goto ice_aq_get_set_rss_lut_send;
-       } else {
-               goto ice_aq_get_set_rss_lut_send;
-       }
+       desc_params = &desc.params.get_set_rss_lut;
+       vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
+       desc_params->vsi_id = cpu_to_le16(vsi_id | ICE_AQC_RSS_VSI_VALID);
 
-       /* LUT size is only valid for Global and PF table types */
-       switch (lut_size) {
-       case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128:
-               break;
-       case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512:
-               flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512_FLAG <<
-                         ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
-                        ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
-               break;
-       case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K:
-               if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF) {
-                       flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K_FLAG <<
-                                 ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
-                                ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
-                       break;
-               }
-               fallthrough;
-       default:
-               status = -EINVAL;
-               goto ice_aq_get_set_rss_lut_exit;
-       }
+       if (lut_type == ICE_LUT_GLOBAL)
+               glob_lut_idx = FIELD_PREP(ICE_AQC_LUT_GLOBAL_IDX,
+                                         params->global_lut_id);
 
-ice_aq_get_set_rss_lut_send:
-       cmd_resp->flags = cpu_to_le16(flags);
-       status = ice_aq_send_cmd(hw, &desc, lut, lut_size, NULL);
+       flags = lut_type | glob_lut_idx | ice_lut_size_to_flag(lut_size);
+       desc_params->flags = cpu_to_le16(flags);
 
-ice_aq_get_set_rss_lut_exit:
-       return status;
+       return ice_aq_send_cmd(hw, &desc, lut, lut_size, NULL);
 }
 
 /**
@@ -4016,12 +4055,10 @@ static int
 __ice_aq_get_set_rss_key(struct ice_hw *hw, u16 vsi_id,
                         struct ice_aqc_get_set_rss_keys *key, bool set)
 {
-       struct ice_aqc_get_set_rss_key *cmd_resp;
+       struct ice_aqc_get_set_rss_key *desc_params;
        u16 key_size = sizeof(*key);
        struct ice_aq_desc desc;
 
-       cmd_resp = &desc.params.get_set_rss_key;
-
        if (set) {
                ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_rss_key);
                desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
@@ -4029,10 +4066,8 @@ __ice_aq_get_set_rss_key(struct ice_hw *hw, u16 vsi_id,
                ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_rss_key);
        }
 
-       cmd_resp->vsi_id = cpu_to_le16(((vsi_id <<
-                                        ICE_AQC_GSET_RSS_KEY_VSI_ID_S) &
-                                       ICE_AQC_GSET_RSS_KEY_VSI_ID_M) |
-                                      ICE_AQC_GSET_RSS_KEY_VSI_VALID);
+       desc_params = &desc.params.get_set_rss_key;
+       desc_params->vsi_id = cpu_to_le16(vsi_id | ICE_AQC_RSS_VSI_VALID);
 
        return ice_aq_send_cmd(hw, &desc, key, key_size, NULL);
 }
index df12a9d..71b82cd 100644 (file)
@@ -93,6 +93,7 @@ int
 ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
                    struct ice_aqc_get_phy_caps_data *caps,
                    struct ice_sq_cd *cd);
+bool ice_is_pf_c827(struct ice_hw *hw);
 int
 ice_aq_list_caps(struct ice_hw *hw, void *buf, u16 buf_size, u32 *cap_count,
                 enum ice_adminq_opc opc, struct ice_sq_cd *cd);
index cc7357e..67bfd1f 100644 (file)
@@ -20,8 +20,23 @@ static const struct rhashtable_params ice_fdb_ht_params = {
 
 static bool ice_eswitch_br_is_dev_valid(const struct net_device *dev)
 {
-       /* Accept only PF netdev and PRs */
-       return ice_is_port_repr_netdev(dev) || netif_is_ice(dev);
+       /* Accept only PF netdev, PRs and LAG */
+       return ice_is_port_repr_netdev(dev) || netif_is_ice(dev) ||
+               netif_is_lag_master(dev);
+}
+
+static struct net_device *
+ice_eswitch_br_get_uplink_from_lag(struct net_device *lag_dev)
+{
+       struct net_device *lower;
+       struct list_head *iter;
+
+       netdev_for_each_lower_dev(lag_dev, lower, iter) {
+               if (netif_is_ice(lower))
+                       return lower;
+       }
+
+       return NULL;
 }
 
 static struct ice_esw_br_port *
@@ -31,8 +46,19 @@ ice_eswitch_br_netdev_to_port(struct net_device *dev)
                struct ice_repr *repr = ice_netdev_to_repr(dev);
 
                return repr->br_port;
-       } else if (netif_is_ice(dev)) {
-               struct ice_pf *pf = ice_netdev_to_pf(dev);
+       } else if (netif_is_ice(dev) || netif_is_lag_master(dev)) {
+               struct net_device *ice_dev;
+               struct ice_pf *pf;
+
+               if (netif_is_lag_master(dev))
+                       ice_dev = ice_eswitch_br_get_uplink_from_lag(dev);
+               else
+                       ice_dev = dev;
+
+               if (!ice_dev)
+                       return NULL;
+
+               pf = ice_netdev_to_pf(ice_dev);
 
                return pf->br_port;
        }
@@ -1085,7 +1111,18 @@ ice_eswitch_br_port_link(struct ice_esw_br_offloads *br_offloads,
                err = ice_eswitch_br_vf_repr_port_init(bridge, repr);
                trace_ice_eswitch_br_port_link(repr->br_port);
        } else {
-               struct ice_pf *pf = ice_netdev_to_pf(dev);
+               struct net_device *ice_dev;
+               struct ice_pf *pf;
+
+               if (netif_is_lag_master(dev))
+                       ice_dev = ice_eswitch_br_get_uplink_from_lag(dev);
+               else
+                       ice_dev = dev;
+
+               if (!ice_dev)
+                       return 0;
+
+               pf = ice_netdev_to_pf(ice_dev);
 
                err = ice_eswitch_br_uplink_port_init(bridge, pf);
                trace_ice_eswitch_br_port_link(pf->br_port);
index a92dc9a..531cc21 100644 (file)
 #define VP_MDET_TX_TCLAN_VALID_M               BIT(0)
 #define VP_MDET_TX_TDPU(_VF)                   (0x00040000 + ((_VF) * 4))
 #define VP_MDET_TX_TDPU_VALID_M                        BIT(0)
+#define GL_MNG_FWSM                            0x000B6134
+#define GL_MNG_FWSM_FW_LOADING_M               BIT(30)
 #define GLNVM_FLA                              0x000B6108
 #define GLNVM_FLA_LOCKED_M                     BIT(6)
 #define GLNVM_GENS                             0x000B6100
 #define VSIQF_FD_CNT_FD_BCNT_M                 ICE_M(0x3FFF, 16)
 #define VSIQF_FD_SIZE(_VSI)                    (0x00462000 + ((_VSI) * 4))
 #define VSIQF_HKEY_MAX_INDEX                   12
-#define VSIQF_HLUT_MAX_INDEX                   15
 #define PFPM_APM                               0x000B8080
 #define PFPM_APM_APME_M                                BIT(0)
 #define PFPM_WUFC                              0x0009DC00
index 077f2e9..927518f 100644 (file)
@@ -907,6 +907,7 @@ static void ice_vsi_set_rss_params(struct ice_vsi *vsi)
 {
        struct ice_hw_common_caps *cap;
        struct ice_pf *pf = vsi->back;
+       u16 max_rss_size;
 
        if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) {
                vsi->rss_size = 1;
@@ -914,32 +915,31 @@ static void ice_vsi_set_rss_params(struct ice_vsi *vsi)
        }
 
        cap = &pf->hw.func_caps.common_cap;
+       max_rss_size = BIT(cap->rss_table_entry_width);
        switch (vsi->type) {
        case ICE_VSI_CHNL:
        case ICE_VSI_PF:
                /* PF VSI will inherit RSS instance of PF */
                vsi->rss_table_size = (u16)cap->rss_table_size;
                if (vsi->type == ICE_VSI_CHNL)
-                       vsi->rss_size = min_t(u16, vsi->num_rxq,
-                                             BIT(cap->rss_table_entry_width));
+                       vsi->rss_size = min_t(u16, vsi->num_rxq, max_rss_size);
                else
                        vsi->rss_size = min_t(u16, num_online_cpus(),
-                                             BIT(cap->rss_table_entry_width));
-               vsi->rss_lut_type = ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF;
+                                             max_rss_size);
+               vsi->rss_lut_type = ICE_LUT_PF;
                break;
        case ICE_VSI_SWITCHDEV_CTRL:
-               vsi->rss_table_size = ICE_VSIQF_HLUT_ARRAY_SIZE;
-               vsi->rss_size = min_t(u16, num_online_cpus(),
-                                     BIT(cap->rss_table_entry_width));
-               vsi->rss_lut_type = ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_VSI;
+               vsi->rss_table_size = ICE_LUT_VSI_SIZE;
+               vsi->rss_size = min_t(u16, num_online_cpus(), max_rss_size);
+               vsi->rss_lut_type = ICE_LUT_VSI;
                break;
        case ICE_VSI_VF:
                /* VF VSI will get a small RSS table.
                 * For VSI_LUT, LUT size should be set to 64 bytes.
                 */
-               vsi->rss_table_size = ICE_VSIQF_HLUT_ARRAY_SIZE;
+               vsi->rss_table_size = ICE_LUT_VSI_SIZE;
                vsi->rss_size = ICE_MAX_RSS_QS_PER_VF;
-               vsi->rss_lut_type = ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_VSI;
+               vsi->rss_lut_type = ICE_LUT_VSI;
                break;
        case ICE_VSI_LB:
                break;
index 2e80d5c..0f04347 100644 (file)
@@ -4520,6 +4520,31 @@ static void ice_deinit_eth(struct ice_pf *pf)
        ice_decfg_netdev(vsi);
 }
 
+/**
+ * ice_wait_for_fw - wait for full FW readiness
+ * @hw: pointer to the hardware structure
+ * @timeout: milliseconds that can elapse before timing out
+ */
+static int ice_wait_for_fw(struct ice_hw *hw, u32 timeout)
+{
+       int fw_loading;
+       u32 elapsed = 0;
+
+       while (elapsed <= timeout) {
+               fw_loading = rd32(hw, GL_MNG_FWSM) & GL_MNG_FWSM_FW_LOADING_M;
+
+               /* firmware was not yet loaded, we have to wait more */
+               if (fw_loading) {
+                       elapsed += 100;
+                       msleep(100);
+                       continue;
+               }
+               return 0;
+       }
+
+       return -ETIMEDOUT;
+}
+
 static int ice_init_dev(struct ice_pf *pf)
 {
        struct device *dev = ice_pf_to_dev(pf);
@@ -4532,6 +4557,18 @@ static int ice_init_dev(struct ice_pf *pf)
                return err;
        }
 
+       /* Some cards require longer initialization times
+        * due to necessity of loading FW from an external source.
+        * This can take even half a minute.
+        */
+       if (ice_is_pf_c827(hw)) {
+               err = ice_wait_for_fw(hw, 30000);
+               if (err) {
+                       dev_err(dev, "ice_wait_for_fw timed out");
+                       return err;
+               }
+       }
+
        ice_init_feature_support(pf);
 
        ice_request_fw(pf);
index 6a93647..f6f2736 100644 (file)
@@ -287,6 +287,7 @@ struct ice_nvgre_hdr {
  * M = EVLAN (0x8100) - Outer L2 header has EVLAN (ethernet type 0x8100)
  * N = EVLAN (0x9100) - Outer L2 header has EVLAN (ethernet type 0x9100)
  */
+#define ICE_PKT_FROM_NETWORK   BIT(3)
 #define ICE_PKT_VLAN_STAG      BIT(12)
 #define ICE_PKT_VLAN_ITAG      BIT(13)
 #define ICE_PKT_VLAN_EVLAN     (BIT(14) | BIT(15))
@@ -392,10 +393,10 @@ enum ice_hw_metadata_offset {
 };
 
 enum ice_pkt_flags {
-       ICE_PKT_FLAGS_VLAN = 0,
-       ICE_PKT_FLAGS_TUNNEL = 1,
-       ICE_PKT_FLAGS_TCP = 2,
-       ICE_PKT_FLAGS_ERROR = 3,
+       ICE_PKT_FLAGS_MDID20 = 0,
+       ICE_PKT_FLAGS_MDID21 = 1,
+       ICE_PKT_FLAGS_MDID22 = 2,
+       ICE_PKT_FLAGS_MDID23 = 3,
 };
 
 struct ice_hw_metadata {
index 3b68cb9..1969425 100644 (file)
@@ -112,6 +112,9 @@ struct ice_cgu_pll_params_e822 {
 extern const struct
 ice_cgu_pll_params_e822 e822_cgu_params[NUM_ICE_TIME_REF_FREQ];
 
+#define E810C_QSFP_C827_0_HANDLE 2
+#define E810C_QSFP_C827_1_HANDLE 3
+
 /* Table of constants related to possible TIME_REF sources */
 extern const struct ice_time_ref_info_e822 e822_time_ref[NUM_ICE_TIME_REF_FREQ];
 
index 91bc92f..a7afb61 100644 (file)
@@ -6058,14 +6058,21 @@ ice_adv_add_update_vsi_list(struct ice_hw *hw,
 void ice_rule_add_tunnel_metadata(struct ice_adv_lkup_elem *lkup)
 {
        lkup->type = ICE_HW_METADATA;
-       lkup->m_u.metadata.flags[ICE_PKT_FLAGS_TUNNEL] =
+       lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID21] |=
                cpu_to_be16(ICE_PKT_TUNNEL_MASK);
 }
 
+void ice_rule_add_direction_metadata(struct ice_adv_lkup_elem *lkup)
+{
+       lkup->type = ICE_HW_METADATA;
+       lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID20] |=
+               cpu_to_be16(ICE_PKT_FROM_NETWORK);
+}
+
 void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup)
 {
        lkup->type = ICE_HW_METADATA;
-       lkup->m_u.metadata.flags[ICE_PKT_FLAGS_VLAN] =
+       lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID20] |=
                cpu_to_be16(ICE_PKT_VLAN_MASK);
 }
 
index 250823a..0bd4320 100644 (file)
@@ -359,6 +359,7 @@ int ice_share_res(struct ice_hw *hw, u16 type, u8 shared, u16 res_id);
 
 /* Switch/bridge related commands */
 void ice_rule_add_tunnel_metadata(struct ice_adv_lkup_elem *lkup);
+void ice_rule_add_direction_metadata(struct ice_adv_lkup_elem *lkup);
 void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup);
 void ice_rule_add_src_vsi_metadata(struct ice_adv_lkup_elem *lkup);
 int
index 38547db..37b54db 100644 (file)
@@ -7,6 +7,8 @@
 #include "ice_lib.h"
 #include "ice_protocol_type.h"
 
+#define ICE_TC_METADATA_LKUP_IDX 0
+
 /**
  * ice_tc_count_lkups - determine lookup count for switch filter
  * @flags: TC-flower flags
@@ -19,7 +21,13 @@ static int
 ice_tc_count_lkups(u32 flags, struct ice_tc_flower_lyr_2_4_hdrs *headers,
                   struct ice_tc_flower_fltr *fltr)
 {
-       int lkups_cnt = 0;
+       int lkups_cnt = 1; /* 0th lookup is metadata */
+
+       /* Always add metadata as the 0th lookup. Included elements:
+        * - Direction flag (always present)
+        * - ICE_TC_FLWR_FIELD_VLAN_TPID (present if specified)
+        * - Tunnel flag (present if tunnel)
+        */
 
        if (flags & ICE_TC_FLWR_FIELD_TENANT_ID)
                lkups_cnt++;
@@ -54,10 +62,6 @@ ice_tc_count_lkups(u32 flags, struct ice_tc_flower_lyr_2_4_hdrs *headers,
        if (flags & (ICE_TC_FLWR_FIELD_VLAN | ICE_TC_FLWR_FIELD_VLAN_PRIO))
                lkups_cnt++;
 
-       /* is VLAN TPID specified */
-       if (flags & ICE_TC_FLWR_FIELD_VLAN_TPID)
-               lkups_cnt++;
-
        /* is CVLAN specified? */
        if (flags & (ICE_TC_FLWR_FIELD_CVLAN | ICE_TC_FLWR_FIELD_CVLAN_PRIO))
                lkups_cnt++;
@@ -84,10 +88,6 @@ ice_tc_count_lkups(u32 flags, struct ice_tc_flower_lyr_2_4_hdrs *headers,
                     ICE_TC_FLWR_FIELD_SRC_L4_PORT))
                lkups_cnt++;
 
-       /* matching for tunneled packets in metadata */
-       if (fltr->tunnel_type != TNL_LAST)
-               lkups_cnt++;
-
        return lkups_cnt;
 }
 
@@ -176,10 +176,9 @@ static u16 ice_check_supported_vlan_tpid(u16 vlan_tpid)
 
 static int
 ice_tc_fill_tunnel_outer(u32 flags, struct ice_tc_flower_fltr *fltr,
-                        struct ice_adv_lkup_elem *list)
+                        struct ice_adv_lkup_elem *list, int i)
 {
        struct ice_tc_flower_lyr_2_4_hdrs *hdr = &fltr->outer_headers;
-       int i = 0;
 
        if (flags & ICE_TC_FLWR_FIELD_TENANT_ID) {
                u32 tenant_id;
@@ -329,8 +328,7 @@ ice_tc_fill_tunnel_outer(u32 flags, struct ice_tc_flower_fltr *fltr,
        }
 
        /* always fill matching on tunneled packets in metadata */
-       ice_rule_add_tunnel_metadata(&list[i]);
-       i++;
+       ice_rule_add_tunnel_metadata(&list[ICE_TC_METADATA_LKUP_IDX]);
 
        return i;
 }
@@ -358,13 +356,16 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags,
        struct ice_tc_flower_lyr_2_4_hdrs *headers = &tc_fltr->outer_headers;
        bool inner = false;
        u16 vlan_tpid = 0;
-       int i = 0;
+       int i = 1; /* 0th lookup is metadata */
 
        rule_info->vlan_type = vlan_tpid;
 
+       /* Always add direction metadata */
+       ice_rule_add_direction_metadata(&list[ICE_TC_METADATA_LKUP_IDX]);
+
        rule_info->tun_type = ice_sw_type_from_tunnel(tc_fltr->tunnel_type);
        if (tc_fltr->tunnel_type != TNL_LAST) {
-               i = ice_tc_fill_tunnel_outer(flags, tc_fltr, list);
+               i = ice_tc_fill_tunnel_outer(flags, tc_fltr, list, i);
 
                headers = &tc_fltr->inner_headers;
                inner = true;
@@ -431,8 +432,7 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags,
                rule_info->vlan_type =
                                ice_check_supported_vlan_tpid(vlan_tpid);
 
-               ice_rule_add_vlan_metadata(&list[i]);
-               i++;
+               ice_rule_add_vlan_metadata(&list[ICE_TC_METADATA_LKUP_IDX]);
        }
 
        if (flags & (ICE_TC_FLWR_FIELD_CVLAN | ICE_TC_FLWR_FIELD_CVLAN_PRIO)) {
index e82f38c..5e353b0 100644 (file)
@@ -1040,10 +1040,10 @@ enum ice_sw_fwd_act_type {
 };
 
 struct ice_aq_get_set_rss_lut_params {
-       u16 vsi_handle;         /* software VSI handle */
-       u16 lut_size;           /* size of the LUT buffer */
-       u8 lut_type;            /* type of the LUT (i.e. VSI, PF, Global) */
        u8 *lut;                /* input RSS LUT for set and output RSS LUT for get */
+       enum ice_lut_size lut_size; /* size of the LUT buffer */
+       enum ice_lut_type lut_type; /* type of the LUT (i.e. VSI, PF, Global) */
+       u16 vsi_handle;         /* software VSI handle */
        u8 global_lut_id;       /* only valid when lut_type is global */
 };
 
@@ -1145,9 +1145,6 @@ struct ice_aq_get_set_rss_lut_params {
 
 #define ICE_SR_WORDS_IN_1KB            512
 
-/* Hash redirection LUT for VSI - maximum array size */
-#define ICE_VSIQF_HLUT_ARRAY_SIZE      ((VSIQF_HLUT_MAX_INDEX + 1) * 4)
-
 /* AQ API version for LLDP_FILTER_CONTROL */
 #define ICE_FW_API_LLDP_FLTR_MAJ       1
 #define ICE_FW_API_LLDP_FLTR_MIN       7
index 625da88..85d9965 100644 (file)
@@ -500,7 +500,7 @@ static int ice_vc_get_vf_res_msg(struct ice_vf *vf, u8 *msg)
        vfres->num_queue_pairs = vsi->num_txq;
        vfres->max_vectors = vf->pf->vfs.num_msix_per;
        vfres->rss_key_size = ICE_VSIQF_HKEY_ARRAY_SIZE;
-       vfres->rss_lut_size = ICE_VSIQF_HLUT_ARRAY_SIZE;
+       vfres->rss_lut_size = ICE_LUT_VSI_SIZE;
        vfres->max_mtu = ice_vc_get_max_frame_size(vf);
 
        vfres->vsi_res[0].vsi_id = vf->lan_vsi_num;
@@ -962,7 +962,7 @@ static int ice_vc_config_rss_lut(struct ice_vf *vf, u8 *msg)
                goto error_param;
        }
 
-       if (vrl->lut_entries != ICE_VSIQF_HLUT_ARRAY_SIZE) {
+       if (vrl->lut_entries != ICE_LUT_VSI_SIZE) {
                v_ret = VIRTCHNL_STATUS_ERR_PARAM;
                goto error_param;
        }
@@ -978,7 +978,7 @@ static int ice_vc_config_rss_lut(struct ice_vf *vf, u8 *msg)
                goto error_param;
        }
 
-       if (ice_set_rss_lut(vsi, vrl->lut, ICE_VSIQF_HLUT_ARRAY_SIZE))
+       if (ice_set_rss_lut(vsi, vrl->lut, ICE_LUT_VSI_SIZE))
                v_ret = VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR;
 error_param:
        return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_RSS_LUT, v_ret,