@@ -193,6 +193,40 @@ ice_flow_val_hdrs(struct ice_flow_seg_info *segs, u8 segs_cnt)
193193 return 0 ;
194194}
195195
196+ /* Sizes of fixed known protocol headers without header options */
197+ #define ICE_FLOW_PROT_HDR_SZ_MAC 14
198+ #define ICE_FLOW_PROT_HDR_SZ_IPV4 20
199+ #define ICE_FLOW_PROT_HDR_SZ_IPV6 40
200+ #define ICE_FLOW_PROT_HDR_SZ_TCP 20
201+ #define ICE_FLOW_PROT_HDR_SZ_UDP 8
202+ #define ICE_FLOW_PROT_HDR_SZ_SCTP 12
203+
204+ /**
205+ * ice_flow_calc_seg_sz - calculates size of a packet segment based on headers
206+ * @params: information about the flow to be processed
207+ * @seg: index of packet segment whose header size is to be determined
208+ */
209+ static u16 ice_flow_calc_seg_sz (struct ice_flow_prof_params * params , u8 seg )
210+ {
211+ u16 sz = ICE_FLOW_PROT_HDR_SZ_MAC ;
212+
213+ /* L3 headers */
214+ if (params -> prof -> segs [seg ].hdrs & ICE_FLOW_SEG_HDR_IPV4 )
215+ sz += ICE_FLOW_PROT_HDR_SZ_IPV4 ;
216+ else if (params -> prof -> segs [seg ].hdrs & ICE_FLOW_SEG_HDR_IPV6 )
217+ sz += ICE_FLOW_PROT_HDR_SZ_IPV6 ;
218+
219+ /* L4 headers */
220+ if (params -> prof -> segs [seg ].hdrs & ICE_FLOW_SEG_HDR_TCP )
221+ sz += ICE_FLOW_PROT_HDR_SZ_TCP ;
222+ else if (params -> prof -> segs [seg ].hdrs & ICE_FLOW_SEG_HDR_UDP )
223+ sz += ICE_FLOW_PROT_HDR_SZ_UDP ;
224+ else if (params -> prof -> segs [seg ].hdrs & ICE_FLOW_SEG_HDR_SCTP )
225+ sz += ICE_FLOW_PROT_HDR_SZ_SCTP ;
226+
227+ return sz ;
228+ }
229+
196230/**
197231 * ice_flow_proc_seg_hdrs - process protocol headers present in pkt segments
198232 * @params: information about the flow to be processed
@@ -347,6 +381,81 @@ ice_flow_xtract_fld(struct ice_hw *hw, struct ice_flow_prof_params *params,
347381 return 0 ;
348382}
349383
384+ /**
385+ * ice_flow_xtract_raws - Create extract sequence entries for raw bytes
386+ * @hw: pointer to the HW struct
387+ * @params: information about the flow to be processed
388+ * @seg: index of packet segment whose raw fields are to be be extracted
389+ */
390+ static enum ice_status
391+ ice_flow_xtract_raws (struct ice_hw * hw , struct ice_flow_prof_params * params ,
392+ u8 seg )
393+ {
394+ u16 fv_words ;
395+ u16 hdrs_sz ;
396+ u8 i ;
397+
398+ if (!params -> prof -> segs [seg ].raws_cnt )
399+ return 0 ;
400+
401+ if (params -> prof -> segs [seg ].raws_cnt >
402+ ARRAY_SIZE (params -> prof -> segs [seg ].raws ))
403+ return ICE_ERR_MAX_LIMIT ;
404+
405+ /* Offsets within the segment headers are not supported */
406+ hdrs_sz = ice_flow_calc_seg_sz (params , seg );
407+ if (!hdrs_sz )
408+ return ICE_ERR_PARAM ;
409+
410+ fv_words = hw -> blk [params -> blk ].es .fvw ;
411+
412+ for (i = 0 ; i < params -> prof -> segs [seg ].raws_cnt ; i ++ ) {
413+ struct ice_flow_seg_fld_raw * raw ;
414+ u16 off , cnt , j ;
415+
416+ raw = & params -> prof -> segs [seg ].raws [i ];
417+
418+ /* Storing extraction information */
419+ raw -> info .xtrct .prot_id = ICE_PROT_MAC_OF_OR_S ;
420+ raw -> info .xtrct .off = (raw -> off / ICE_FLOW_FV_EXTRACT_SZ ) *
421+ ICE_FLOW_FV_EXTRACT_SZ ;
422+ raw -> info .xtrct .disp = (raw -> off % ICE_FLOW_FV_EXTRACT_SZ ) *
423+ BITS_PER_BYTE ;
424+ raw -> info .xtrct .idx = params -> es_cnt ;
425+
426+ /* Determine the number of field vector entries this raw field
427+ * consumes.
428+ */
429+ cnt = DIV_ROUND_UP (raw -> info .xtrct .disp +
430+ (raw -> info .src .last * BITS_PER_BYTE ),
431+ (ICE_FLOW_FV_EXTRACT_SZ * BITS_PER_BYTE ));
432+ off = raw -> info .xtrct .off ;
433+ for (j = 0 ; j < cnt ; j ++ ) {
434+ u16 idx ;
435+
436+ /* Make sure the number of extraction sequence required
437+ * does not exceed the block's capability
438+ */
439+ if (params -> es_cnt >= hw -> blk [params -> blk ].es .count ||
440+ params -> es_cnt >= ICE_MAX_FV_WORDS )
441+ return ICE_ERR_MAX_LIMIT ;
442+
443+ /* some blocks require a reversed field vector layout */
444+ if (hw -> blk [params -> blk ].es .reverse )
445+ idx = fv_words - params -> es_cnt - 1 ;
446+ else
447+ idx = params -> es_cnt ;
448+
449+ params -> es [idx ].prot_id = raw -> info .xtrct .prot_id ;
450+ params -> es [idx ].off = off ;
451+ params -> es_cnt ++ ;
452+ off += ICE_FLOW_FV_EXTRACT_SZ ;
453+ }
454+ }
455+
456+ return 0 ;
457+ }
458+
350459/**
351460 * ice_flow_create_xtrct_seq - Create an extraction sequence for given segments
352461 * @hw: pointer to the HW struct
@@ -373,6 +482,11 @@ ice_flow_create_xtrct_seq(struct ice_hw *hw,
373482 if (status )
374483 return status ;
375484 }
485+
486+ /* Process raw matching bytes */
487+ status = ice_flow_xtract_raws (hw , params , i );
488+ if (status )
489+ return status ;
376490 }
377491
378492 return status ;
@@ -943,6 +1057,42 @@ ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld,
9431057 ice_flow_set_fld_ext (seg , fld , t , val_loc , mask_loc , last_loc );
9441058}
9451059
1060+ /**
1061+ * ice_flow_add_fld_raw - sets locations of a raw field from entry's input buf
1062+ * @seg: packet segment the field being set belongs to
1063+ * @off: offset of the raw field from the beginning of the segment in bytes
1064+ * @len: length of the raw pattern to be matched
1065+ * @val_loc: location of the value to match from entry's input buffer
1066+ * @mask_loc: location of mask value from entry's input buffer
1067+ *
1068+ * This function specifies the offset of the raw field to be match from the
1069+ * beginning of the specified packet segment, and the locations, in the form of
1070+ * byte offsets from the start of the input buffer for a flow entry, from where
1071+ * the value to match and the mask value to be extracted. These locations are
1072+ * then stored in the flow profile. When adding flow entries to the associated
1073+ * flow profile, these locations can be used to quickly extract the values to
1074+ * create the content of a match entry. This function should only be used for
1075+ * fixed-size data structures.
1076+ */
1077+ void
1078+ ice_flow_add_fld_raw (struct ice_flow_seg_info * seg , u16 off , u8 len ,
1079+ u16 val_loc , u16 mask_loc )
1080+ {
1081+ if (seg -> raws_cnt < ICE_FLOW_SEG_RAW_FLD_MAX ) {
1082+ seg -> raws [seg -> raws_cnt ].off = off ;
1083+ seg -> raws [seg -> raws_cnt ].info .type = ICE_FLOW_FLD_TYPE_SIZE ;
1084+ seg -> raws [seg -> raws_cnt ].info .src .val = val_loc ;
1085+ seg -> raws [seg -> raws_cnt ].info .src .mask = mask_loc ;
1086+ /* The "last" field is used to store the length of the field */
1087+ seg -> raws [seg -> raws_cnt ].info .src .last = len ;
1088+ }
1089+
1090+ /* Overflows of "raws" will be handled as an error condition later in
1091+ * the flow when this information is processed.
1092+ */
1093+ seg -> raws_cnt ++ ;
1094+ }
1095+
9461096#define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \
9471097 (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6)
9481098
0 commit comments