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 },
};
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,
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 },
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,
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 },
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,
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 },
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,
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 },
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,
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);
/* 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
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,
{ 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 } }
};
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 },
*/
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,
*/
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 */
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;
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++) {
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) {
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;
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: