Skip to content

Commit

Permalink
ice: Support non word aligned input set field
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Qi Zhang authored and Tony Nguyen committed Mar 22, 2021
1 parent 390bd14 commit b199ddd
Show file tree
Hide file tree
Showing 8 changed files with 623 additions and 36 deletions.
62 changes: 55 additions & 7 deletions drivers/net/ethernet/intel/ice/ice_fdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,39 @@ static void ice_pkt_insert_ipv6_addr(u8 *pkt, int offset, __be32 *addr)
sizeof(*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
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -616,14 +649,19 @@ 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:
ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
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:
Expand All @@ -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:
Expand All @@ -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:
Expand All @@ -657,13 +699,19 @@ 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:
ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET,
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:
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_fdir.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
#define ICE_IPV6_UDP_DST_PORT_OFFSET 56
#define ICE_IPV6_SCTP_SRC_PORT_OFFSET 54
#define ICE_IPV6_SCTP_DST_PORT_OFFSET 56
#define ICE_IPV4_TOS_OFFSET 15
#define ICE_IPV4_TTL_OFFSET 22
#define ICE_IPV6_TC_OFFSET 14
#define ICE_IPV6_HLIM_OFFSET 21
#define ICE_IPV6_PROTO_OFFSET 20

/* IP v4 has 2 flag bits that enable fragment processing: DF and MF. DF
* requests that the packet not be fragmented. MF indicates that a packet has
* been fragmented.
Expand Down Expand Up @@ -86,6 +92,7 @@ struct ice_fdir_v4 {
u8 tos;
u8 ip_ver;
u8 proto;
u8 ttl;
};

#define ICE_IPV6_ADDR_LEN_AS_U32 4
Expand All @@ -99,6 +106,7 @@ struct ice_fdir_v6 {
__be32 sec_parm_idx; /* security parameter index */
u8 tc;
u8 proto;
u8 hlim;
};

struct ice_fdir_extra {
Expand Down
Loading

0 comments on commit b199ddd

Please sign in to comment.