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_pkt_insert_mac_addr - insert a MAC addr into a memory buffer. 497 * @pkt: packet buffer 498 * @addr: MAC address to convert and insert into pkt at offset 499 */ 500 static void ice_pkt_insert_mac_addr(u8 *pkt, u8 *addr) 501 { 502 ether_addr_copy(pkt, addr); 503 } 504 505 /** 506 * ice_fdir_get_gen_prgm_pkt - generate a training packet 507 * @hw: pointer to the hardware structure 508 * @input: flow director filter data structure 509 * @pkt: pointer to return filter packet 510 * @frag: generate a fragment packet 511 * @tun: true implies generate a tunnel packet 512 */ 513 enum ice_status 514 ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input, 515 u8 *pkt, bool frag, bool tun) 516 { 517 enum ice_fltr_ptype flow; 518 u16 tnl_port; 519 u8 *loc; 520 u16 idx; 521 522 if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) { 523 switch (input->ip.v4.proto) { 524 case IPPROTO_TCP: 525 flow = ICE_FLTR_PTYPE_NONF_IPV4_TCP; 526 break; 527 case IPPROTO_UDP: 528 flow = ICE_FLTR_PTYPE_NONF_IPV4_UDP; 529 break; 530 case IPPROTO_SCTP: 531 flow = ICE_FLTR_PTYPE_NONF_IPV4_SCTP; 532 break; 533 case IPPROTO_IP: 534 flow = ICE_FLTR_PTYPE_NONF_IPV4_OTHER; 535 break; 536 default: 537 return ICE_ERR_PARAM; 538 } 539 } else if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) { 540 switch (input->ip.v6.proto) { 541 case IPPROTO_TCP: 542 flow = ICE_FLTR_PTYPE_NONF_IPV6_TCP; 543 break; 544 case IPPROTO_UDP: 545 flow = ICE_FLTR_PTYPE_NONF_IPV6_UDP; 546 break; 547 case IPPROTO_SCTP: 548 flow = ICE_FLTR_PTYPE_NONF_IPV6_SCTP; 549 break; 550 case IPPROTO_IP: 551 flow = ICE_FLTR_PTYPE_NONF_IPV6_OTHER; 552 break; 553 default: 554 return ICE_ERR_PARAM; 555 } 556 } else { 557 flow = input->flow_type; 558 } 559 560 for (idx = 0; idx < ICE_FDIR_NUM_PKT; idx++) 561 if (ice_fdir_pkt[idx].flow == flow) 562 break; 563 if (idx == ICE_FDIR_NUM_PKT) 564 return ICE_ERR_PARAM; 565 if (!tun) { 566 memcpy(pkt, ice_fdir_pkt[idx].pkt, ice_fdir_pkt[idx].pkt_len); 567 loc = pkt; 568 } else { 569 if (!ice_get_open_tunnel_port(hw, &tnl_port)) 570 return ICE_ERR_DOES_NOT_EXIST; 571 if (!ice_fdir_pkt[idx].tun_pkt) 572 return ICE_ERR_PARAM; 573 memcpy(pkt, ice_fdir_pkt[idx].tun_pkt, 574 ice_fdir_pkt[idx].tun_pkt_len); 575 ice_pkt_insert_u16(pkt, ICE_IPV4_UDP_DST_PORT_OFFSET, 576 htons(tnl_port)); 577 loc = &pkt[ICE_FDIR_TUN_PKT_OFF]; 578 } 579 580 /* Reverse the src and dst, since the HW expects them to be from Tx 581 * perspective. The input from user is from Rx filter perspective. 582 */ 583 switch (flow) { 584 case ICE_FLTR_PTYPE_NONF_IPV4_TCP: 585 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 586 input->ip.v4.src_ip); 587 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_DST_PORT_OFFSET, 588 input->ip.v4.src_port); 589 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 590 input->ip.v4.dst_ip); 591 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET, 592 input->ip.v4.dst_port); 593 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 594 if (frag) 595 loc[20] = ICE_FDIR_IPV4_PKT_FLAG_DF; 596 break; 597 case ICE_FLTR_PTYPE_NONF_IPV4_UDP: 598 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 599 input->ip.v4.src_ip); 600 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_DST_PORT_OFFSET, 601 input->ip.v4.src_port); 602 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 603 input->ip.v4.dst_ip); 604 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET, 605 input->ip.v4.dst_port); 606 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 607 ice_pkt_insert_mac_addr(loc + ETH_ALEN, 608 input->ext_data.src_mac); 609 break; 610 case ICE_FLTR_PTYPE_NONF_IPV4_SCTP: 611 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 612 input->ip.v4.src_ip); 613 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_DST_PORT_OFFSET, 614 input->ip.v4.src_port); 615 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 616 input->ip.v4.dst_ip); 617 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_SRC_PORT_OFFSET, 618 input->ip.v4.dst_port); 619 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 620 break; 621 case ICE_FLTR_PTYPE_NONF_IPV4_OTHER: 622 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 623 input->ip.v4.src_ip); 624 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 625 input->ip.v4.dst_ip); 626 ice_pkt_insert_u16(loc, ICE_IPV4_PROTO_OFFSET, 0); 627 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 628 break; 629 case ICE_FLTR_PTYPE_NONF_IPV6_TCP: 630 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 631 input->ip.v6.src_ip); 632 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 633 input->ip.v6.dst_ip); 634 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_DST_PORT_OFFSET, 635 input->ip.v6.src_port); 636 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET, 637 input->ip.v6.dst_port); 638 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 639 break; 640 case ICE_FLTR_PTYPE_NONF_IPV6_UDP: 641 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 642 input->ip.v6.src_ip); 643 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 644 input->ip.v6.dst_ip); 645 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_DST_PORT_OFFSET, 646 input->ip.v6.src_port); 647 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET, 648 input->ip.v6.dst_port); 649 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 650 break; 651 case ICE_FLTR_PTYPE_NONF_IPV6_SCTP: 652 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 653 input->ip.v6.src_ip); 654 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 655 input->ip.v6.dst_ip); 656 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_DST_PORT_OFFSET, 657 input->ip.v6.src_port); 658 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET, 659 input->ip.v6.dst_port); 660 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 661 break; 662 case ICE_FLTR_PTYPE_NONF_IPV6_OTHER: 663 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 664 input->ip.v6.src_ip); 665 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 666 input->ip.v6.dst_ip); 667 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 668 break; 669 default: 670 return ICE_ERR_PARAM; 671 } 672 673 if (input->flex_fltr) 674 ice_pkt_insert_u16(loc, input->flex_offset, input->flex_word); 675 676 return 0; 677 } 678 679 /** 680 * ice_fdir_has_frag - does flow type have 2 ptypes 681 * @flow: flow ptype 682 * 683 * returns true is there is a fragment packet for this ptype 684 */ 685 bool ice_fdir_has_frag(enum ice_fltr_ptype flow) 686 { 687 if (flow == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) 688 return true; 689 else 690 return false; 691 } 692 693 /** 694 * ice_fdir_find_by_idx - find filter with idx 695 * @hw: pointer to hardware structure 696 * @fltr_idx: index to find. 697 * 698 * Returns pointer to filter if found or null 699 */ 700 struct ice_fdir_fltr * 701 ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx) 702 { 703 struct ice_fdir_fltr *rule; 704 705 list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) { 706 /* rule ID found in the list */ 707 if (fltr_idx == rule->fltr_id) 708 return rule; 709 if (fltr_idx < rule->fltr_id) 710 break; 711 } 712 return NULL; 713 } 714 715 /** 716 * ice_fdir_list_add_fltr - add a new node to the flow director filter list 717 * @hw: hardware structure 718 * @fltr: filter node to add to structure 719 */ 720 void ice_fdir_list_add_fltr(struct ice_hw *hw, struct ice_fdir_fltr *fltr) 721 { 722 struct ice_fdir_fltr *rule, *parent = NULL; 723 724 list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) { 725 /* rule ID found or pass its spot in the list */ 726 if (rule->fltr_id >= fltr->fltr_id) 727 break; 728 parent = rule; 729 } 730 731 if (parent) 732 list_add(&fltr->fltr_node, &parent->fltr_node); 733 else 734 list_add(&fltr->fltr_node, &hw->fdir_list_head); 735 } 736 737 /** 738 * ice_fdir_update_cntrs - increment / decrement filter counter 739 * @hw: pointer to hardware structure 740 * @flow: filter flow type 741 * @add: true implies filters added 742 */ 743 void 744 ice_fdir_update_cntrs(struct ice_hw *hw, enum ice_fltr_ptype flow, bool add) 745 { 746 int incr; 747 748 incr = add ? 1 : -1; 749 hw->fdir_active_fltr += incr; 750 751 if (flow == ICE_FLTR_PTYPE_NONF_NONE || flow >= ICE_FLTR_PTYPE_MAX) 752 ice_debug(hw, ICE_DBG_SW, "Unknown filter type %d\n", flow); 753 else 754 hw->fdir_fltr_cnt[flow] += incr; 755 } 756 757 /** 758 * ice_cmp_ipv6_addr - compare 2 IP v6 addresses 759 * @a: IP v6 address 760 * @b: IP v6 address 761 * 762 * Returns 0 on equal, returns non-0 if different 763 */ 764 static int ice_cmp_ipv6_addr(__be32 *a, __be32 *b) 765 { 766 return memcmp(a, b, 4 * sizeof(__be32)); 767 } 768 769 /** 770 * ice_fdir_comp_rules - compare 2 filters 771 * @a: a Flow Director filter data structure 772 * @b: a Flow Director filter data structure 773 * @v6: bool true if v6 filter 774 * 775 * Returns true if the filters match 776 */ 777 static bool 778 ice_fdir_comp_rules(struct ice_fdir_fltr *a, struct ice_fdir_fltr *b, bool v6) 779 { 780 enum ice_fltr_ptype flow_type = a->flow_type; 781 782 /* The calling function already checks that the two filters have the 783 * same flow_type. 784 */ 785 if (!v6) { 786 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP || 787 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP || 788 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP) { 789 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip && 790 a->ip.v4.src_ip == b->ip.v4.src_ip && 791 a->ip.v4.dst_port == b->ip.v4.dst_port && 792 a->ip.v4.src_port == b->ip.v4.src_port) 793 return true; 794 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) { 795 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip && 796 a->ip.v4.src_ip == b->ip.v4.src_ip && 797 a->ip.v4.l4_header == b->ip.v4.l4_header && 798 a->ip.v4.proto == b->ip.v4.proto && 799 a->ip.v4.ip_ver == b->ip.v4.ip_ver && 800 a->ip.v4.tos == b->ip.v4.tos) 801 return true; 802 } 803 } else { 804 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP || 805 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_TCP || 806 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_SCTP) { 807 if (a->ip.v6.dst_port == b->ip.v6.dst_port && 808 a->ip.v6.src_port == b->ip.v6.src_port && 809 !ice_cmp_ipv6_addr(a->ip.v6.dst_ip, 810 b->ip.v6.dst_ip) && 811 !ice_cmp_ipv6_addr(a->ip.v6.src_ip, 812 b->ip.v6.src_ip)) 813 return true; 814 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) { 815 if (a->ip.v6.dst_port == b->ip.v6.dst_port && 816 a->ip.v6.src_port == b->ip.v6.src_port) 817 return true; 818 } 819 } 820 821 return false; 822 } 823 824 /** 825 * ice_fdir_is_dup_fltr - test if filter is already in list for PF 826 * @hw: hardware data structure 827 * @input: Flow Director filter data structure 828 * 829 * Returns true if the filter is found in the list 830 */ 831 bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input) 832 { 833 struct ice_fdir_fltr *rule; 834 bool ret = false; 835 836 list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) { 837 enum ice_fltr_ptype flow_type; 838 839 if (rule->flow_type != input->flow_type) 840 continue; 841 842 flow_type = input->flow_type; 843 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP || 844 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP || 845 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP || 846 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) 847 ret = ice_fdir_comp_rules(rule, input, false); 848 else 849 ret = ice_fdir_comp_rules(rule, input, true); 850 if (ret) { 851 if (rule->fltr_id == input->fltr_id && 852 rule->q_index != input->q_index) 853 ret = false; 854 else 855 break; 856 } 857 } 858 859 return ret; 860 } 861