1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 2018-2020, Intel Corporation. */ 3 4 #include "ice_common.h" 5 6 /* These are training packet headers used to program flow director filters. */ 7 static const u8 ice_fdir_tcpv4_pkt[] = { 8 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 10 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 11 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 14 0x20, 0x00, 0x00, 0x00, 0x00, 0x00 15 }; 16 17 static const u8 ice_fdir_udpv4_pkt[] = { 18 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 20 0x00, 0x1C, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 21 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 0x00, 0x00, 24 }; 25 26 static const u8 ice_fdir_sctpv4_pkt[] = { 27 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 29 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x40, 0x84, 30 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 33 }; 34 35 static const u8 ice_fdir_ipv4_pkt[] = { 36 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 38 0x00, 0x14, 0x00, 0x00, 0x40, 0x00, 0x40, 0x10, 39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40 0x00, 0x00 41 }; 42 43 static const u8 ice_fdir_tcpv6_pkt[] = { 44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 46 0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 0x00, 0x00, 47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 0x00, 0x00, 0x50, 0x00, 0x20, 0x00, 0x00, 0x00, 53 0x00, 0x00, 54 }; 55 56 static const u8 ice_fdir_udpv6_pkt[] = { 57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 59 0x00, 0x00, 0x00, 0x08, 0x11, 0x40, 0x00, 0x00, 60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 65 }; 66 67 static const u8 ice_fdir_sctpv6_pkt[] = { 68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 69 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 70 0x00, 0x00, 0x00, 0x0C, 0x84, 0x40, 0x00, 0x00, 71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 0x00, 0x00, 77 }; 78 79 static const u8 ice_fdir_ipv6_pkt[] = { 80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 81 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 82 0x00, 0x00, 0x00, 0x00, 0x3B, 0x40, 0x00, 0x00, 83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 87 }; 88 89 static const u8 ice_fdir_tcp4_tun_pkt[] = { 90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 91 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 92 0x00, 0x5a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 95 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 98 0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0x00, 99 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 102 0x50, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 103 }; 104 105 static const u8 ice_fdir_udp4_tun_pkt[] = { 106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 107 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 108 0x00, 0x4e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 111 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 114 0x45, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x40, 0x00, 115 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 117 0x00, 0x00, 0x00, 0x00, 118 }; 119 120 static const u8 ice_fdir_sctp4_tun_pkt[] = { 121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 122 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 123 0x00, 0x52, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 126 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 129 0x45, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 130 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 133 }; 134 135 static const u8 ice_fdir_ip4_tun_pkt[] = { 136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 137 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 138 0x00, 0x46, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 141 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 144 0x45, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 145 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 146 0x00, 0x00, 0x00, 0x00, 147 }; 148 149 static const u8 ice_fdir_tcp6_tun_pkt[] = { 150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 151 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 152 0x00, 0x6e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 155 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 158 0x60, 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 164 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x20, 0x00, 165 0x00, 0x00, 0x00, 0x00, 166 }; 167 168 static const u8 ice_fdir_udp6_tun_pkt[] = { 169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 170 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 171 0x00, 0x62, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 174 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 177 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x11, 0x40, 178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 183 }; 184 185 static const u8 ice_fdir_sctp6_tun_pkt[] = { 186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 187 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 188 0x00, 0x66, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 191 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 194 0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x84, 0x40, 195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 200 0x00, 0x00, 0x00, 0x00, 201 }; 202 203 static const u8 ice_fdir_ip6_tun_pkt[] = { 204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 205 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 206 0x00, 0x5a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 209 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 212 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x40, 213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 217 }; 218 219 /* Flow Director no-op training packet table */ 220 static const struct ice_fdir_base_pkt ice_fdir_pkt[] = { 221 { 222 ICE_FLTR_PTYPE_NONF_IPV4_TCP, 223 sizeof(ice_fdir_tcpv4_pkt), ice_fdir_tcpv4_pkt, 224 sizeof(ice_fdir_tcp4_tun_pkt), ice_fdir_tcp4_tun_pkt, 225 }, 226 { 227 ICE_FLTR_PTYPE_NONF_IPV4_UDP, 228 sizeof(ice_fdir_udpv4_pkt), ice_fdir_udpv4_pkt, 229 sizeof(ice_fdir_udp4_tun_pkt), ice_fdir_udp4_tun_pkt, 230 }, 231 { 232 ICE_FLTR_PTYPE_NONF_IPV4_SCTP, 233 sizeof(ice_fdir_sctpv4_pkt), ice_fdir_sctpv4_pkt, 234 sizeof(ice_fdir_sctp4_tun_pkt), ice_fdir_sctp4_tun_pkt, 235 }, 236 { 237 ICE_FLTR_PTYPE_NONF_IPV4_OTHER, 238 sizeof(ice_fdir_ipv4_pkt), ice_fdir_ipv4_pkt, 239 sizeof(ice_fdir_ip4_tun_pkt), ice_fdir_ip4_tun_pkt, 240 }, 241 { 242 ICE_FLTR_PTYPE_NONF_IPV6_TCP, 243 sizeof(ice_fdir_tcpv6_pkt), ice_fdir_tcpv6_pkt, 244 sizeof(ice_fdir_tcp6_tun_pkt), ice_fdir_tcp6_tun_pkt, 245 }, 246 { 247 ICE_FLTR_PTYPE_NONF_IPV6_UDP, 248 sizeof(ice_fdir_udpv6_pkt), ice_fdir_udpv6_pkt, 249 sizeof(ice_fdir_udp6_tun_pkt), ice_fdir_udp6_tun_pkt, 250 }, 251 { 252 ICE_FLTR_PTYPE_NONF_IPV6_SCTP, 253 sizeof(ice_fdir_sctpv6_pkt), ice_fdir_sctpv6_pkt, 254 sizeof(ice_fdir_sctp6_tun_pkt), ice_fdir_sctp6_tun_pkt, 255 }, 256 { 257 ICE_FLTR_PTYPE_NONF_IPV6_OTHER, 258 sizeof(ice_fdir_ipv6_pkt), ice_fdir_ipv6_pkt, 259 sizeof(ice_fdir_ip6_tun_pkt), ice_fdir_ip6_tun_pkt, 260 }, 261 }; 262 263 #define ICE_FDIR_NUM_PKT ARRAY_SIZE(ice_fdir_pkt) 264 265 /** 266 * ice_set_dflt_val_fd_desc 267 * @fd_fltr_ctx: pointer to fd filter descriptor 268 */ 269 static void ice_set_dflt_val_fd_desc(struct ice_fd_fltr_desc_ctx *fd_fltr_ctx) 270 { 271 fd_fltr_ctx->comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO; 272 fd_fltr_ctx->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL; 273 fd_fltr_ctx->fd_space = ICE_FXD_FLTR_QW0_FD_SPACE_GUAR_BEST; 274 fd_fltr_ctx->cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS; 275 fd_fltr_ctx->evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_TRUE; 276 fd_fltr_ctx->toq = ICE_FXD_FLTR_QW0_TO_Q_EQUALS_QINDEX; 277 fd_fltr_ctx->toq_prio = ICE_FXD_FLTR_QW0_TO_Q_PRIO1; 278 fd_fltr_ctx->dpu_recipe = ICE_FXD_FLTR_QW0_DPU_RECIPE_DFLT; 279 fd_fltr_ctx->drop = ICE_FXD_FLTR_QW0_DROP_NO; 280 fd_fltr_ctx->flex_prio = ICE_FXD_FLTR_QW0_FLEX_PRI_NONE; 281 fd_fltr_ctx->flex_mdid = ICE_FXD_FLTR_QW0_FLEX_MDID0; 282 fd_fltr_ctx->flex_val = ICE_FXD_FLTR_QW0_FLEX_VAL0; 283 fd_fltr_ctx->dtype = ICE_TX_DESC_DTYPE_FLTR_PROG; 284 fd_fltr_ctx->desc_prof_prio = ICE_FXD_FLTR_QW1_PROF_PRIO_ZERO; 285 fd_fltr_ctx->desc_prof = ICE_FXD_FLTR_QW1_PROF_ZERO; 286 fd_fltr_ctx->swap = ICE_FXD_FLTR_QW1_SWAP_SET; 287 fd_fltr_ctx->fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_ONE; 288 fd_fltr_ctx->fdid_mdid = ICE_FXD_FLTR_QW1_FDID_MDID_FD; 289 fd_fltr_ctx->fdid = ICE_FXD_FLTR_QW1_FDID_ZERO; 290 } 291 292 /** 293 * ice_set_fd_desc_val 294 * @ctx: pointer to fd filter descriptor context 295 * @fdir_desc: populated with fd filter descriptor values 296 */ 297 static void 298 ice_set_fd_desc_val(struct ice_fd_fltr_desc_ctx *ctx, 299 struct ice_fltr_desc *fdir_desc) 300 { 301 u64 qword; 302 303 /* prep QW0 of FD filter programming desc */ 304 qword = ((u64)ctx->qindex << ICE_FXD_FLTR_QW0_QINDEX_S) & 305 ICE_FXD_FLTR_QW0_QINDEX_M; 306 qword |= ((u64)ctx->comp_q << ICE_FXD_FLTR_QW0_COMP_Q_S) & 307 ICE_FXD_FLTR_QW0_COMP_Q_M; 308 qword |= ((u64)ctx->comp_report << ICE_FXD_FLTR_QW0_COMP_REPORT_S) & 309 ICE_FXD_FLTR_QW0_COMP_REPORT_M; 310 qword |= ((u64)ctx->fd_space << ICE_FXD_FLTR_QW0_FD_SPACE_S) & 311 ICE_FXD_FLTR_QW0_FD_SPACE_M; 312 qword |= ((u64)ctx->cnt_index << ICE_FXD_FLTR_QW0_STAT_CNT_S) & 313 ICE_FXD_FLTR_QW0_STAT_CNT_M; 314 qword |= ((u64)ctx->cnt_ena << ICE_FXD_FLTR_QW0_STAT_ENA_S) & 315 ICE_FXD_FLTR_QW0_STAT_ENA_M; 316 qword |= ((u64)ctx->evict_ena << ICE_FXD_FLTR_QW0_EVICT_ENA_S) & 317 ICE_FXD_FLTR_QW0_EVICT_ENA_M; 318 qword |= ((u64)ctx->toq << ICE_FXD_FLTR_QW0_TO_Q_S) & 319 ICE_FXD_FLTR_QW0_TO_Q_M; 320 qword |= ((u64)ctx->toq_prio << ICE_FXD_FLTR_QW0_TO_Q_PRI_S) & 321 ICE_FXD_FLTR_QW0_TO_Q_PRI_M; 322 qword |= ((u64)ctx->dpu_recipe << ICE_FXD_FLTR_QW0_DPU_RECIPE_S) & 323 ICE_FXD_FLTR_QW0_DPU_RECIPE_M; 324 qword |= ((u64)ctx->drop << ICE_FXD_FLTR_QW0_DROP_S) & 325 ICE_FXD_FLTR_QW0_DROP_M; 326 qword |= ((u64)ctx->flex_prio << ICE_FXD_FLTR_QW0_FLEX_PRI_S) & 327 ICE_FXD_FLTR_QW0_FLEX_PRI_M; 328 qword |= ((u64)ctx->flex_mdid << ICE_FXD_FLTR_QW0_FLEX_MDID_S) & 329 ICE_FXD_FLTR_QW0_FLEX_MDID_M; 330 qword |= ((u64)ctx->flex_val << ICE_FXD_FLTR_QW0_FLEX_VAL_S) & 331 ICE_FXD_FLTR_QW0_FLEX_VAL_M; 332 fdir_desc->qidx_compq_space_stat = cpu_to_le64(qword); 333 334 /* prep QW1 of FD filter programming desc */ 335 qword = ((u64)ctx->dtype << ICE_FXD_FLTR_QW1_DTYPE_S) & 336 ICE_FXD_FLTR_QW1_DTYPE_M; 337 qword |= ((u64)ctx->pcmd << ICE_FXD_FLTR_QW1_PCMD_S) & 338 ICE_FXD_FLTR_QW1_PCMD_M; 339 qword |= ((u64)ctx->desc_prof_prio << ICE_FXD_FLTR_QW1_PROF_PRI_S) & 340 ICE_FXD_FLTR_QW1_PROF_PRI_M; 341 qword |= ((u64)ctx->desc_prof << ICE_FXD_FLTR_QW1_PROF_S) & 342 ICE_FXD_FLTR_QW1_PROF_M; 343 qword |= ((u64)ctx->fd_vsi << ICE_FXD_FLTR_QW1_FD_VSI_S) & 344 ICE_FXD_FLTR_QW1_FD_VSI_M; 345 qword |= ((u64)ctx->swap << ICE_FXD_FLTR_QW1_SWAP_S) & 346 ICE_FXD_FLTR_QW1_SWAP_M; 347 qword |= ((u64)ctx->fdid_prio << ICE_FXD_FLTR_QW1_FDID_PRI_S) & 348 ICE_FXD_FLTR_QW1_FDID_PRI_M; 349 qword |= ((u64)ctx->fdid_mdid << ICE_FXD_FLTR_QW1_FDID_MDID_S) & 350 ICE_FXD_FLTR_QW1_FDID_MDID_M; 351 qword |= ((u64)ctx->fdid << ICE_FXD_FLTR_QW1_FDID_S) & 352 ICE_FXD_FLTR_QW1_FDID_M; 353 fdir_desc->dtype_cmd_vsi_fdid = cpu_to_le64(qword); 354 } 355 356 /** 357 * ice_fdir_get_prgm_desc - set a fdir descriptor from a fdir filter struct 358 * @hw: pointer to the hardware structure 359 * @input: filter 360 * @fdesc: filter descriptor 361 * @add: if add is true, this is an add operation, false implies delete 362 */ 363 void 364 ice_fdir_get_prgm_desc(struct ice_hw *hw, struct ice_fdir_fltr *input, 365 struct ice_fltr_desc *fdesc, bool add) 366 { 367 struct ice_fd_fltr_desc_ctx fdir_fltr_ctx = { 0 }; 368 369 /* set default context info */ 370 ice_set_dflt_val_fd_desc(&fdir_fltr_ctx); 371 372 /* change sideband filtering values */ 373 fdir_fltr_ctx.fdid = input->fltr_id; 374 if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DROP_PKT) { 375 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_YES; 376 fdir_fltr_ctx.qindex = 0; 377 } else { 378 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO; 379 fdir_fltr_ctx.qindex = input->q_index; 380 } 381 fdir_fltr_ctx.cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS; 382 fdir_fltr_ctx.cnt_index = input->cnt_index; 383 fdir_fltr_ctx.fd_vsi = ice_get_hw_vsi_num(hw, input->dest_vsi); 384 fdir_fltr_ctx.evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_FALSE; 385 fdir_fltr_ctx.toq_prio = 3; 386 fdir_fltr_ctx.pcmd = add ? ICE_FXD_FLTR_QW1_PCMD_ADD : 387 ICE_FXD_FLTR_QW1_PCMD_REMOVE; 388 fdir_fltr_ctx.swap = ICE_FXD_FLTR_QW1_SWAP_NOT_SET; 389 fdir_fltr_ctx.comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO; 390 fdir_fltr_ctx.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL; 391 fdir_fltr_ctx.fdid_prio = 3; 392 fdir_fltr_ctx.desc_prof = 1; 393 fdir_fltr_ctx.desc_prof_prio = 3; 394 ice_set_fd_desc_val(&fdir_fltr_ctx, fdesc); 395 } 396 397 /** 398 * ice_alloc_fd_res_cntr - obtain counter resource for FD type 399 * @hw: pointer to the hardware structure 400 * @cntr_id: returns counter index 401 */ 402 enum ice_status ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id) 403 { 404 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK, 405 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id); 406 } 407 408 /** 409 * ice_free_fd_res_cntr - Free counter resource for FD type 410 * @hw: pointer to the hardware structure 411 * @cntr_id: counter index to be freed 412 */ 413 enum ice_status ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id) 414 { 415 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK, 416 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id); 417 } 418 419 /** 420 * ice_alloc_fd_guar_item - allocate resource for FD guaranteed entries 421 * @hw: pointer to the hardware structure 422 * @cntr_id: returns counter index 423 * @num_fltr: number of filter entries to be allocated 424 */ 425 enum ice_status 426 ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr) 427 { 428 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES, 429 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr, 430 cntr_id); 431 } 432 433 /** 434 * ice_alloc_fd_shrd_item - allocate resource for flow director shared entries 435 * @hw: pointer to the hardware structure 436 * @cntr_id: returns counter index 437 * @num_fltr: number of filter entries to be allocated 438 */ 439 enum ice_status 440 ice_alloc_fd_shrd_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr) 441 { 442 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES, 443 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr, 444 cntr_id); 445 } 446 447 /** 448 * ice_get_fdir_cnt_all - get the number of Flow Director filters 449 * @hw: hardware data structure 450 * 451 * Returns the number of filters available on device 452 */ 453 int ice_get_fdir_cnt_all(struct ice_hw *hw) 454 { 455 return hw->func_caps.fd_fltr_guar + hw->func_caps.fd_fltr_best_effort; 456 } 457 458 /** 459 * ice_pkt_insert_ipv6_addr - insert a be32 IPv6 address into a memory buffer 460 * @pkt: packet buffer 461 * @offset: offset into buffer 462 * @addr: IPv6 address to convert and insert into pkt at offset 463 */ 464 static void ice_pkt_insert_ipv6_addr(u8 *pkt, int offset, __be32 *addr) 465 { 466 int idx; 467 468 for (idx = 0; idx < ICE_IPV6_ADDR_LEN_AS_U32; idx++) 469 memcpy(pkt + offset + idx * sizeof(*addr), &addr[idx], 470 sizeof(*addr)); 471 } 472 473 /** 474 * ice_pkt_insert_u16 - insert a be16 value into a memory buffer 475 * @pkt: packet buffer 476 * @offset: offset into buffer 477 * @data: 16 bit value to convert and insert into pkt at offset 478 */ 479 static void ice_pkt_insert_u16(u8 *pkt, int offset, __be16 data) 480 { 481 memcpy(pkt + offset, &data, sizeof(data)); 482 } 483 484 /** 485 * ice_pkt_insert_u32 - insert a be32 value into a memory buffer 486 * @pkt: packet buffer 487 * @offset: offset into buffer 488 * @data: 32 bit value to convert and insert into pkt at offset 489 */ 490 static void ice_pkt_insert_u32(u8 *pkt, int offset, __be32 data) 491 { 492 memcpy(pkt + offset, &data, sizeof(data)); 493 } 494 495 /** 496 * ice_fdir_get_gen_prgm_pkt - generate a training packet 497 * @hw: pointer to the hardware structure 498 * @input: flow director filter data structure 499 * @pkt: pointer to return filter packet 500 * @frag: generate a fragment packet 501 * @tun: true implies generate a tunnel packet 502 */ 503 enum ice_status 504 ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input, 505 u8 *pkt, bool frag, bool tun) 506 { 507 enum ice_fltr_ptype flow; 508 u16 tnl_port; 509 u8 *loc; 510 u16 idx; 511 512 if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) { 513 switch (input->ip.v4.proto) { 514 case IPPROTO_TCP: 515 flow = ICE_FLTR_PTYPE_NONF_IPV4_TCP; 516 break; 517 case IPPROTO_UDP: 518 flow = ICE_FLTR_PTYPE_NONF_IPV4_UDP; 519 break; 520 case IPPROTO_SCTP: 521 flow = ICE_FLTR_PTYPE_NONF_IPV4_SCTP; 522 break; 523 case IPPROTO_IP: 524 flow = ICE_FLTR_PTYPE_NONF_IPV4_OTHER; 525 break; 526 default: 527 return ICE_ERR_PARAM; 528 } 529 } else if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) { 530 switch (input->ip.v6.proto) { 531 case IPPROTO_TCP: 532 flow = ICE_FLTR_PTYPE_NONF_IPV6_TCP; 533 break; 534 case IPPROTO_UDP: 535 flow = ICE_FLTR_PTYPE_NONF_IPV6_UDP; 536 break; 537 case IPPROTO_SCTP: 538 flow = ICE_FLTR_PTYPE_NONF_IPV6_SCTP; 539 break; 540 case IPPROTO_IP: 541 flow = ICE_FLTR_PTYPE_NONF_IPV6_OTHER; 542 break; 543 default: 544 return ICE_ERR_PARAM; 545 } 546 } else { 547 flow = input->flow_type; 548 } 549 550 for (idx = 0; idx < ICE_FDIR_NUM_PKT; idx++) 551 if (ice_fdir_pkt[idx].flow == flow) 552 break; 553 if (idx == ICE_FDIR_NUM_PKT) 554 return ICE_ERR_PARAM; 555 if (!tun) { 556 memcpy(pkt, ice_fdir_pkt[idx].pkt, ice_fdir_pkt[idx].pkt_len); 557 loc = pkt; 558 } else { 559 if (!ice_get_open_tunnel_port(hw, TNL_ALL, &tnl_port)) 560 return ICE_ERR_DOES_NOT_EXIST; 561 if (!ice_fdir_pkt[idx].tun_pkt) 562 return ICE_ERR_PARAM; 563 memcpy(pkt, ice_fdir_pkt[idx].tun_pkt, 564 ice_fdir_pkt[idx].tun_pkt_len); 565 ice_pkt_insert_u16(pkt, ICE_IPV4_UDP_DST_PORT_OFFSET, 566 htons(tnl_port)); 567 loc = &pkt[ICE_FDIR_TUN_PKT_OFF]; 568 } 569 570 /* Reverse the src and dst, since the HW expects them to be from Tx 571 * perspective. The input from user is from Rx filter perspective. 572 */ 573 switch (flow) { 574 case ICE_FLTR_PTYPE_NONF_IPV4_TCP: 575 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 576 input->ip.v4.src_ip); 577 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_DST_PORT_OFFSET, 578 input->ip.v4.src_port); 579 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 580 input->ip.v4.dst_ip); 581 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET, 582 input->ip.v4.dst_port); 583 if (frag) 584 loc[20] = ICE_FDIR_IPV4_PKT_FLAG_DF; 585 break; 586 case ICE_FLTR_PTYPE_NONF_IPV4_UDP: 587 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 588 input->ip.v4.src_ip); 589 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_DST_PORT_OFFSET, 590 input->ip.v4.src_port); 591 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 592 input->ip.v4.dst_ip); 593 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET, 594 input->ip.v4.dst_port); 595 break; 596 case ICE_FLTR_PTYPE_NONF_IPV4_SCTP: 597 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 598 input->ip.v4.src_ip); 599 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_DST_PORT_OFFSET, 600 input->ip.v4.src_port); 601 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 602 input->ip.v4.dst_ip); 603 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_SRC_PORT_OFFSET, 604 input->ip.v4.dst_port); 605 break; 606 case ICE_FLTR_PTYPE_NONF_IPV4_OTHER: 607 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 608 input->ip.v4.src_ip); 609 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 610 input->ip.v4.dst_ip); 611 ice_pkt_insert_u16(loc, ICE_IPV4_PROTO_OFFSET, 0); 612 break; 613 case ICE_FLTR_PTYPE_NONF_IPV6_TCP: 614 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 615 input->ip.v6.src_ip); 616 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 617 input->ip.v6.dst_ip); 618 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_DST_PORT_OFFSET, 619 input->ip.v6.src_port); 620 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET, 621 input->ip.v6.dst_port); 622 break; 623 case ICE_FLTR_PTYPE_NONF_IPV6_UDP: 624 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 625 input->ip.v6.src_ip); 626 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 627 input->ip.v6.dst_ip); 628 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_DST_PORT_OFFSET, 629 input->ip.v6.src_port); 630 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET, 631 input->ip.v6.dst_port); 632 break; 633 case ICE_FLTR_PTYPE_NONF_IPV6_SCTP: 634 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 635 input->ip.v6.src_ip); 636 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 637 input->ip.v6.dst_ip); 638 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_DST_PORT_OFFSET, 639 input->ip.v6.src_port); 640 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET, 641 input->ip.v6.dst_port); 642 break; 643 case ICE_FLTR_PTYPE_NONF_IPV6_OTHER: 644 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 645 input->ip.v6.src_ip); 646 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 647 input->ip.v6.dst_ip); 648 break; 649 default: 650 return ICE_ERR_PARAM; 651 } 652 653 if (input->flex_fltr) 654 ice_pkt_insert_u16(loc, input->flex_offset, input->flex_word); 655 656 return 0; 657 } 658 659 /** 660 * ice_fdir_has_frag - does flow type have 2 ptypes 661 * @flow: flow ptype 662 * 663 * returns true is there is a fragment packet for this ptype 664 */ 665 bool ice_fdir_has_frag(enum ice_fltr_ptype flow) 666 { 667 if (flow == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) 668 return true; 669 else 670 return false; 671 } 672 673 /** 674 * ice_fdir_find_by_idx - find filter with idx 675 * @hw: pointer to hardware structure 676 * @fltr_idx: index to find. 677 * 678 * Returns pointer to filter if found or null 679 */ 680 struct ice_fdir_fltr * 681 ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx) 682 { 683 struct ice_fdir_fltr *rule; 684 685 list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) { 686 /* rule ID found in the list */ 687 if (fltr_idx == rule->fltr_id) 688 return rule; 689 if (fltr_idx < rule->fltr_id) 690 break; 691 } 692 return NULL; 693 } 694 695 /** 696 * ice_fdir_list_add_fltr - add a new node to the flow director filter list 697 * @hw: hardware structure 698 * @fltr: filter node to add to structure 699 */ 700 void ice_fdir_list_add_fltr(struct ice_hw *hw, struct ice_fdir_fltr *fltr) 701 { 702 struct ice_fdir_fltr *rule, *parent = NULL; 703 704 list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) { 705 /* rule ID found or pass its spot in the list */ 706 if (rule->fltr_id >= fltr->fltr_id) 707 break; 708 parent = rule; 709 } 710 711 if (parent) 712 list_add(&fltr->fltr_node, &parent->fltr_node); 713 else 714 list_add(&fltr->fltr_node, &hw->fdir_list_head); 715 } 716 717 /** 718 * ice_fdir_update_cntrs - increment / decrement filter counter 719 * @hw: pointer to hardware structure 720 * @flow: filter flow type 721 * @add: true implies filters added 722 */ 723 void 724 ice_fdir_update_cntrs(struct ice_hw *hw, enum ice_fltr_ptype flow, bool add) 725 { 726 int incr; 727 728 incr = add ? 1 : -1; 729 hw->fdir_active_fltr += incr; 730 731 if (flow == ICE_FLTR_PTYPE_NONF_NONE || flow >= ICE_FLTR_PTYPE_MAX) 732 ice_debug(hw, ICE_DBG_SW, "Unknown filter type %d\n", flow); 733 else 734 hw->fdir_fltr_cnt[flow] += incr; 735 } 736 737 /** 738 * ice_cmp_ipv6_addr - compare 2 IP v6 addresses 739 * @a: IP v6 address 740 * @b: IP v6 address 741 * 742 * Returns 0 on equal, returns non-0 if different 743 */ 744 static int ice_cmp_ipv6_addr(__be32 *a, __be32 *b) 745 { 746 return memcmp(a, b, 4 * sizeof(__be32)); 747 } 748 749 /** 750 * ice_fdir_comp_rules - compare 2 filters 751 * @a: a Flow Director filter data structure 752 * @b: a Flow Director filter data structure 753 * @v6: bool true if v6 filter 754 * 755 * Returns true if the filters match 756 */ 757 static bool 758 ice_fdir_comp_rules(struct ice_fdir_fltr *a, struct ice_fdir_fltr *b, bool v6) 759 { 760 enum ice_fltr_ptype flow_type = a->flow_type; 761 762 /* The calling function already checks that the two filters have the 763 * same flow_type. 764 */ 765 if (!v6) { 766 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP || 767 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP || 768 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP) { 769 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip && 770 a->ip.v4.src_ip == b->ip.v4.src_ip && 771 a->ip.v4.dst_port == b->ip.v4.dst_port && 772 a->ip.v4.src_port == b->ip.v4.src_port) 773 return true; 774 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) { 775 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip && 776 a->ip.v4.src_ip == b->ip.v4.src_ip && 777 a->ip.v4.l4_header == b->ip.v4.l4_header && 778 a->ip.v4.proto == b->ip.v4.proto && 779 a->ip.v4.ip_ver == b->ip.v4.ip_ver && 780 a->ip.v4.tos == b->ip.v4.tos) 781 return true; 782 } 783 } else { 784 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP || 785 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_TCP || 786 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_SCTP) { 787 if (a->ip.v6.dst_port == b->ip.v6.dst_port && 788 a->ip.v6.src_port == b->ip.v6.src_port && 789 !ice_cmp_ipv6_addr(a->ip.v6.dst_ip, 790 b->ip.v6.dst_ip) && 791 !ice_cmp_ipv6_addr(a->ip.v6.src_ip, 792 b->ip.v6.src_ip)) 793 return true; 794 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) { 795 if (a->ip.v6.dst_port == b->ip.v6.dst_port && 796 a->ip.v6.src_port == b->ip.v6.src_port) 797 return true; 798 } 799 } 800 801 return false; 802 } 803 804 /** 805 * ice_fdir_is_dup_fltr - test if filter is already in list for PF 806 * @hw: hardware data structure 807 * @input: Flow Director filter data structure 808 * 809 * Returns true if the filter is found in the list 810 */ 811 bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input) 812 { 813 struct ice_fdir_fltr *rule; 814 bool ret = false; 815 816 list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) { 817 enum ice_fltr_ptype flow_type; 818 819 if (rule->flow_type != input->flow_type) 820 continue; 821 822 flow_type = input->flow_type; 823 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP || 824 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP || 825 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP || 826 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) 827 ret = ice_fdir_comp_rules(rule, input, false); 828 else 829 ret = ice_fdir_comp_rules(rule, input, true); 830 if (ret) { 831 if (rule->fltr_id == input->fltr_id && 832 rule->q_index != input->q_index) 833 ret = false; 834 else 835 break; 836 } 837 } 838 839 return ret; 840 } 841