summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel/ice/ice_fdir.c
diff options
context:
space:
mode:
authorQi Zhang <qi.z.zhang@intel.com>2021-03-09 06:07:59 +0300
committerTony Nguyen <anthony.l.nguyen@intel.com>2021-03-22 21:32:11 +0300
commitb199dddbd399536d5470e10e6bfd7d0e1b5fb71a (patch)
tree0c219fbcf944dc75f53d536a127dee533a40718b /drivers/net/ethernet/intel/ice/ice_fdir.c
parent390bd141808d5019506f0f53a777c3b9cb7c5c62 (diff)
downloadlinux-b199dddbd399536d5470e10e6bfd7d0e1b5fb71a.tar.xz
ice: Support non word aligned input set field
To support FDIR input set with protocol field like DSCP, TTL, PROT, etc. which is not word aligned, we need to enable field vector masking. Signed-off-by: Dan Nowlin <dan.nowlin@intel.com> Signed-off-by: Qi Zhang <qi.z.zhang@intel.com> Tested-by: Chen Bo <BoX.C.Chen@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_fdir.c')
-rw-r--r--drivers/net/ethernet/intel/ice/ice_fdir.c62
1 files changed, 55 insertions, 7 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_fdir.c b/drivers/net/ethernet/intel/ice/ice_fdir.c
index 1e77f43b3b3e..0c2066c0ab1f 100644
--- a/drivers/net/ethernet/intel/ice/ice_fdir.c
+++ b/drivers/net/ethernet/intel/ice/ice_fdir.c
@@ -471,6 +471,39 @@ static void ice_pkt_insert_ipv6_addr(u8 *pkt, int offset, __be32 *addr)
}
/**
+ * ice_pkt_insert_u8 - insert a u8 value into a memory buffer.
+ * @pkt: packet buffer
+ * @offset: offset into buffer
+ * @data: 8 bit value to convert and insert into pkt at offset
+ */
+static void ice_pkt_insert_u8(u8 *pkt, int offset, u8 data)
+{
+ memcpy(pkt + offset, &data, sizeof(data));
+}
+
+/**
+ * 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);
+ memcpy(pkt + offset, &high, sizeof(high));
+
+ low = (*(pkt + offset + 1) & 0x0F) + ((data & 0x0F) << 4);
+ memcpy(pkt + offset + 1, &low, sizeof(low));
+}
+
+/**
* ice_pkt_insert_u16 - insert a be16 value into a memory buffer
* @pkt: packet buffer
* @offset: offset into buffer
@@ -530,11 +563,9 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
case IPPROTO_SCTP:
flow = ICE_FLTR_PTYPE_NONF_IPV4_SCTP;
break;
- case IPPROTO_IP:
+ default:
flow = ICE_FLTR_PTYPE_NONF_IPV4_OTHER;
break;
- default:
- return ICE_ERR_PARAM;
}
} else if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) {
switch (input->ip.v6.proto) {
@@ -547,11 +578,9 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
case IPPROTO_SCTP:
flow = ICE_FLTR_PTYPE_NONF_IPV6_SCTP;
break;
- case IPPROTO_IP:
+ default:
flow = ICE_FLTR_PTYPE_NONF_IPV6_OTHER;
break;
- default:
- return ICE_ERR_PARAM;
}
} else {
flow = input->flow_type;
@@ -590,6 +619,8 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
input->ip.v4.dst_ip);
ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET,
input->ip.v4.dst_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;
@@ -603,6 +634,8 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
input->ip.v4.dst_ip);
ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET,
input->ip.v4.dst_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);
ice_pkt_insert_mac_addr(loc + ETH_ALEN,
input->ext_data.src_mac);
@@ -616,6 +649,8 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
input->ip.v4.dst_ip);
ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_SRC_PORT_OFFSET,
input->ip.v4.dst_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:
@@ -623,7 +658,10 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
input->ip.v4.src_ip);
ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
input->ip.v4.dst_ip);
- ice_pkt_insert_u16(loc, ICE_IPV4_PROTO_OFFSET, 0);
+ 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_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:
@@ -635,6 +673,8 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
input->ip.v6.src_port);
ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET,
input->ip.v6.dst_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:
@@ -646,6 +686,8 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
input->ip.v6.src_port);
ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET,
input->ip.v6.dst_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:
@@ -657,6 +699,8 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
input->ip.v6.src_port);
ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET,
input->ip.v6.dst_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:
@@ -664,6 +708,10 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
input->ip.v6.src_ip);
ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET,
input->ip.v6.dst_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: