net/ice/base: support destination MAC field for FDIR
[dpdk.git] / drivers / net / ice / base / ice_fdir.c
index db5bbc6..3a2175b 100644 (file)
@@ -343,10 +343,13 @@ ice_fdir_get_prgm_desc(struct ice_hw *hw, struct ice_fdir_fltr *input,
                fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_YES;
                fdir_fltr_ctx.qindex = 0;
        } else {
+               if (input->dest_ctl ==
+                   ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QGROUP)
+                       fdir_fltr_ctx.toq = input->q_region;
                fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO;
                fdir_fltr_ctx.qindex = input->q_index;
        }
-       fdir_fltr_ctx.cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS;
+       fdir_fltr_ctx.cnt_ena = input->cnt_ena;
        fdir_fltr_ctx.cnt_index = input->cnt_index;
        fdir_fltr_ctx.fd_vsi = ice_get_hw_vsi_num(hw, input->dest_vsi);
        fdir_fltr_ctx.evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_FALSE;
@@ -495,6 +498,28 @@ static void ice_pkt_insert_u8(u8 *pkt, int offset, u8 data)
        ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA);
 }
 
+/**
+ * ice_pkt_insert_u8_tc - insert a u8 value into a memory buffer for tc ipv6.
+ * @pkt: packet buffer
+ * @offset: offset into buffer
+ * @data: 8 bit value to convert and insert into pkt at offset
+ *
+ * This function is designed for inserting Traffic Class (tc) for IPv6,
+ * since that tc is not aligned in number of bytes. Here we split it out
+ * into two part and fill each byte with data copy from pkt, then insert
+ * the two bytes data one by one.
+ */
+static void ice_pkt_insert_u8_tc(u8 *pkt, int offset, u8 data)
+{
+       u8 high, low;
+
+       high = (data >> 4) + (*(pkt + offset) & 0xF0);
+       ice_memcpy(pkt + offset, &high, sizeof(high), ICE_NONDMA_TO_NONDMA);
+
+       low = (*(pkt + offset + 1) & 0x0F) + ((data & 0x0F) << 4);
+       ice_memcpy(pkt + offset + 1, &low, sizeof(low), ICE_NONDMA_TO_NONDMA);
+}
+
 /**
  * ice_pkt_insert_u16 - insert a be16 value into a memory buffer.
  * @pkt: packet buffer
@@ -517,6 +542,17 @@ static void ice_pkt_insert_u32(u8 *pkt, int offset, __be32 data)
        ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA);
 }
 
+/**
+ * ice_pkt_insert_mac_addr - insert a MAC addr into a memory buffer.
+ * @pkt: packet buffer
+ * @offset: offset into buffer
+ * @addr: MAC address to convert and insert into pkt at offset
+ */
+static void ice_pkt_insert_mac_addr(u8 *pkt, u8 *addr)
+{
+       ice_memcpy(pkt, addr, ETH_ALEN, ICE_NONDMA_TO_NONDMA);
+}
+
 /**
  * ice_fdir_get_gen_prgm_pkt - generate a training packet
  * @hw: pointer to the hardware structure
@@ -601,6 +637,7 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
                                   input->ip.v4.src_port);
                ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
                ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
+               ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
                if (frag)
                        loc[20] = ICE_FDIR_IPV4_PKT_FLAG_DF;
                break;
@@ -615,6 +652,7 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
                                   input->ip.v4.src_port);
                ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
                ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
+               ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
                break;
        case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
                ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
@@ -627,6 +665,7 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
                                   input->ip.v4.src_port);
                ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos);
                ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
+               ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
                break;
        case ICE_FLTR_PTYPE_NONF_IPV4_OTHER:
                ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
@@ -637,6 +676,7 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
                ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl);
                ice_pkt_insert_u8(loc, ICE_IPV4_PROTO_OFFSET,
                                  input->ip.v4.proto);
+               ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
                break;
        case ICE_FLTR_PTYPE_NONF_IPV6_TCP:
                ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
@@ -647,6 +687,9 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
                                   input->ip.v6.dst_port);
                ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET,
                                   input->ip.v6.src_port);
+               ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
+               ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
+               ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
                break;
        case ICE_FLTR_PTYPE_NONF_IPV6_UDP:
                ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
@@ -657,6 +700,9 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
                                   input->ip.v6.dst_port);
                ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET,
                                   input->ip.v6.src_port);
+               ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
+               ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
+               ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
                break;
        case ICE_FLTR_PTYPE_NONF_IPV6_SCTP:
                ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
@@ -667,12 +713,20 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
                                   input->ip.v6.dst_port);
                ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET,
                                   input->ip.v6.src_port);
+               ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
+               ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
+               ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
                break;
        case ICE_FLTR_PTYPE_NONF_IPV6_OTHER:
                ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
                                         input->ip.v6.dst_ip);
                ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
                                         input->ip.v6.src_ip);
+               ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc);
+               ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim);
+               ice_pkt_insert_u8(loc, ICE_IPV6_PROTO_OFFSET,
+                                 input->ip.v6.proto);
+               ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
                break;
        default:
                return ICE_ERR_PARAM;