#define ICE_FLOW_FLD_SZ_GTP_TEID 4
#define ICE_FLOW_FLD_SZ_PPPOE_SESS_ID 2
-/* Protocol header fields are extracted at the word boundaries as word-sized
- * values. Specify the displacement value of some non-word-aligned fields needed
- * to compute the offset of words containing the fields in the corresponding
- * protocol headers. Displacement values are expressed in number of bits.
- */
-#define ICE_FLOW_FLD_IPV6_TTL_DSCP_DISP (-4)
-#define ICE_FLOW_FLD_IPV6_TTL_PROT_DISP ((-2) * BITS_PER_BYTE)
-#define ICE_FLOW_FLD_IPV6_TTL_TTL_DISP ((-1) * BITS_PER_BYTE)
-
/* Describe properties of a protocol header field */
struct ice_flow_field_info {
enum ice_flow_seg_hdr hdr;
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_VLAN, 14, ICE_FLOW_FLD_SZ_VLAN),
/* ICE_FLOW_FIELD_IDX_ETH_TYPE */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_ETH, 12, ICE_FLOW_FLD_SZ_ETH_TYPE),
- /* IPv4 */
- /* ICE_FLOW_FIELD_IDX_IP_DSCP */
- ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 1, 1),
- /* ICE_FLOW_FIELD_IDX_IP_TTL */
- ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NONE, 8, 1),
- /* ICE_FLOW_FIELD_IDX_IP_PROT */
- ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_NONE, 9, ICE_FLOW_FLD_SZ_IP_PROT),
+ /* IPv4 / IPv6 */
+ /* ICE_FLOW_FIELD_IDX_IPV4_DSCP */
+ ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV4, 0, ICE_FLOW_FLD_SZ_IP_DSCP,
+ 0x00fc),
+ /* ICE_FLOW_FIELD_IDX_IPV6_DSCP */
+ ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_IPV6, 0, ICE_FLOW_FLD_SZ_IP_DSCP,
+ 0x0ff0),
+ /* ICE_FLOW_FIELD_IDX_IPV4_TTL */
+ ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8,
+ ICE_FLOW_FLD_SZ_IP_TTL, 0xff00),
+ /* ICE_FLOW_FIELD_IDX_IPV4_PROT */
+ ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 8,
+ ICE_FLOW_FLD_SZ_IP_PROT, 0x00ff),
+ /* ICE_FLOW_FIELD_IDX_IPV6_TTL */
+ ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6,
+ ICE_FLOW_FLD_SZ_IP_TTL, 0x00ff),
+ /* ICE_FLOW_FIELD_IDX_IPV6_PROT */
+ ICE_FLOW_FLD_INFO_MSK(ICE_FLOW_SEG_HDR_NONE, 6,
+ ICE_FLOW_FLD_SZ_IP_PROT, 0xff00),
/* ICE_FLOW_FIELD_IDX_IPV4_SA */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 12, ICE_FLOW_FLD_SZ_IPV4_ADDR),
/* ICE_FLOW_FIELD_IDX_IPV4_DA */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 16, ICE_FLOW_FLD_SZ_IPV4_ADDR),
- /* IPv6 */
/* ICE_FLOW_FIELD_IDX_IPV6_SA */
ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, ICE_FLOW_FLD_SZ_IPV6_ADDR),
/* ICE_FLOW_FIELD_IDX_IPV6_DA */
* Packet types for packets with an Outer/First/Single MAC header
*/
static const u32 ice_ptypes_mac_ofos[] = {
- 0xFDC00CC6, 0xBFBF7F7E, 0xF7EFDFDF, 0xFEFDFDFB,
- 0x03BF7F7E, 0x00000000, 0x00000000, 0x00000000,
- 0x000B0F0F, 0x00003000, 0x00000000, 0x00000000,
+ 0xFDC00846, 0xBFBF7F7E, 0xF70001DF, 0xFEFDFDFB,
+ 0x0000077E, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00003000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* Packet types for packets with an Outer/First/Single IPv4 header */
static const u32 ice_ptypes_ipv4_ofos[] = {
- 0xFDC00000, 0xBFBF7F7E, 0x00EFDFDF, 0x00000000,
+ 0x1DC00000, 0x04000800, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x0003000F, 0x000FC000, 0x00000000, 0x00000000,
+ 0x00000000, 0x000FC000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* Packet types for packets with an Innermost/Last IPv4 header */
static const u32 ice_ptypes_ipv4_il[] = {
- 0xE0000000, 0xB807700E, 0x8001DC03, 0xE01DC03B,
- 0x0007700E, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x000FF800, 0x00000000,
+ 0xE0000000, 0xB807700E, 0x80000003, 0xE01DC03B,
+ 0x0000000E, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x001FF800, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* Packet types for packets with an Outer/First/Single IPv6 header */
static const u32 ice_ptypes_ipv6_ofos[] = {
- 0x00000000, 0x00000000, 0xF7000000, 0xFEFDFDFB,
- 0x03BF7F7E, 0x00000000, 0x00000000, 0x00000000,
- 0x00080F00, 0x03F00000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x77000000, 0x10002000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x03F00000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* Packet types for packets with an Innermost/Last IPv6 header */
static const u32 ice_ptypes_ipv6_il[] = {
- 0x00000000, 0x03B80770, 0x00EE01DC, 0x0EE00000,
- 0x03B80770, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x03B80770, 0x000001DC, 0x0EE00000,
+ 0x00000770, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x7FE00000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
* packets with inner UDP.
*/
static const u32 ice_ptypes_udp_il[] = {
- 0x81000000, 0x20204040, 0x04081010, 0x80810102,
- 0x00204040, 0x00000000, 0x00000000, 0x00000000,
+ 0x81000000, 0x20204040, 0x04000010, 0x80810102,
+ 0x00000040, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00410000, 0x10842000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* Packet types for packets with an Innermost/Last TCP header */
static const u32 ice_ptypes_tcp_il[] = {
- 0x04000000, 0x80810102, 0x10204040, 0x02040408,
- 0x00810102, 0x00000000, 0x00000000, 0x00000000,
+ 0x04000000, 0x80810102, 0x10000040, 0x02040408,
+ 0x00000102, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00820000, 0x21084000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* Packet types for packets with an Innermost/Last SCTP header */
static const u32 ice_ptypes_sctp_il[] = {
- 0x08000000, 0x01020204, 0x20408081, 0x04080810,
- 0x01020204, 0x00000000, 0x00000000, 0x00000000,
+ 0x08000000, 0x01020204, 0x20000081, 0x04080810,
+ 0x00000204, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x01040000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* Packet types for packets with an Innermost/Last ICMP header */
static const u32 ice_ptypes_icmp_il[] = {
- 0x00000000, 0x02040408, 0x40810102, 0x08101020,
- 0x02040408, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x02040408, 0x40000102, 0x08101020,
+ 0x00000408, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x42108000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* Packet types for packets with an Outermost/First GRE header */
static const u32 ice_ptypes_gre_of[] = {
- 0x00000000, 0xBFBF7800, 0x00EFDFDF, 0xFEFDE000,
- 0x03BF7F7E, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xBFBF7800, 0x000001DF, 0xFEFDE000,
+ 0x0000017E, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
/* Packet types for packets with an Innermost/Last MAC header */
static const u32 ice_ptypes_mac_il[] = {
- 0x00000000, 0x00000000, 0x00EFDE00, 0x00000000,
- 0x03BF7800, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
* @params: information about the flow to be processed
* @seg: packet segment index of the field to be extracted
* @fld: ID of field to be extracted
+ * @match: bitfield of all fields
*
* This function determines the protocol ID, offset, and size of the given
* field. It then allocates one or more extraction sequence entries for the
*/
static enum ice_status
ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
- u8 seg, enum ice_flow_field fld)
+ u8 seg, enum ice_flow_field fld, u64 match)
{
enum ice_flow_field sib = ICE_FLOW_FIELD_IDX_MAX;
enum ice_prot_id prot_id = ICE_PROT_ID_INVAL;
u8 fv_words = hw->blk[params->blk].es.fvw;
struct ice_flow_fld_info *flds;
u16 cnt, ese_bits, i;
+ u16 sib_mask = 0;
s16 adj = 0;
u16 mask;
u16 off;
case ICE_FLOW_FIELD_IDX_ETH_TYPE:
prot_id = seg == 0 ? ICE_PROT_ETYPE_OL : ICE_PROT_ETYPE_IL;
break;
- case ICE_FLOW_FIELD_IDX_IP_DSCP:
- if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV6)
- adj = ICE_FLOW_FLD_IPV6_TTL_DSCP_DISP;
- /* Fall through */
- case ICE_FLOW_FIELD_IDX_IP_TTL:
- case ICE_FLOW_FIELD_IDX_IP_PROT:
- /* Some fields are located at different offsets in IPv4 and
- * IPv6
+ case ICE_FLOW_FIELD_IDX_IPV4_DSCP:
+ prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
+ break;
+ case ICE_FLOW_FIELD_IDX_IPV6_DSCP:
+ prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
+ break;
+ case ICE_FLOW_FIELD_IDX_IPV4_TTL:
+ case ICE_FLOW_FIELD_IDX_IPV4_PROT:
+ prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S : ICE_PROT_IPV4_IL;
+
+ /* TTL and PROT share the same extraction seq. entry.
+ * Each is considered a sibling to the other in terms of sharing
+ * the same extraction sequence entry.
*/
- if (params->prof->segs[seg].hdrs & ICE_FLOW_SEG_HDR_IPV4) {
- prot_id = seg == 0 ? ICE_PROT_IPV4_OF_OR_S :
- ICE_PROT_IPV4_IL;
- /* TTL and PROT share the same extraction seq. entry.
- * Each is considered a sibling to the other in term
- * sharing the same extraction sequence entry.
- */
- if (fld == ICE_FLOW_FIELD_IDX_IP_TTL)
- sib = ICE_FLOW_FIELD_IDX_IP_PROT;
- else if (fld == ICE_FLOW_FIELD_IDX_IP_PROT)
- sib = ICE_FLOW_FIELD_IDX_IP_TTL;
- } else if (params->prof->segs[seg].hdrs &
- ICE_FLOW_SEG_HDR_IPV6) {
- prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S :
- ICE_PROT_IPV6_IL;
- if (fld == ICE_FLOW_FIELD_IDX_IP_TTL)
- adj = ICE_FLOW_FLD_IPV6_TTL_TTL_DISP;
- else if (fld == ICE_FLOW_FIELD_IDX_IP_PROT)
- adj = ICE_FLOW_FLD_IPV6_TTL_PROT_DISP;
- }
+ if (fld == ICE_FLOW_FIELD_IDX_IPV4_TTL)
+ sib = ICE_FLOW_FIELD_IDX_IPV4_PROT;
+ else if (fld == ICE_FLOW_FIELD_IDX_IPV4_PROT)
+ sib = ICE_FLOW_FIELD_IDX_IPV4_TTL;
+
+ /* If the sibling field is also included, that field's
+ * mask needs to be included.
+ */
+ if (match & BIT(sib))
+ sib_mask = ice_flds_info[sib].mask;
+ break;
+ case ICE_FLOW_FIELD_IDX_IPV6_TTL:
+ case ICE_FLOW_FIELD_IDX_IPV6_PROT:
+ prot_id = seg == 0 ? ICE_PROT_IPV6_OF_OR_S : ICE_PROT_IPV6_IL;
+
+ /* TTL and PROT share the same extraction seq. entry.
+ * Each is considered a sibling to the other in terms of sharing
+ * the same extraction sequence entry.
+ */
+ if (fld == ICE_FLOW_FIELD_IDX_IPV6_TTL)
+ sib = ICE_FLOW_FIELD_IDX_IPV6_PROT;
+ else if (fld == ICE_FLOW_FIELD_IDX_IPV6_PROT)
+ sib = ICE_FLOW_FIELD_IDX_IPV6_TTL;
+
+ /* If the sibling field is also included, that field's
+ * mask needs to be included.
+ */
+ if (match & BIT(sib))
+ sib_mask = ice_flds_info[sib].mask;
break;
case ICE_FLOW_FIELD_IDX_IPV4_SA:
case ICE_FLOW_FIELD_IDX_IPV4_DA:
ICE_FLOW_FV_EXTRACT_SZ;
flds[fld].xtrct.disp = (u8)((ice_flds_info[fld].off + adj) % ese_bits);
flds[fld].xtrct.idx = params->es_cnt;
+ flds[fld].xtrct.mask = ice_flds_info[fld].mask;
/* Adjust the next field-entry index after accommodating the number of
* entries this field consumes
/* Fill in the extraction sequence entries needed for this field */
off = flds[fld].xtrct.off;
- mask = ice_flds_info[fld].mask;
+ mask = flds[fld].xtrct.mask;
for (i = 0; i < cnt; i++) {
/* Only consume an extraction sequence entry if there is no
* sibling field associated with this field or the sibling entry
params->es[idx].prot_id = prot_id;
params->es[idx].off = off;
- params->mask[idx] = mask;
+ params->mask[idx] = mask | sib_mask;
params->es_cnt++;
}
if (match & bit) {
status = ice_flow_xtract_fld
- (hw, params, i, (enum ice_flow_field)j);
+ (hw, params, i, (enum ice_flow_field)j,
+ match);
if (status)
return status;
match &= ~bit;
struct ice_flow_prof *prof;
enum ice_status status;
- segs = (struct ice_flow_seg_info *)ice_malloc(hw, sizeof(*segs));
+ segs = (struct ice_flow_seg_info *)ice_calloc(hw, segs_cnt,
+ sizeof(*segs));
if (!segs)
return ICE_ERR_NO_MEMORY;
/* Construct the packet segment info from the hashed fields */
- status = ice_flow_set_rss_seg_info(segs, hashed_flds, addl_hdrs);
+ status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds,
+ addl_hdrs);
if (status)
goto out;