Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ice: Enable writing hardware filtering tables

Enable the driver to write the filtering hardware tables to allow for
changing of RSS rules. Upon loading of DDP package, a minimal configuration
should be written to hardware.

Introduce and initialize structures for storing configuration and make
the top level calls to configure the RSS tables to initial values. A packet
segment will be created but nothing is written to hardware yet.

Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Henry Tieman <henry.w.tieman@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

authored by

Tony Nguyen and committed by
Jeff Kirsher
c90ed40c 08a45c59

+491 -4
+2 -1
drivers/net/ethernet/intel/ice/Makefile
··· 17 17 ice_lib.o \ 18 18 ice_txrx_lib.o \ 19 19 ice_txrx.o \ 20 - ice_flex_pipe.o \ 20 + ice_flex_pipe.o \ 21 + ice_flow.o \ 21 22 ice_ethtool.o 22 23 ice-$(CONFIG_PCI_IOV) += ice_virtchnl_pf.o ice_sriov.o 23 24 ice-$(CONFIG_DCB) += ice_dcb.o ice_dcb_nl.o ice_dcb_lib.o
+5 -1
drivers/net/ethernet/intel/ice/ice_common.c
··· 4 4 #include "ice_common.h" 5 5 #include "ice_sched.h" 6 6 #include "ice_adminq_cmd.h" 7 + #include "ice_flow.h" 7 8 8 9 #define ICE_PF_RESET_WAIT_COUNT 200 9 10 ··· 3407 3406 if (status) 3408 3407 return status; 3409 3408 } 3410 - 3409 + /* Replay per VSI all RSS configurations */ 3410 + status = ice_replay_rss_cfg(hw, vsi_handle); 3411 + if (status) 3412 + return status; 3411 3413 /* Replay per VSI all filters */ 3412 3414 status = ice_replay_vsi_all_fltr(hw, vsi_handle); 3413 3415 return status;
+30 -1
drivers/net/ethernet/intel/ice/ice_flex_pipe.c
··· 3 3 4 4 #include "ice_common.h" 5 5 #include "ice_flex_pipe.h" 6 + #include "ice_flow.h" 6 7 7 8 /** 8 9 * ice_pkg_val_buf ··· 1380 1379 */ 1381 1380 void ice_free_hw_tbls(struct ice_hw *hw) 1382 1381 { 1382 + struct ice_rss_cfg *r, *rt; 1383 1383 u8 i; 1384 1384 1385 1385 for (i = 0; i < ICE_BLK_COUNT; i++) { 1386 - hw->blk[i].is_list_init = false; 1386 + if (hw->blk[i].is_list_init) { 1387 + struct ice_es *es = &hw->blk[i].es; 1387 1388 1389 + mutex_destroy(&es->prof_map_lock); 1390 + mutex_destroy(&hw->fl_profs_locks[i]); 1391 + 1392 + hw->blk[i].is_list_init = false; 1393 + } 1388 1394 devm_kfree(ice_hw_to_dev(hw), hw->blk[i].xlt1.ptypes); 1389 1395 devm_kfree(ice_hw_to_dev(hw), hw->blk[i].xlt1.ptg_tbl); 1390 1396 devm_kfree(ice_hw_to_dev(hw), hw->blk[i].xlt1.t); ··· 1405 1397 devm_kfree(ice_hw_to_dev(hw), hw->blk[i].es.written); 1406 1398 } 1407 1399 1400 + list_for_each_entry_safe(r, rt, &hw->rss_list_head, l_entry) { 1401 + list_del(&r->l_entry); 1402 + devm_kfree(ice_hw_to_dev(hw), r); 1403 + } 1404 + mutex_destroy(&hw->rss_locks); 1408 1405 memset(hw->blk, 0, sizeof(hw->blk)); 1406 + } 1407 + 1408 + /** 1409 + * ice_init_flow_profs - init flow profile locks and list heads 1410 + * @hw: pointer to the hardware structure 1411 + * @blk_idx: HW block index 1412 + */ 1413 + static void ice_init_flow_profs(struct ice_hw *hw, u8 blk_idx) 1414 + { 1415 + mutex_init(&hw->fl_profs_locks[blk_idx]); 1416 + INIT_LIST_HEAD(&hw->fl_profs[blk_idx]); 1409 1417 } 1410 1418 1411 1419 /** ··· 1467 1443 { 1468 1444 u8 i; 1469 1445 1446 + mutex_init(&hw->rss_locks); 1447 + INIT_LIST_HEAD(&hw->rss_list_head); 1470 1448 for (i = 0; i < ICE_BLK_COUNT; i++) { 1471 1449 struct ice_prof_redir *prof_redir = &hw->blk[i].prof_redir; 1472 1450 struct ice_prof_tcam *prof = &hw->blk[i].prof; ··· 1480 1454 if (hw->blk[i].is_list_init) 1481 1455 continue; 1482 1456 1457 + ice_init_flow_profs(hw, i); 1458 + mutex_init(&es->prof_map_lock); 1459 + INIT_LIST_HEAD(&es->prof_map); 1483 1460 hw->blk[i].is_list_init = true; 1484 1461 1485 1462 hw->blk[i].overwrite = blk_sizes[i].overwrite;
+250
drivers/net/ethernet/intel/ice/ice_flow.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2019, Intel Corporation. */ 3 + 4 + #include "ice_common.h" 5 + #include "ice_flow.h" 6 + 7 + /* Describe properties of a protocol header field */ 8 + struct ice_flow_field_info { 9 + enum ice_flow_seg_hdr hdr; 10 + s16 off; /* Offset from start of a protocol header, in bits */ 11 + u16 size; /* Size of fields in bits */ 12 + }; 13 + 14 + #define ICE_FLOW_FLD_INFO(_hdr, _offset_bytes, _size_bytes) { \ 15 + .hdr = _hdr, \ 16 + .off = (_offset_bytes) * BITS_PER_BYTE, \ 17 + .size = (_size_bytes) * BITS_PER_BYTE, \ 18 + } 19 + 20 + /* Table containing properties of supported protocol header fields */ 21 + static const 22 + struct ice_flow_field_info ice_flds_info[ICE_FLOW_FIELD_IDX_MAX] = { 23 + /* IPv4 / IPv6 */ 24 + /* ICE_FLOW_FIELD_IDX_IPV4_SA */ 25 + ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 12, sizeof(struct in_addr)), 26 + /* ICE_FLOW_FIELD_IDX_IPV4_DA */ 27 + ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV4, 16, sizeof(struct in_addr)), 28 + /* ICE_FLOW_FIELD_IDX_IPV6_SA */ 29 + ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 8, sizeof(struct in6_addr)), 30 + /* ICE_FLOW_FIELD_IDX_IPV6_DA */ 31 + ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_IPV6, 24, sizeof(struct in6_addr)), 32 + /* Transport */ 33 + /* ICE_FLOW_FIELD_IDX_TCP_SRC_PORT */ 34 + ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 0, sizeof(__be16)), 35 + /* ICE_FLOW_FIELD_IDX_TCP_DST_PORT */ 36 + ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_TCP, 2, sizeof(__be16)), 37 + /* ICE_FLOW_FIELD_IDX_UDP_SRC_PORT */ 38 + ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 0, sizeof(__be16)), 39 + /* ICE_FLOW_FIELD_IDX_UDP_DST_PORT */ 40 + ICE_FLOW_FLD_INFO(ICE_FLOW_SEG_HDR_UDP, 2, sizeof(__be16)), 41 + }; 42 + 43 + /** 44 + * ice_flow_set_fld_ext - specifies locations of field from entry's input buffer 45 + * @seg: packet segment the field being set belongs to 46 + * @fld: field to be set 47 + * @type: type of the field 48 + * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from 49 + * entry's input buffer 50 + * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's 51 + * input buffer 52 + * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from 53 + * entry's input buffer 54 + * 55 + * This helper function stores information of a field being matched, including 56 + * the type of the field and the locations of the value to match, the mask, and 57 + * and the upper-bound value in the start of the input buffer for a flow entry. 58 + * This function should only be used for fixed-size data structures. 59 + * 60 + * This function also opportunistically determines the protocol headers to be 61 + * present based on the fields being set. Some fields cannot be used alone to 62 + * determine the protocol headers present. Sometimes, fields for particular 63 + * protocol headers are not matched. In those cases, the protocol headers 64 + * must be explicitly set. 65 + */ 66 + static void 67 + ice_flow_set_fld_ext(struct ice_flow_seg_info *seg, enum ice_flow_field fld, 68 + enum ice_flow_fld_match_type type, u16 val_loc, 69 + u16 mask_loc, u16 last_loc) 70 + { 71 + u64 bit = BIT_ULL(fld); 72 + 73 + seg->match |= bit; 74 + if (type == ICE_FLOW_FLD_TYPE_RANGE) 75 + seg->range |= bit; 76 + 77 + seg->fields[fld].type = type; 78 + seg->fields[fld].src.val = val_loc; 79 + seg->fields[fld].src.mask = mask_loc; 80 + seg->fields[fld].src.last = last_loc; 81 + 82 + ICE_FLOW_SET_HDRS(seg, ice_flds_info[fld].hdr); 83 + } 84 + 85 + /** 86 + * ice_flow_set_fld - specifies locations of field from entry's input buffer 87 + * @seg: packet segment the field being set belongs to 88 + * @fld: field to be set 89 + * @val_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of the value to match from 90 + * entry's input buffer 91 + * @mask_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of mask value from entry's 92 + * input buffer 93 + * @last_loc: if not ICE_FLOW_FLD_OFF_INVAL, location of last/upper value from 94 + * entry's input buffer 95 + * @range: indicate if field being matched is to be in a range 96 + * 97 + * This function specifies the locations, in the form of byte offsets from the 98 + * start of the input buffer for a flow entry, from where the value to match, 99 + * the mask value, and upper value can be extracted. These locations are then 100 + * stored in the flow profile. When adding a flow entry associated with the 101 + * flow profile, these locations will be used to quickly extract the values and 102 + * create the content of a match entry. This function should only be used for 103 + * fixed-size data structures. 104 + */ 105 + static void 106 + ice_flow_set_fld(struct ice_flow_seg_info *seg, enum ice_flow_field fld, 107 + u16 val_loc, u16 mask_loc, u16 last_loc, bool range) 108 + { 109 + enum ice_flow_fld_match_type t = range ? 110 + ICE_FLOW_FLD_TYPE_RANGE : ICE_FLOW_FLD_TYPE_REG; 111 + 112 + ice_flow_set_fld_ext(seg, fld, t, val_loc, mask_loc, last_loc); 113 + } 114 + 115 + #define ICE_FLOW_RSS_SEG_HDR_L3_MASKS \ 116 + (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6) 117 + 118 + #define ICE_FLOW_RSS_SEG_HDR_L4_MASKS \ 119 + (ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_SCTP) 120 + 121 + #define ICE_FLOW_RSS_SEG_HDR_VAL_MASKS \ 122 + (ICE_FLOW_RSS_SEG_HDR_L3_MASKS | \ 123 + ICE_FLOW_RSS_SEG_HDR_L4_MASKS) 124 + 125 + /** 126 + * ice_flow_set_rss_seg_info - setup packet segments for RSS 127 + * @segs: pointer to the flow field segment(s) 128 + * @hash_fields: fields to be hashed on for the segment(s) 129 + * @flow_hdr: protocol header fields within a packet segment 130 + * 131 + * Helper function to extract fields from hash bitmap and use flow 132 + * header value to set flow field segment for further use in flow 133 + * profile entry or removal. 134 + */ 135 + static enum ice_status 136 + ice_flow_set_rss_seg_info(struct ice_flow_seg_info *segs, u64 hash_fields, 137 + u32 flow_hdr) 138 + { 139 + u64 val; 140 + u8 i; 141 + 142 + for_each_set_bit(i, (unsigned long *)&hash_fields, 143 + ICE_FLOW_FIELD_IDX_MAX) 144 + ice_flow_set_fld(segs, (enum ice_flow_field)i, 145 + ICE_FLOW_FLD_OFF_INVAL, ICE_FLOW_FLD_OFF_INVAL, 146 + ICE_FLOW_FLD_OFF_INVAL, false); 147 + 148 + ICE_FLOW_SET_HDRS(segs, flow_hdr); 149 + 150 + if (segs->hdrs & ~ICE_FLOW_RSS_SEG_HDR_VAL_MASKS) 151 + return ICE_ERR_PARAM; 152 + 153 + val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L3_MASKS); 154 + if (val && !is_power_of_2(val)) 155 + return ICE_ERR_CFG; 156 + 157 + val = (u64)(segs->hdrs & ICE_FLOW_RSS_SEG_HDR_L4_MASKS); 158 + if (val && !is_power_of_2(val)) 159 + return ICE_ERR_CFG; 160 + 161 + return 0; 162 + } 163 + 164 + #define ICE_RSS_OUTER_HEADERS 1 165 + 166 + /** 167 + * ice_add_rss_cfg_sync - add an RSS configuration 168 + * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure 169 + * @addl_hdrs: protocol header fields 170 + * @segs_cnt: packet segment count 171 + * 172 + * Assumption: lock has already been acquired for RSS list 173 + */ 174 + static enum ice_status 175 + ice_add_rss_cfg_sync(u64 hashed_flds, u32 addl_hdrs, u8 segs_cnt) 176 + { 177 + struct ice_flow_seg_info *segs; 178 + enum ice_status status; 179 + 180 + if (!segs_cnt || segs_cnt > ICE_FLOW_SEG_MAX) 181 + return ICE_ERR_PARAM; 182 + 183 + segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL); 184 + if (!segs) 185 + return ICE_ERR_NO_MEMORY; 186 + 187 + /* Construct the packet segment info from the hashed fields */ 188 + status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds, 189 + addl_hdrs); 190 + 191 + kfree(segs); 192 + return status; 193 + } 194 + 195 + /** 196 + * ice_add_rss_cfg - add an RSS configuration with specified hashed fields 197 + * @hw: pointer to the hardware structure 198 + * @vsi_handle: software VSI handle 199 + * @hashed_flds: hash bit fields (ICE_FLOW_HASH_*) to configure 200 + * @addl_hdrs: protocol header fields 201 + * 202 + * This function will generate a flow profile based on fields associated with 203 + * the input fields to hash on, the flow type and use the VSI number to add 204 + * a flow entry to the profile. 205 + */ 206 + enum ice_status 207 + ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, 208 + u32 addl_hdrs) 209 + { 210 + enum ice_status status; 211 + 212 + if (hashed_flds == ICE_HASH_INVALID || 213 + !ice_is_vsi_valid(hw, vsi_handle)) 214 + return ICE_ERR_PARAM; 215 + 216 + mutex_lock(&hw->rss_locks); 217 + status = ice_add_rss_cfg_sync(hashed_flds, addl_hdrs, 218 + ICE_RSS_OUTER_HEADERS); 219 + mutex_unlock(&hw->rss_locks); 220 + 221 + return status; 222 + } 223 + 224 + /** 225 + * ice_replay_rss_cfg - replay RSS configurations associated with VSI 226 + * @hw: pointer to the hardware structure 227 + * @vsi_handle: software VSI handle 228 + */ 229 + enum ice_status ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle) 230 + { 231 + enum ice_status status = 0; 232 + struct ice_rss_cfg *r; 233 + 234 + if (!ice_is_vsi_valid(hw, vsi_handle)) 235 + return ICE_ERR_PARAM; 236 + 237 + mutex_lock(&hw->rss_locks); 238 + list_for_each_entry(r, &hw->rss_list_head, l_entry) { 239 + if (test_bit(vsi_handle, r->vsis)) { 240 + status = ice_add_rss_cfg_sync(r->hashed_flds, 241 + r->packet_hdr, 242 + ICE_RSS_OUTER_HEADERS); 243 + if (status) 244 + break; 245 + } 246 + } 247 + mutex_unlock(&hw->rss_locks); 248 + 249 + return status; 250 + }
+114
drivers/net/ethernet/intel/ice/ice_flow.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Copyright (c) 2019, Intel Corporation. */ 3 + 4 + #ifndef _ICE_FLOW_H_ 5 + #define _ICE_FLOW_H_ 6 + 7 + #define ICE_FLOW_FLD_OFF_INVAL 0xffff 8 + 9 + /* Generate flow hash field from flow field type(s) */ 10 + #define ICE_FLOW_HASH_IPV4 \ 11 + (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | \ 12 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)) 13 + #define ICE_FLOW_HASH_IPV6 \ 14 + (BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | \ 15 + BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)) 16 + #define ICE_FLOW_HASH_TCP_PORT \ 17 + (BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT) | \ 18 + BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)) 19 + #define ICE_FLOW_HASH_UDP_PORT \ 20 + (BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT) | \ 21 + BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)) 22 + 23 + #define ICE_HASH_INVALID 0 24 + #define ICE_HASH_TCP_IPV4 (ICE_FLOW_HASH_IPV4 | ICE_FLOW_HASH_TCP_PORT) 25 + #define ICE_HASH_TCP_IPV6 (ICE_FLOW_HASH_IPV6 | ICE_FLOW_HASH_TCP_PORT) 26 + #define ICE_HASH_UDP_IPV4 (ICE_FLOW_HASH_IPV4 | ICE_FLOW_HASH_UDP_PORT) 27 + #define ICE_HASH_UDP_IPV6 (ICE_FLOW_HASH_IPV6 | ICE_FLOW_HASH_UDP_PORT) 28 + 29 + /* Protocol header fields within a packet segment. A segment consists of one or 30 + * more protocol headers that make up a logical group of protocol headers. Each 31 + * logical group of protocol headers encapsulates or is encapsulated using/by 32 + * tunneling or encapsulation protocols for network virtualization such as GRE, 33 + * VxLAN, etc. 34 + */ 35 + enum ice_flow_seg_hdr { 36 + ICE_FLOW_SEG_HDR_NONE = 0x00000000, 37 + ICE_FLOW_SEG_HDR_IPV4 = 0x00000004, 38 + ICE_FLOW_SEG_HDR_IPV6 = 0x00000008, 39 + ICE_FLOW_SEG_HDR_TCP = 0x00000040, 40 + ICE_FLOW_SEG_HDR_UDP = 0x00000080, 41 + ICE_FLOW_SEG_HDR_SCTP = 0x00000100, 42 + }; 43 + 44 + enum ice_flow_field { 45 + /* L3 */ 46 + ICE_FLOW_FIELD_IDX_IPV4_SA, 47 + ICE_FLOW_FIELD_IDX_IPV4_DA, 48 + ICE_FLOW_FIELD_IDX_IPV6_SA, 49 + ICE_FLOW_FIELD_IDX_IPV6_DA, 50 + /* L4 */ 51 + ICE_FLOW_FIELD_IDX_TCP_SRC_PORT, 52 + ICE_FLOW_FIELD_IDX_TCP_DST_PORT, 53 + ICE_FLOW_FIELD_IDX_UDP_SRC_PORT, 54 + ICE_FLOW_FIELD_IDX_UDP_DST_PORT, 55 + /* The total number of enums must not exceed 64 */ 56 + ICE_FLOW_FIELD_IDX_MAX 57 + }; 58 + 59 + #define ICE_FLOW_SEG_MAX 2 60 + #define ICE_FLOW_SET_HDRS(seg, val) ((seg)->hdrs |= (u32)(val)) 61 + 62 + struct ice_flow_seg_xtrct { 63 + u8 prot_id; /* Protocol ID of extracted header field */ 64 + u16 off; /* Starting offset of the field in header in bytes */ 65 + u8 idx; /* Index of FV entry used */ 66 + u8 disp; /* Displacement of field in bits fr. FV entry's start */ 67 + }; 68 + 69 + enum ice_flow_fld_match_type { 70 + ICE_FLOW_FLD_TYPE_REG, /* Value, mask */ 71 + ICE_FLOW_FLD_TYPE_RANGE, /* Value, mask, last (upper bound) */ 72 + ICE_FLOW_FLD_TYPE_PREFIX, /* IP address, prefix, size of prefix */ 73 + ICE_FLOW_FLD_TYPE_SIZE, /* Value, mask, size of match */ 74 + }; 75 + 76 + struct ice_flow_fld_loc { 77 + /* Describe offsets of field information relative to the beginning of 78 + * input buffer provided when adding flow entries. 79 + */ 80 + u16 val; /* Offset where the value is located */ 81 + u16 mask; /* Offset where the mask/prefix value is located */ 82 + u16 last; /* Length or offset where the upper value is located */ 83 + }; 84 + 85 + struct ice_flow_fld_info { 86 + enum ice_flow_fld_match_type type; 87 + /* Location where to retrieve data from an input buffer */ 88 + struct ice_flow_fld_loc src; 89 + /* Location where to put the data into the final entry buffer */ 90 + struct ice_flow_fld_loc entry; 91 + struct ice_flow_seg_xtrct xtrct; 92 + }; 93 + 94 + struct ice_flow_seg_info { 95 + u32 hdrs; /* Bitmask indicating protocol headers present */ 96 + u64 match; /* Bitmask indicating header fields to be matched */ 97 + u64 range; /* Bitmask indicating header fields matched as ranges */ 98 + 99 + struct ice_flow_fld_info fields[ICE_FLOW_FIELD_IDX_MAX]; 100 + }; 101 + 102 + struct ice_rss_cfg { 103 + struct list_head l_entry; 104 + /* bitmap of VSIs added to the RSS entry */ 105 + DECLARE_BITMAP(vsis, ICE_MAX_VSI); 106 + u64 hashed_flds; 107 + u32 packet_hdr; 108 + }; 109 + 110 + enum ice_status ice_replay_rss_cfg(struct ice_hw *hw, u16 vsi_handle); 111 + enum ice_status 112 + ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, 113 + u32 addl_hdrs); 114 + #endif /* _ICE_FLOW_H_ */
+86 -1
drivers/net/ethernet/intel/ice/ice_lib.c
··· 3 3 4 4 #include "ice.h" 5 5 #include "ice_base.h" 6 + #include "ice_flow.h" 6 7 #include "ice_lib.h" 7 8 #include "ice_dcb_lib.h" 8 9 ··· 1088 1087 } 1089 1088 1090 1089 /** 1090 + * ice_vsi_set_rss_flow_fld - Sets RSS input set for different flows 1091 + * @vsi: VSI to be configured 1092 + * 1093 + * This function will only be called after successful download package call 1094 + * during initialization of PF. Since the downloaded package will erase the 1095 + * RSS section, this function will configure RSS input sets for different 1096 + * flow types. The last profile added has the highest priority, therefore 2 1097 + * tuple profiles (i.e. IPv4 src/dst) are added before 4 tuple profiles 1098 + * (i.e. IPv4 src/dst TCP src/dst port). 1099 + */ 1100 + static void ice_vsi_set_rss_flow_fld(struct ice_vsi *vsi) 1101 + { 1102 + u16 vsi_handle = vsi->idx, vsi_num = vsi->vsi_num; 1103 + struct ice_pf *pf = vsi->back; 1104 + struct ice_hw *hw = &pf->hw; 1105 + enum ice_status status; 1106 + struct device *dev; 1107 + 1108 + dev = ice_pf_to_dev(pf); 1109 + if (ice_is_safe_mode(pf)) { 1110 + dev_dbg(dev, "Advanced RSS disabled. Package download failed, vsi num = %d\n", 1111 + vsi_num); 1112 + return; 1113 + } 1114 + /* configure RSS for IPv4 with input set IP src/dst */ 1115 + status = ice_add_rss_cfg(hw, vsi_handle, ICE_FLOW_HASH_IPV4, 1116 + ICE_FLOW_SEG_HDR_IPV4); 1117 + if (status) 1118 + dev_dbg(dev, "ice_add_rss_cfg failed for ipv4 flow, vsi = %d, error = %d\n", 1119 + vsi_num, status); 1120 + 1121 + /* configure RSS for IPv6 with input set IPv6 src/dst */ 1122 + status = ice_add_rss_cfg(hw, vsi_handle, ICE_FLOW_HASH_IPV6, 1123 + ICE_FLOW_SEG_HDR_IPV6); 1124 + if (status) 1125 + dev_dbg(dev, "ice_add_rss_cfg failed for ipv6 flow, vsi = %d, error = %d\n", 1126 + vsi_num, status); 1127 + 1128 + /* configure RSS for tcp4 with input set IP src/dst, TCP src/dst */ 1129 + status = ice_add_rss_cfg(hw, vsi_handle, ICE_HASH_TCP_IPV4, 1130 + ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV4); 1131 + if (status) 1132 + dev_dbg(dev, "ice_add_rss_cfg failed for tcp4 flow, vsi = %d, error = %d\n", 1133 + vsi_num, status); 1134 + 1135 + /* configure RSS for udp4 with input set IP src/dst, UDP src/dst */ 1136 + status = ice_add_rss_cfg(hw, vsi_handle, ICE_HASH_UDP_IPV4, 1137 + ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV4); 1138 + if (status) 1139 + dev_dbg(dev, "ice_add_rss_cfg failed for udp4 flow, vsi = %d, error = %d\n", 1140 + vsi_num, status); 1141 + 1142 + /* configure RSS for sctp4 with input set IP src/dst */ 1143 + status = ice_add_rss_cfg(hw, vsi_handle, ICE_FLOW_HASH_IPV4, 1144 + ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV4); 1145 + if (status) 1146 + dev_dbg(dev, "ice_add_rss_cfg failed for sctp4 flow, vsi = %d, error = %d\n", 1147 + vsi_num, status); 1148 + 1149 + /* configure RSS for tcp6 with input set IPv6 src/dst, TCP src/dst */ 1150 + status = ice_add_rss_cfg(hw, vsi_handle, ICE_HASH_TCP_IPV6, 1151 + ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV6); 1152 + if (status) 1153 + dev_dbg(dev, "ice_add_rss_cfg failed for tcp6 flow, vsi = %d, error = %d\n", 1154 + vsi_num, status); 1155 + 1156 + /* configure RSS for udp6 with input set IPv6 src/dst, UDP src/dst */ 1157 + status = ice_add_rss_cfg(hw, vsi_handle, ICE_HASH_UDP_IPV6, 1158 + ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV6); 1159 + if (status) 1160 + dev_dbg(dev, "ice_add_rss_cfg failed for udp6 flow, vsi = %d, error = %d\n", 1161 + vsi_num, status); 1162 + 1163 + /* configure RSS for sctp6 with input set IPv6 src/dst */ 1164 + status = ice_add_rss_cfg(hw, vsi_handle, ICE_FLOW_HASH_IPV6, 1165 + ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV6); 1166 + if (status) 1167 + dev_dbg(dev, "ice_add_rss_cfg failed for sctp6 flow, vsi = %d, error = %d\n", 1168 + vsi_num, status); 1169 + } 1170 + 1171 + /** 1091 1172 * ice_add_mac_to_list - Add a MAC address filter entry to the list 1092 1173 * @vsi: the VSI to be forwarded to 1093 1174 * @add_list: pointer to the list which contains MAC filter entries ··· 1984 1901 * receive traffic on first queue. Hence no need to capture 1985 1902 * return value 1986 1903 */ 1987 - if (test_bit(ICE_FLAG_RSS_ENA, pf->flags)) 1904 + if (test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { 1988 1905 ice_vsi_cfg_rss_lut_key(vsi); 1906 + ice_vsi_set_rss_flow_fld(vsi); 1907 + } 1989 1908 break; 1990 1909 case ICE_VSI_VF: 1991 1910 /* VF driver will take care of creating netdev for this type and
+4
drivers/net/ethernet/intel/ice/ice_type.h
··· 559 559 560 560 /* HW block tables */ 561 561 struct ice_blk_info blk[ICE_BLK_COUNT]; 562 + struct mutex fl_profs_locks[ICE_BLK_COUNT]; /* lock fltr profiles */ 563 + struct list_head fl_profs[ICE_BLK_COUNT]; 564 + struct mutex rss_locks; /* protect RSS configuration */ 565 + struct list_head rss_list_head; 562 566 }; 563 567 564 568 /* Statistics collected by each port, VSI, VEB, and S-channel */