net/ena: update version to 2.0.1
[dpdk.git] / drivers / net / ice / base / ice_switch.c
index 22de281..be43c8b 100644 (file)
@@ -61,10 +61,11 @@ struct ice_dummy_pkt_offsets {
 static const
 struct ice_dummy_pkt_offsets dummy_gre_packet_offsets[] = {
        { ICE_MAC_OFOS,         0 },
+       { ICE_ETYPE_OL,         12 },
        { ICE_IPV4_OFOS,        14 },
        { ICE_NVGRE,            34 },
        { ICE_MAC_IL,           42 },
-       { ICE_IPV4_IL,          54 },
+       { ICE_IPV4_IL,          56 },
        { ICE_PROTOCOL_LAST,    0 },
 };
 
@@ -72,7 +73,7 @@ static const
 u8 dummy_gre_packet[] = { 0, 0, 0, 0,          /* ICE_MAC_OFOS 0 */
                          0, 0, 0, 0,
                          0, 0, 0, 0,
-                         0x08, 0,
+                         0x08, 0,              /* ICE_ETYPE_OL 12 */
                          0x45, 0, 0, 0x3E,     /* ICE_IPV4_OFOS 14 */
                          0, 0, 0, 0,
                          0, 0x2F, 0, 0,
@@ -94,6 +95,7 @@ u8 dummy_gre_packet[] = { 0, 0, 0, 0,         /* ICE_MAC_OFOS 0 */
 static const
 struct ice_dummy_pkt_offsets dummy_udp_tun_tcp_packet_offsets[] = {
        { ICE_MAC_OFOS,         0 },
+       { ICE_ETYPE_OL,         12 },
        { ICE_IPV4_OFOS,        14 },
        { ICE_UDP_OF,           34 },
        { ICE_VXLAN,            42 },
@@ -108,7 +110,8 @@ u8 dummy_udp_tun_tcp_packet[] = {
        0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
-       0x08, 0x00,
+
+       0x08, 0x00,             /* ICE_ETYPE_OL 12 */
 
        0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */
        0x00, 0x01, 0x00, 0x00,
@@ -143,6 +146,7 @@ u8 dummy_udp_tun_tcp_packet[] = {
 static const
 struct ice_dummy_pkt_offsets dummy_udp_tun_udp_packet_offsets[] = {
        { ICE_MAC_OFOS,         0 },
+       { ICE_ETYPE_OL,         12 },
        { ICE_IPV4_OFOS,        14 },
        { ICE_UDP_OF,           34 },
        { ICE_VXLAN,            42 },
@@ -157,7 +161,8 @@ u8 dummy_udp_tun_udp_packet[] = {
        0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
-       0x08, 0x00,
+
+       0x08, 0x00,             /* ICE_ETYPE_OL 12 */
 
        0x45, 0x00, 0x00, 0x4e, /* ICE_IPV4_OFOS 14 */
        0x00, 0x01, 0x00, 0x00,
@@ -189,6 +194,7 @@ u8 dummy_udp_tun_udp_packet[] = {
 static const
 struct ice_dummy_pkt_offsets dummy_udp_packet_offsets[] = {
        { ICE_MAC_OFOS,         0 },
+       { ICE_ETYPE_OL,         12 },
        { ICE_IPV4_OFOS,        14 },
        { ICE_UDP_ILOS,         34 },
        { ICE_PROTOCOL_LAST,    0 },
@@ -199,7 +205,8 @@ dummy_udp_packet[] = {
        0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
-       0x08, 0x00,
+
+       0x08, 0x00,             /* ICE_ETYPE_OL 12 */
 
        0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 14 */
        0x00, 0x01, 0x00, 0x00,
@@ -216,6 +223,7 @@ dummy_udp_packet[] = {
 static const
 struct ice_dummy_pkt_offsets dummy_tcp_packet_offsets[] = {
        { ICE_MAC_OFOS,         0 },
+       { ICE_ETYPE_OL,         12 },
        { ICE_IPV4_OFOS,        14 },
        { ICE_TCP_IL,           34 },
        { ICE_PROTOCOL_LAST,    0 },
@@ -226,7 +234,8 @@ dummy_tcp_packet[] = {
        0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
-       0x08, 0x00,
+
+       0x08, 0x00,             /* ICE_ETYPE_OL 12 */
 
        0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 14 */
        0x00, 0x01, 0x00, 0x00,
@@ -243,23 +252,98 @@ dummy_tcp_packet[] = {
        0x00, 0x00,     /* 2 bytes for 4 byte alignment */
 };
 
+static const
+struct ice_dummy_pkt_offsets dummy_tcp_ipv6_packet_offsets[] = {
+       { ICE_MAC_OFOS,         0 },
+       { ICE_ETYPE_OL,         12 },
+       { ICE_IPV6_OFOS,        14 },
+       { ICE_TCP_IL,           54 },
+       { ICE_PROTOCOL_LAST,    0 },
+};
+
+static const u8
+dummy_tcp_ipv6_packet[] = {
+       0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+
+       0x86, 0xDD,             /* ICE_ETYPE_OL 12 */
+
+       0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
+       0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 54 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x50, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, /* 2 bytes for 4 byte alignment */
+};
+
+static const
+struct ice_dummy_pkt_offsets dummy_udp_ipv6_packet_offsets[] = {
+       { ICE_MAC_OFOS,         0 },
+       { ICE_ETYPE_OL,         12 },
+       { ICE_IPV6_OFOS,        14 },
+       { ICE_UDP_ILOS,         54 },
+       { ICE_PROTOCOL_LAST,    0 },
+};
+
+static const u8
+dummy_udp_ipv6_packet[] = {
+       0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+
+       0x86, 0xDD,             /* ICE_ETYPE_OL 12 */
+
+       0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
+       0x00, 0x08, 0x11, 0x00, /* Next header UDP*/
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00,
+
+       0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 54 */
+       0x00, 0x08, 0x00, 0x00,
+
+       0x00, 0x00, /* 2 bytes for 4 byte alignment */
+};
+
 /* this is a recipe to profile bitmap association */
 static ice_declare_bitmap(recipe_to_profile[ICE_MAX_NUM_RECIPES],
                          ICE_MAX_NUM_PROFILES);
 static ice_declare_bitmap(available_result_ids, ICE_CHAIN_FV_INDEX_START + 1);
 
+static void ice_get_recp_to_prof_map(struct ice_hw *hw);
+
 /**
  * ice_get_recp_frm_fw - update SW bookkeeping from FW recipe entries
  * @hw: pointer to hardware structure
  * @recps: struct that we need to populate
  * @rid: recipe ID that we are populating
+ * @refresh_required: true if we should get recipe to profile mapping from FW
  *
  * This function is used to populate all the necessary entries into our
  * bookkeeping so that we have a current list of all the recipes that are
  * programmed in the firmware.
  */
 static enum ice_status
-ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid)
+ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid,
+                   bool *refresh_required)
 {
        u16 i, sub_recps, fv_word_idx = 0, result_idx = 0;
        ice_declare_bitmap(r_bitmap, ICE_MAX_NUM_PROFILES);
@@ -280,6 +364,19 @@ ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid)
        /* non-zero status meaning recipe doesn't exist */
        if (status)
                goto err_unroll;
+
+       /* Get recipe to profile map so that we can get the fv from lkups that
+        * we read for a recipe from FW. Since we want to minimize the number of
+        * times we make this FW call, just make one call and cache the copy
+        * until a new recipe is added. This operation is only required the
+        * first time to get the changes from FW. Then to search existing
+        * entries we don't need to update the cache again until another recipe
+        * gets added.
+        */
+       if (*refresh_required) {
+               ice_get_recp_to_prof_map(hw);
+               *refresh_required = false;
+       }
        lkup_exts = &recps[rid].lkup_exts;
        /* start populating all the entries for recps[rid] based on lkups from
         * firmware
@@ -4371,6 +4468,7 @@ exit_error:
 static const struct ice_prot_ext_tbl_entry ice_prot_ext[] = {
        { ICE_MAC_OFOS,         { 0, 2, 4, 6, 8, 10, 12 } },
        { ICE_MAC_IL,           { 0, 2, 4, 6, 8, 10, 12 } },
+       { ICE_ETYPE_OL,         { 0 } },
        { ICE_IPV4_OFOS,        { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
        { ICE_IPV4_IL,          { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
        { ICE_IPV6_IL,          { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
@@ -4384,7 +4482,7 @@ static const struct ice_prot_ext_tbl_entry ice_prot_ext[] = {
        { ICE_VXLAN,            { 8, 10, 12, 14 } },
        { ICE_GENEVE,           { 8, 10, 12, 14 } },
        { ICE_VXLAN_GPE,        { 0, 2, 4 } },
-       { ICE_NVGRE,            { 0, 2 } },
+       { ICE_NVGRE,            { 0, 2, 4, 6 } },
        { ICE_PROTOCOL_LAST,    { 0 } }
 };
 
@@ -4408,6 +4506,7 @@ static const struct ice_pref_recipe_group ice_recipe_pack[] = {
 static const struct ice_protocol_entry ice_prot_id_tbl[] = {
        { ICE_MAC_OFOS,         ICE_MAC_OFOS_HW },
        { ICE_MAC_IL,           ICE_MAC_IL_HW },
+       { ICE_ETYPE_OL,         ICE_ETYPE_OL_HW },
        { ICE_IPV4_OFOS,        ICE_IPV4_OFOS_HW },
        { ICE_IPV4_IL,          ICE_IPV4_IL_HW },
        { ICE_IPV6_OFOS,        ICE_IPV6_OFOS_HW },
@@ -4432,10 +4531,10 @@ static const struct ice_protocol_entry ice_prot_id_tbl[] = {
  */
 static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts)
 {
+       bool refresh_required = true;
        struct ice_sw_recipe *recp;
        u16 i;
 
-       ice_get_recp_to_prof_map(hw);
        /* Initialize available_result_ids which tracks available result idx */
        for (i = 0; i <= ICE_CHAIN_FV_INDEX_START; i++)
                ice_set_bit(ICE_CHAIN_FV_INDEX_START - i,
@@ -4451,7 +4550,8 @@ static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts)
                 */
                if (!recp[i].recp_created)
                        if (ice_get_recp_frm_fw(hw,
-                                               hw->switch_info->recp_list, i))
+                                               hw->switch_info->recp_list, i,
+                                               &refresh_required))
                                continue;
 
                /* if number of words we are looking for match */
@@ -4533,7 +4633,7 @@ ice_fill_valid_words(struct ice_adv_lkup_elem *rule,
 
        for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++)
                if (((u16 *)&rule->m_u)[j] &&
-                   rule->type < ARRAY_SIZE(ice_prot_ext)) {
+                   (unsigned long)rule->type < ARRAY_SIZE(ice_prot_ext)) {
                        /* No more space to accommodate */
                        if (word >= ICE_MAX_CHAIN_WORDS)
                                return 0;
@@ -5257,7 +5357,7 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
                      u16 *pkt_len,
                      const struct ice_dummy_pkt_offsets **offsets)
 {
-       bool tcp = false, udp = false;
+       bool tcp = false, udp = false, ipv6 = false;
        u16 i;
 
        for (i = 0; i < lkups_cnt; i++) {
@@ -5265,6 +5365,8 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
                        udp = true;
                else if (lkups[i].type == ICE_TCP_IL)
                        tcp = true;
+               else if (lkups[i].type == ICE_IPV6_OFOS)
+                       ipv6 = true;
        }
 
        if (tun_type == ICE_SW_TUN_NVGRE || tun_type == ICE_ALL_TUNNELS) {
@@ -5289,11 +5391,21 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
                return;
        }
 
-       if (udp) {
+       if (udp && !ipv6) {
                *pkt = dummy_udp_packet;
                *pkt_len = sizeof(dummy_udp_packet);
                *offsets = dummy_udp_packet_offsets;
                return;
+       } else if (udp && ipv6) {
+               *pkt = dummy_udp_ipv6_packet;
+               *pkt_len = sizeof(dummy_udp_ipv6_packet);
+               *offsets = dummy_udp_ipv6_packet_offsets;
+               return;
+       } else if ((tcp && ipv6) || ipv6) {
+               *pkt = dummy_tcp_ipv6_packet;
+               *pkt_len = sizeof(dummy_tcp_ipv6_packet);
+               *offsets = dummy_tcp_ipv6_packet_offsets;
+               return;
        }
 
        *pkt = dummy_tcp_packet;
@@ -5353,10 +5465,17 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
                case ICE_MAC_IL:
                        len = sizeof(struct ice_ether_hdr);
                        break;
+               case ICE_ETYPE_OL:
+                       len = sizeof(struct ice_ethtype_hdr);
+                       break;
                case ICE_IPV4_OFOS:
                case ICE_IPV4_IL:
                        len = sizeof(struct ice_ipv4_hdr);
                        break;
+               case ICE_IPV6_OFOS:
+               case ICE_IPV6_IL:
+                       len = sizeof(struct ice_ipv6_hdr);
+                       break;
                case ICE_TCP_IL:
                case ICE_UDP_OF:
                case ICE_UDP_ILOS: