55#include "ice_flow.h"
66#include <net/gre.h>
77
8+ /* Size of known protocol header fields */
9+ #define ICE_FLOW_FLD_SZ_ETH_TYPE 2
10+ #define ICE_FLOW_FLD_SZ_VLAN 2
11+ #define ICE_FLOW_FLD_SZ_IPV4_ADDR 4
12+ #define ICE_FLOW_FLD_SZ_IPV6_ADDR 16
13+ #define ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR 4
14+ #define ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR 6
15+ #define ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR 8
16+ #define ICE_FLOW_FLD_SZ_IPV4_ID 2
17+ #define ICE_FLOW_FLD_SZ_IPV6_ID 4
18+ #define ICE_FLOW_FLD_SZ_IP_CHKSUM 2
19+ #define ICE_FLOW_FLD_SZ_TCP_CHKSUM 2
20+ #define ICE_FLOW_FLD_SZ_UDP_CHKSUM 2
21+ #define ICE_FLOW_FLD_SZ_SCTP_CHKSUM 4
22+ #define ICE_FLOW_FLD_SZ_IP_DSCP 1
23+ #define ICE_FLOW_FLD_SZ_IP_TTL 1
24+ #define ICE_FLOW_FLD_SZ_IP_PROT 1
25+ #define ICE_FLOW_FLD_SZ_PORT 2
26+ #define ICE_FLOW_FLD_SZ_TCP_FLAGS 1
27+ #define ICE_FLOW_FLD_SZ_ICMP_TYPE 1
28+ #define ICE_FLOW_FLD_SZ_ICMP_CODE 1
29+ #define ICE_FLOW_FLD_SZ_ARP_OPER 2
30+ #define ICE_FLOW_FLD_SZ_GRE_KEYID 4
31+ #define ICE_FLOW_FLD_SZ_GTP_TEID 4
32+ #define ICE_FLOW_FLD_SZ_GTP_QFI 2
33+ #define ICE_FLOW_FLD_SZ_PFCP_SEID 8
34+ #define ICE_FLOW_FLD_SZ_ESP_SPI 4
35+ #define ICE_FLOW_FLD_SZ_AH_SPI 4
36+ #define ICE_FLOW_FLD_SZ_NAT_T_ESP_SPI 4
37+ #define ICE_FLOW_FLD_SZ_L2TPV2_SESS_ID 2
38+ #define ICE_FLOW_FLD_SZ_L2TPV2_LEN_SESS_ID 2
39+
840/* Describe properties of a protocol header field */
941struct ice_flow_field_info {
1042 enum ice_flow_seg_hdr hdr ;
@@ -20,6 +52,7 @@ struct ice_flow_field_info {
2052 .mask = 0, \
2153}
2254
55+ /* QFI: 6-bit field in GTP-U PDU Session Container (3GPP TS 38.415) */
2356#define ICE_FLOW_FLD_INFO_MSK (_hdr , _offset_bytes , _size_bytes , _mask ) { \
2457 .hdr = _hdr, \
2558 .off = (_offset_bytes) * BITS_PER_BYTE, \
@@ -61,7 +94,33 @@ struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
6194 /* ICE_FLOW_FIELD_IDX_IPV6_SA */
6295 ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_IPV6 , 8 , sizeof (struct in6_addr )),
6396 /* ICE_FLOW_FIELD_IDX_IPV6_DA */
64- ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_IPV6 , 24 , sizeof (struct in6_addr )),
97+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_IPV6 , 24 , ICE_FLOW_FLD_SZ_IPV6_ADDR ),
98+ /* ICE_FLOW_FIELD_IDX_IPV4_CHKSUM */
99+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_IPV4 , 10 , ICE_FLOW_FLD_SZ_IP_CHKSUM ),
100+ /* ICE_FLOW_FIELD_IDX_IPV4_FRAG */
101+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_IPV_FRAG , 4 ,
102+ ICE_FLOW_FLD_SZ_IPV4_ID ),
103+ /* ICE_FLOW_FIELD_IDX_IPV6_FRAG */
104+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_IPV_FRAG , 4 ,
105+ ICE_FLOW_FLD_SZ_IPV6_ID ),
106+ /* ICE_FLOW_FIELD_IDX_IPV6_PRE32_SA */
107+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_IPV6 , 8 ,
108+ ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR ),
109+ /* ICE_FLOW_FIELD_IDX_IPV6_PRE32_DA */
110+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_IPV6 , 24 ,
111+ ICE_FLOW_FLD_SZ_IPV6_PRE32_ADDR ),
112+ /* ICE_FLOW_FIELD_IDX_IPV6_PRE48_SA */
113+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_IPV6 , 8 ,
114+ ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR ),
115+ /* ICE_FLOW_FIELD_IDX_IPV6_PRE48_DA */
116+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_IPV6 , 24 ,
117+ ICE_FLOW_FLD_SZ_IPV6_PRE48_ADDR ),
118+ /* ICE_FLOW_FIELD_IDX_IPV6_PRE64_SA */
119+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_IPV6 , 8 ,
120+ ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR ),
121+ /* ICE_FLOW_FIELD_IDX_IPV6_PRE64_DA */
122+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_IPV6 , 24 ,
123+ ICE_FLOW_FLD_SZ_IPV6_PRE64_ADDR ),
65124 /* Transport */
66125 /* ICE_FLOW_FIELD_IDX_TCP_SRC_PORT */
67126 ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_TCP , 0 , sizeof (__be16 )),
@@ -76,7 +135,14 @@ struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
76135 /* ICE_FLOW_FIELD_IDX_SCTP_DST_PORT */
77136 ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_SCTP , 2 , sizeof (__be16 )),
78137 /* ICE_FLOW_FIELD_IDX_TCP_FLAGS */
79- ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_TCP , 13 , 1 ),
138+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_TCP , 13 , ICE_FLOW_FLD_SZ_TCP_FLAGS ),
139+ /* ICE_FLOW_FIELD_IDX_TCP_CHKSUM */
140+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_TCP , 16 , ICE_FLOW_FLD_SZ_TCP_CHKSUM ),
141+ /* ICE_FLOW_FIELD_IDX_UDP_CHKSUM */
142+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_UDP , 6 , ICE_FLOW_FLD_SZ_UDP_CHKSUM ),
143+ /* ICE_FLOW_FIELD_IDX_SCTP_CHKSUM */
144+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_SCTP , 8 ,
145+ ICE_FLOW_FLD_SZ_SCTP_CHKSUM ),
80146 /* ARP */
81147 /* ICE_FLOW_FIELD_IDX_ARP_SIP */
82148 ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_ARP , 14 , sizeof (struct in_addr )),
@@ -108,9 +174,17 @@ struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
108174 ICE_FLOW_FLD_INFO_MSK (ICE_FLOW_SEG_HDR_GTPU_EH , 22 , sizeof (__be16 ),
109175 0x3f00 ),
110176 /* ICE_FLOW_FIELD_IDX_GTPU_UP_TEID */
111- ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_GTPU_UP , 12 , sizeof (__be32 )),
177+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_GTPU_UP , 12 ,
178+ ICE_FLOW_FLD_SZ_GTP_TEID ),
179+ /* ICE_FLOW_FIELD_IDX_GTPU_UP_QFI */
180+ ICE_FLOW_FLD_INFO_MSK (ICE_FLOW_SEG_HDR_GTPU_UP , 22 ,
181+ ICE_FLOW_FLD_SZ_GTP_QFI , 0x3f00 ),
112182 /* ICE_FLOW_FIELD_IDX_GTPU_DWN_TEID */
113- ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_GTPU_DWN , 12 , sizeof (__be32 )),
183+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_GTPU_DWN , 12 ,
184+ ICE_FLOW_FLD_SZ_GTP_TEID ),
185+ /* ICE_FLOW_FIELD_IDX_GTPU_DWN_QFI */
186+ ICE_FLOW_FLD_INFO_MSK (ICE_FLOW_SEG_HDR_GTPU_DWN , 22 ,
187+ ICE_FLOW_FLD_SZ_GTP_QFI , 0x3f00 ),
114188 /* PPPoE */
115189 /* ICE_FLOW_FIELD_IDX_PPPOE_SESS_ID */
116190 ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_PPPOE , 2 , sizeof (__be16 )),
@@ -128,7 +202,16 @@ struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = {
128202 ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_AH , 4 , sizeof (__be32 )),
129203 /* NAT_T_ESP */
130204 /* ICE_FLOW_FIELD_IDX_NAT_T_ESP_SPI */
131- ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_NAT_T_ESP , 8 , sizeof (__be32 )),
205+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_NAT_T_ESP , 8 ,
206+ ICE_FLOW_FLD_SZ_NAT_T_ESP_SPI ),
207+ /* L2TPV2 */
208+ /* ICE_FLOW_FIELD_IDX_L2TPV2_SESS_ID */
209+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_L2TPV2 , 12 ,
210+ ICE_FLOW_FLD_SZ_L2TPV2_SESS_ID ),
211+ /* L2TPV2_LEN */
212+ /* ICE_FLOW_FIELD_IDX_L2TPV2_LEN_SESS_ID */
213+ ICE_FLOW_FLD_INFO (ICE_FLOW_SEG_HDR_L2TPV2 , 14 ,
214+ ICE_FLOW_FLD_SZ_L2TPV2_LEN_SESS_ID ),
132215};
133216
134217/* Bitmaps indicating relevant packet types for a particular protocol header
@@ -2324,6 +2407,130 @@ static void ice_rss_set_symm(struct ice_hw *hw, struct ice_flow_prof *prof)
23242407 }
23252408}
23262409
2410+ /**
2411+ * ice_rss_cfg_raw_symm - Configure symmetric RSS for a raw parser profile
2412+ * @hw: device HW
2413+ * @prof: parser profile describing extracted FV (field vector) entries
2414+ * @prof_id: RSS profile identifier used to program symmetry registers
2415+ *
2416+ * The routine scans the parser profile's FV entries and looks for
2417+ * direction-sensitive pairs (L3 src/dst, L4 src/dst). When a pair is found,
2418+ * it programs XOR-based symmetry so that flows hash identically regardless
2419+ * of packet direction. This preserves CPU affinity for the same 5-tuple.
2420+ *
2421+ * Notes:
2422+ * - The size of each logical field (IPv4/IPv6 address, L4 port) is expressed
2423+ * in units of ICE_FLOW_FV_EXTRACT_SZ so we can step across fv[] correctly.
2424+ * - We guard against out-of-bounds access before looking at fv[i + len].
2425+ */
2426+ static void ice_rss_cfg_raw_symm (struct ice_hw * hw ,
2427+ const struct ice_parser_profile * prof ,
2428+ u64 prof_id )
2429+ {
2430+ for (size_t i = 0 ; i < prof -> fv_num ; i ++ ) {
2431+ u8 proto_id = prof -> fv [i ].proto_id ;
2432+ u16 src_off = 0 , dst_off = 0 ;
2433+ size_t src_idx , dst_idx ;
2434+ bool is_matched = false;
2435+ unsigned int len = 0 ;
2436+
2437+ switch (proto_id ) {
2438+ /* IPv4 address pairs (outer/inner variants) */
2439+ case ICE_PROT_IPV4_OF_OR_S :
2440+ case ICE_PROT_IPV4_IL :
2441+ case ICE_PROT_IPV4_IL_IL :
2442+ len = ICE_FLOW_FLD_SZ_IPV4_ADDR /
2443+ ICE_FLOW_FV_EXTRACT_SZ ;
2444+ src_off = ICE_FLOW_FIELD_IPV4_SRC_OFFSET ;
2445+ dst_off = ICE_FLOW_FIELD_IPV4_DST_OFFSET ;
2446+ break ;
2447+
2448+ /* IPv6 address pairs (outer/inner variants) */
2449+ case ICE_PROT_IPV6_OF_OR_S :
2450+ case ICE_PROT_IPV6_IL :
2451+ case ICE_PROT_IPV6_IL_IL :
2452+ len = ICE_FLOW_FLD_SZ_IPV6_ADDR /
2453+ ICE_FLOW_FV_EXTRACT_SZ ;
2454+ src_off = ICE_FLOW_FIELD_IPV6_SRC_OFFSET ;
2455+ dst_off = ICE_FLOW_FIELD_IPV6_DST_OFFSET ;
2456+ break ;
2457+
2458+ /* L4 port pairs (TCP/UDP/SCTP) */
2459+ case ICE_PROT_TCP_IL :
2460+ case ICE_PROT_UDP_IL_OR_S :
2461+ case ICE_PROT_SCTP_IL :
2462+ len = ICE_FLOW_FLD_SZ_PORT / ICE_FLOW_FV_EXTRACT_SZ ;
2463+ src_off = ICE_FLOW_FIELD_SRC_PORT_OFFSET ;
2464+ dst_off = ICE_FLOW_FIELD_DST_PORT_OFFSET ;
2465+ break ;
2466+
2467+ default :
2468+ continue ;
2469+ }
2470+
2471+ /* Bounds check before accessing fv[i + len]. */
2472+ if (i + len >= prof -> fv_num )
2473+ continue ;
2474+
2475+ /* Verify src/dst pairing for this protocol id. */
2476+ is_matched = prof -> fv [i ].offset == src_off &&
2477+ prof -> fv [i + len ].proto_id == proto_id &&
2478+ prof -> fv [i + len ].offset == dst_off ;
2479+ if (!is_matched )
2480+ continue ;
2481+
2482+ /* Program XOR symmetry for this field pair. */
2483+ src_idx = i ;
2484+ dst_idx = i + len ;
2485+
2486+ ice_rss_config_xor (hw , prof_id , src_idx , dst_idx , len );
2487+
2488+ /* Skip over the pair we just handled; the loop's ++i advances
2489+ * one more element, hence the --i after the jump.
2490+ */
2491+ i += (2 * len );
2492+ /* not strictly needed; keeps static analyzers happy */
2493+ if (i == 0 )
2494+ break ;
2495+ -- i ;
2496+ }
2497+ }
2498+
2499+ /* Max registers index per packet profile */
2500+ #define ICE_SYMM_REG_INDEX_MAX 6
2501+
2502+ /**
2503+ * ice_rss_update_raw_symm - update symmetric hash configuration
2504+ * for raw pattern
2505+ * @hw: pointer to the hardware structure
2506+ * @cfg: configure parameters for raw pattern
2507+ * @id: profile tracking ID
2508+ *
2509+ * Update symmetric hash configuration for raw pattern if required.
2510+ * Otherwise only clear to default.
2511+ */
2512+ void
2513+ ice_rss_update_raw_symm (struct ice_hw * hw ,
2514+ struct ice_rss_raw_cfg * cfg , u64 id )
2515+ {
2516+ struct ice_prof_map * map ;
2517+ u8 prof_id , m ;
2518+
2519+ mutex_lock (& hw -> blk [ICE_BLK_RSS ].es .prof_map_lock );
2520+ map = ice_search_prof_id (hw , ICE_BLK_RSS , id );
2521+ if (map )
2522+ prof_id = map -> prof_id ;
2523+ mutex_unlock (& hw -> blk [ICE_BLK_RSS ].es .prof_map_lock );
2524+ if (!map )
2525+ return ;
2526+ /* clear to default */
2527+ for (m = 0 ; m < ICE_SYMM_REG_INDEX_MAX ; m ++ )
2528+ wr32 (hw , GLQF_HSYMM (prof_id , m ), 0 );
2529+
2530+ if (cfg -> symm )
2531+ ice_rss_cfg_raw_symm (hw , & cfg -> prof , prof_id );
2532+ }
2533+
23272534/**
23282535 * ice_add_rss_cfg_sync - add an RSS configuration
23292536 * @hw: pointer to the hardware structure
0 commit comments