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_eth_pkt[22]; 8 9 static const u8 ice_fdir_tcpv4_pkt[] = { 10 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 12 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 13 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 16 0x20, 0x00, 0x00, 0x00, 0x00, 0x00 17 }; 18 19 static const u8 ice_fdir_udpv4_pkt[] = { 20 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 22 0x00, 0x1C, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 23 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 0x00, 0x00, 26 }; 27 28 static const u8 ice_fdir_sctpv4_pkt[] = { 29 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 30 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 31 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x40, 0x84, 32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 35 }; 36 37 static const u8 ice_fdir_ipv4_pkt[] = { 38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 40 0x00, 0x14, 0x00, 0x00, 0x40, 0x00, 0x40, 0x10, 41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 0x00, 0x00 43 }; 44 45 static const u8 ice_fdir_udp4_gtpu4_pkt[] = { 46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 48 0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00, 51 0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00, 52 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00, 53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 54 0x00, 0x1c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 0x00, 0x00, 58 }; 59 60 static const u8 ice_fdir_tcp4_gtpu4_pkt[] = { 61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 63 0x00, 0x58, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65 0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00, 66 0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00, 67 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00, 68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 69 0x00, 0x28, 0x00, 0x00, 0x40, 0x00, 0x40, 0x06, 70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 74 }; 75 76 static const u8 ice_fdir_icmp4_gtpu4_pkt[] = { 77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 78 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 79 0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 81 0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00, 82 0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00, 83 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00, 84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 85 0x00, 0x1c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, 86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 88 0x00, 0x00, 89 }; 90 91 static const u8 ice_fdir_ipv4_gtpu4_pkt[] = { 92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 93 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 94 0x00, 0x44, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 96 0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00, 97 0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00, 98 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00, 99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 100 0x00, 0x14, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 102 0x00, 0x00, 103 }; 104 105 static const u8 ice_fdir_ipv4_l2tpv3_pkt[] = { 106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 107 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 108 0x00, 0x14, 0x00, 0x00, 0x40, 0x00, 0x40, 0x73, 109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 112 }; 113 114 static const u8 ice_fdir_ipv6_l2tpv3_pkt[] = { 115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 116 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 117 0x00, 0x00, 0x00, 0x00, 0x73, 0x40, 0x00, 0x00, 118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 123 0x00, 0x00, 124 }; 125 126 static const u8 ice_fdir_ipv4_esp_pkt[] = { 127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 128 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 129 0x00, 0x14, 0x00, 0x00, 0x40, 0x00, 0x40, 0x32, 130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 132 0x00, 0x00 133 }; 134 135 static const u8 ice_fdir_ipv6_esp_pkt[] = { 136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 137 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 138 0x00, 0x00, 0x00, 0x00, 0x32, 0x40, 0x00, 0x00, 139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 144 }; 145 146 static const u8 ice_fdir_ipv4_ah_pkt[] = { 147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 148 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 149 0x00, 0x14, 0x00, 0x00, 0x40, 0x00, 0x40, 0x33, 150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 153 0x00, 0x00 154 }; 155 156 static const u8 ice_fdir_ipv6_ah_pkt[] = { 157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 158 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 159 0x00, 0x00, 0x00, 0x00, 0x33, 0x40, 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, 0x00, 0x00, 0x00, 0x00, 165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 166 }; 167 168 static const u8 ice_fdir_ipv4_nat_t_esp_pkt[] = { 169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 170 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 171 0x00, 0x1C, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 173 0x00, 0x00, 0x00, 0x00, 0x11, 0x94, 0x00, 0x00, 174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 175 0x00, 0x00, 176 }; 177 178 static const u8 ice_fdir_ipv6_nat_t_esp_pkt[] = { 179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 180 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 181 0x00, 0x00, 0x00, 0x08, 0x11, 0x40, 0x00, 0x00, 182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 186 0x11, 0x94, 0x00, 0x00, 0x00, 0x08, 187 }; 188 189 static const u8 ice_fdir_ipv4_pfcp_node_pkt[] = { 190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 191 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 192 0x00, 0x2C, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 194 0x00, 0x00, 0x22, 0x65, 0x22, 0x65, 0x00, 0x00, 195 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0x00, 196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 197 0x00, 0x00, 198 }; 199 200 static const u8 ice_fdir_ipv4_pfcp_session_pkt[] = { 201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 202 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 203 0x00, 0x2C, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 205 0x00, 0x00, 0x22, 0x65, 0x22, 0x65, 0x00, 0x00, 206 0x00, 0x00, 0x21, 0x00, 0x00, 0x10, 0x00, 0x00, 207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 208 0x00, 0x00, 209 }; 210 211 static const u8 ice_fdir_ipv6_pfcp_node_pkt[] = { 212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 213 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 214 0x00, 0x00, 0x00, 0x18, 0x11, 0x40, 0x00, 0x00, 215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x65, 219 0x22, 0x65, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 220 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 221 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 222 }; 223 224 static const u8 ice_fdir_ipv6_pfcp_session_pkt[] = { 225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 226 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 227 0x00, 0x00, 0x00, 0x18, 0x11, 0x40, 0x00, 0x00, 228 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 229 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x65, 232 0x22, 0x65, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 233 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 234 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 235 }; 236 237 static const u8 ice_fdir_non_ip_l2_pkt[] = { 238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 240 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 241 }; 242 243 static const u8 ice_fdir_tcpv6_pkt[] = { 244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 245 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 246 0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 0x00, 0x00, 247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 252 0x00, 0x00, 0x50, 0x00, 0x20, 0x00, 0x00, 0x00, 253 0x00, 0x00, 254 }; 255 256 static const u8 ice_fdir_udpv6_pkt[] = { 257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 258 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 259 0x00, 0x00, 0x00, 0x08, 0x11, 0x40, 0x00, 0x00, 260 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 262 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 264 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 265 }; 266 267 static const u8 ice_fdir_sctpv6_pkt[] = { 268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 269 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 270 0x00, 0x00, 0x00, 0x0C, 0x84, 0x40, 0x00, 0x00, 271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 276 0x00, 0x00, 277 }; 278 279 static const u8 ice_fdir_ipv6_pkt[] = { 280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 281 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 282 0x00, 0x00, 0x00, 0x00, 0x3B, 0x40, 0x00, 0x00, 283 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 284 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 285 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 287 }; 288 289 static const u8 ice_fdir_tcp4_tun_pkt[] = { 290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 291 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 292 0x00, 0x5a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 295 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 298 0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0x00, 299 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 302 0x50, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 303 }; 304 305 static const u8 ice_fdir_udp4_tun_pkt[] = { 306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 307 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 308 0x00, 0x4e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 311 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 314 0x45, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x40, 0x00, 315 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 317 0x00, 0x00, 0x00, 0x00, 318 }; 319 320 static const u8 ice_fdir_sctp4_tun_pkt[] = { 321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 322 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 323 0x00, 0x52, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 326 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 327 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 329 0x45, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 330 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 333 }; 334 335 static const u8 ice_fdir_ip4_tun_pkt[] = { 336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 337 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 338 0x00, 0x46, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 341 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 344 0x45, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 345 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 346 0x00, 0x00, 0x00, 0x00, 347 }; 348 349 static const u8 ice_fdir_tcp6_tun_pkt[] = { 350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 351 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 352 0x00, 0x6e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 355 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 358 0x60, 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 364 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x20, 0x00, 365 0x00, 0x00, 0x00, 0x00, 366 }; 367 368 static const u8 ice_fdir_udp6_tun_pkt[] = { 369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 370 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 371 0x00, 0x62, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 374 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 377 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x11, 0x40, 378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 383 }; 384 385 static const u8 ice_fdir_sctp6_tun_pkt[] = { 386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 387 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 388 0x00, 0x66, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 391 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 394 0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x84, 0x40, 395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 400 0x00, 0x00, 0x00, 0x00, 401 }; 402 403 static const u8 ice_fdir_ip6_tun_pkt[] = { 404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 405 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 406 0x00, 0x5a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 407 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 409 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 410 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 411 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 412 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x40, 413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 414 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 415 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 417 }; 418 419 /* Flow Director no-op training packet table */ 420 static const struct ice_fdir_base_pkt ice_fdir_pkt[] = { 421 { 422 ICE_FLTR_PTYPE_NONF_ETH, 423 sizeof(ice_fdir_eth_pkt), ice_fdir_eth_pkt, 424 sizeof(ice_fdir_eth_pkt), ice_fdir_eth_pkt, 425 }, 426 { 427 ICE_FLTR_PTYPE_NONF_IPV4_TCP, 428 sizeof(ice_fdir_tcpv4_pkt), ice_fdir_tcpv4_pkt, 429 sizeof(ice_fdir_tcp4_tun_pkt), ice_fdir_tcp4_tun_pkt, 430 }, 431 { 432 ICE_FLTR_PTYPE_NONF_IPV4_UDP, 433 sizeof(ice_fdir_udpv4_pkt), ice_fdir_udpv4_pkt, 434 sizeof(ice_fdir_udp4_tun_pkt), ice_fdir_udp4_tun_pkt, 435 }, 436 { 437 ICE_FLTR_PTYPE_NONF_IPV4_SCTP, 438 sizeof(ice_fdir_sctpv4_pkt), ice_fdir_sctpv4_pkt, 439 sizeof(ice_fdir_sctp4_tun_pkt), ice_fdir_sctp4_tun_pkt, 440 }, 441 { 442 ICE_FLTR_PTYPE_NONF_IPV4_OTHER, 443 sizeof(ice_fdir_ipv4_pkt), ice_fdir_ipv4_pkt, 444 sizeof(ice_fdir_ip4_tun_pkt), ice_fdir_ip4_tun_pkt, 445 }, 446 { 447 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP, 448 sizeof(ice_fdir_udp4_gtpu4_pkt), 449 ice_fdir_udp4_gtpu4_pkt, 450 sizeof(ice_fdir_udp4_gtpu4_pkt), 451 ice_fdir_udp4_gtpu4_pkt, 452 }, 453 { 454 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP, 455 sizeof(ice_fdir_tcp4_gtpu4_pkt), 456 ice_fdir_tcp4_gtpu4_pkt, 457 sizeof(ice_fdir_tcp4_gtpu4_pkt), 458 ice_fdir_tcp4_gtpu4_pkt, 459 }, 460 { 461 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP, 462 sizeof(ice_fdir_icmp4_gtpu4_pkt), 463 ice_fdir_icmp4_gtpu4_pkt, 464 sizeof(ice_fdir_icmp4_gtpu4_pkt), 465 ice_fdir_icmp4_gtpu4_pkt, 466 }, 467 { 468 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER, 469 sizeof(ice_fdir_ipv4_gtpu4_pkt), 470 ice_fdir_ipv4_gtpu4_pkt, 471 sizeof(ice_fdir_ipv4_gtpu4_pkt), 472 ice_fdir_ipv4_gtpu4_pkt, 473 }, 474 { 475 ICE_FLTR_PTYPE_NONF_IPV4_L2TPV3, 476 sizeof(ice_fdir_ipv4_l2tpv3_pkt), ice_fdir_ipv4_l2tpv3_pkt, 477 sizeof(ice_fdir_ipv4_l2tpv3_pkt), ice_fdir_ipv4_l2tpv3_pkt, 478 }, 479 { 480 ICE_FLTR_PTYPE_NONF_IPV6_L2TPV3, 481 sizeof(ice_fdir_ipv6_l2tpv3_pkt), ice_fdir_ipv6_l2tpv3_pkt, 482 sizeof(ice_fdir_ipv6_l2tpv3_pkt), ice_fdir_ipv6_l2tpv3_pkt, 483 }, 484 { 485 ICE_FLTR_PTYPE_NONF_IPV4_ESP, 486 sizeof(ice_fdir_ipv4_esp_pkt), ice_fdir_ipv4_esp_pkt, 487 sizeof(ice_fdir_ipv4_esp_pkt), ice_fdir_ipv4_esp_pkt, 488 }, 489 { 490 ICE_FLTR_PTYPE_NONF_IPV6_ESP, 491 sizeof(ice_fdir_ipv6_esp_pkt), ice_fdir_ipv6_esp_pkt, 492 sizeof(ice_fdir_ipv6_esp_pkt), ice_fdir_ipv6_esp_pkt, 493 }, 494 { 495 ICE_FLTR_PTYPE_NONF_IPV4_AH, 496 sizeof(ice_fdir_ipv4_ah_pkt), ice_fdir_ipv4_ah_pkt, 497 sizeof(ice_fdir_ipv4_ah_pkt), ice_fdir_ipv4_ah_pkt, 498 }, 499 { 500 ICE_FLTR_PTYPE_NONF_IPV6_AH, 501 sizeof(ice_fdir_ipv6_ah_pkt), ice_fdir_ipv6_ah_pkt, 502 sizeof(ice_fdir_ipv6_ah_pkt), ice_fdir_ipv6_ah_pkt, 503 }, 504 { 505 ICE_FLTR_PTYPE_NONF_IPV4_NAT_T_ESP, 506 sizeof(ice_fdir_ipv4_nat_t_esp_pkt), 507 ice_fdir_ipv4_nat_t_esp_pkt, 508 sizeof(ice_fdir_ipv4_nat_t_esp_pkt), 509 ice_fdir_ipv4_nat_t_esp_pkt, 510 }, 511 { 512 ICE_FLTR_PTYPE_NONF_IPV6_NAT_T_ESP, 513 sizeof(ice_fdir_ipv6_nat_t_esp_pkt), 514 ice_fdir_ipv6_nat_t_esp_pkt, 515 sizeof(ice_fdir_ipv6_nat_t_esp_pkt), 516 ice_fdir_ipv6_nat_t_esp_pkt, 517 }, 518 { 519 ICE_FLTR_PTYPE_NONF_IPV4_PFCP_NODE, 520 sizeof(ice_fdir_ipv4_pfcp_node_pkt), 521 ice_fdir_ipv4_pfcp_node_pkt, 522 sizeof(ice_fdir_ipv4_pfcp_node_pkt), 523 ice_fdir_ipv4_pfcp_node_pkt, 524 }, 525 { 526 ICE_FLTR_PTYPE_NONF_IPV4_PFCP_SESSION, 527 sizeof(ice_fdir_ipv4_pfcp_session_pkt), 528 ice_fdir_ipv4_pfcp_session_pkt, 529 sizeof(ice_fdir_ipv4_pfcp_session_pkt), 530 ice_fdir_ipv4_pfcp_session_pkt, 531 }, 532 { 533 ICE_FLTR_PTYPE_NONF_IPV6_PFCP_NODE, 534 sizeof(ice_fdir_ipv6_pfcp_node_pkt), 535 ice_fdir_ipv6_pfcp_node_pkt, 536 sizeof(ice_fdir_ipv6_pfcp_node_pkt), 537 ice_fdir_ipv6_pfcp_node_pkt, 538 }, 539 { 540 ICE_FLTR_PTYPE_NONF_IPV6_PFCP_SESSION, 541 sizeof(ice_fdir_ipv6_pfcp_session_pkt), 542 ice_fdir_ipv6_pfcp_session_pkt, 543 sizeof(ice_fdir_ipv6_pfcp_session_pkt), 544 ice_fdir_ipv6_pfcp_session_pkt, 545 }, 546 { 547 ICE_FLTR_PTYPE_NON_IP_L2, 548 sizeof(ice_fdir_non_ip_l2_pkt), ice_fdir_non_ip_l2_pkt, 549 sizeof(ice_fdir_non_ip_l2_pkt), ice_fdir_non_ip_l2_pkt, 550 }, 551 { 552 ICE_FLTR_PTYPE_NONF_IPV6_TCP, 553 sizeof(ice_fdir_tcpv6_pkt), ice_fdir_tcpv6_pkt, 554 sizeof(ice_fdir_tcp6_tun_pkt), ice_fdir_tcp6_tun_pkt, 555 }, 556 { 557 ICE_FLTR_PTYPE_NONF_IPV6_UDP, 558 sizeof(ice_fdir_udpv6_pkt), ice_fdir_udpv6_pkt, 559 sizeof(ice_fdir_udp6_tun_pkt), ice_fdir_udp6_tun_pkt, 560 }, 561 { 562 ICE_FLTR_PTYPE_NONF_IPV6_SCTP, 563 sizeof(ice_fdir_sctpv6_pkt), ice_fdir_sctpv6_pkt, 564 sizeof(ice_fdir_sctp6_tun_pkt), ice_fdir_sctp6_tun_pkt, 565 }, 566 { 567 ICE_FLTR_PTYPE_NONF_IPV6_OTHER, 568 sizeof(ice_fdir_ipv6_pkt), ice_fdir_ipv6_pkt, 569 sizeof(ice_fdir_ip6_tun_pkt), ice_fdir_ip6_tun_pkt, 570 }, 571 }; 572 573 #define ICE_FDIR_NUM_PKT ARRAY_SIZE(ice_fdir_pkt) 574 575 /** 576 * ice_set_dflt_val_fd_desc 577 * @fd_fltr_ctx: pointer to fd filter descriptor 578 */ 579 static void ice_set_dflt_val_fd_desc(struct ice_fd_fltr_desc_ctx *fd_fltr_ctx) 580 { 581 fd_fltr_ctx->comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO; 582 fd_fltr_ctx->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL; 583 fd_fltr_ctx->fd_space = ICE_FXD_FLTR_QW0_FD_SPACE_GUAR_BEST; 584 fd_fltr_ctx->cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS; 585 fd_fltr_ctx->evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_TRUE; 586 fd_fltr_ctx->toq = ICE_FXD_FLTR_QW0_TO_Q_EQUALS_QINDEX; 587 fd_fltr_ctx->toq_prio = ICE_FXD_FLTR_QW0_TO_Q_PRIO1; 588 fd_fltr_ctx->dpu_recipe = ICE_FXD_FLTR_QW0_DPU_RECIPE_DFLT; 589 fd_fltr_ctx->drop = ICE_FXD_FLTR_QW0_DROP_NO; 590 fd_fltr_ctx->flex_prio = ICE_FXD_FLTR_QW0_FLEX_PRI_NONE; 591 fd_fltr_ctx->flex_mdid = ICE_FXD_FLTR_QW0_FLEX_MDID0; 592 fd_fltr_ctx->flex_val = ICE_FXD_FLTR_QW0_FLEX_VAL0; 593 fd_fltr_ctx->dtype = ICE_TX_DESC_DTYPE_FLTR_PROG; 594 fd_fltr_ctx->desc_prof_prio = ICE_FXD_FLTR_QW1_PROF_PRIO_ZERO; 595 fd_fltr_ctx->desc_prof = ICE_FXD_FLTR_QW1_PROF_ZERO; 596 fd_fltr_ctx->swap = ICE_FXD_FLTR_QW1_SWAP_SET; 597 fd_fltr_ctx->fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_ONE; 598 fd_fltr_ctx->fdid_mdid = ICE_FXD_FLTR_QW1_FDID_MDID_FD; 599 fd_fltr_ctx->fdid = ICE_FXD_FLTR_QW1_FDID_ZERO; 600 } 601 602 /** 603 * ice_set_fd_desc_val 604 * @ctx: pointer to fd filter descriptor context 605 * @fdir_desc: populated with fd filter descriptor values 606 */ 607 static void 608 ice_set_fd_desc_val(struct ice_fd_fltr_desc_ctx *ctx, 609 struct ice_fltr_desc *fdir_desc) 610 { 611 u64 qword; 612 613 /* prep QW0 of FD filter programming desc */ 614 qword = FIELD_PREP(ICE_FXD_FLTR_QW0_QINDEX_M, ctx->qindex); 615 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_COMP_Q_M, ctx->comp_q); 616 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_COMP_REPORT_M, ctx->comp_report); 617 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_FD_SPACE_M, ctx->fd_space); 618 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_STAT_CNT_M, ctx->cnt_index); 619 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_STAT_ENA_M, ctx->cnt_ena); 620 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_EVICT_ENA_M, ctx->evict_ena); 621 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_TO_Q_M, ctx->toq); 622 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_TO_Q_PRI_M, ctx->toq_prio); 623 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_DPU_RECIPE_M, ctx->dpu_recipe); 624 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_DROP_M, ctx->drop); 625 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_FLEX_PRI_M, ctx->flex_prio); 626 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_FLEX_MDID_M, ctx->flex_mdid); 627 qword |= FIELD_PREP(ICE_FXD_FLTR_QW0_FLEX_VAL_M, ctx->flex_val); 628 fdir_desc->qidx_compq_space_stat = cpu_to_le64(qword); 629 630 /* prep QW1 of FD filter programming desc */ 631 qword = FIELD_PREP(ICE_FXD_FLTR_QW1_DTYPE_M, ctx->dtype); 632 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_PCMD_M, ctx->pcmd); 633 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_PROF_PRI_M, ctx->desc_prof_prio); 634 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_PROF_M, ctx->desc_prof); 635 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_FD_VSI_M, ctx->fd_vsi); 636 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_SWAP_M, ctx->swap); 637 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_FDID_PRI_M, ctx->fdid_prio); 638 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_FDID_MDID_M, ctx->fdid_mdid); 639 qword |= FIELD_PREP(ICE_FXD_FLTR_QW1_FDID_M, ctx->fdid); 640 fdir_desc->dtype_cmd_vsi_fdid = cpu_to_le64(qword); 641 } 642 643 /** 644 * ice_fdir_get_prgm_desc - set a fdir descriptor from a fdir filter struct 645 * @hw: pointer to the hardware structure 646 * @input: filter 647 * @fdesc: filter descriptor 648 * @add: if add is true, this is an add operation, false implies delete 649 */ 650 void 651 ice_fdir_get_prgm_desc(struct ice_hw *hw, struct ice_fdir_fltr *input, 652 struct ice_fltr_desc *fdesc, bool add) 653 { 654 struct ice_fd_fltr_desc_ctx fdir_fltr_ctx = { 0 }; 655 656 /* set default context info */ 657 ice_set_dflt_val_fd_desc(&fdir_fltr_ctx); 658 659 /* change sideband filtering values */ 660 fdir_fltr_ctx.fdid = input->fltr_id; 661 if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DROP_PKT) { 662 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_YES; 663 fdir_fltr_ctx.qindex = 0; 664 } else if (input->dest_ctl == 665 ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER) { 666 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO; 667 fdir_fltr_ctx.qindex = 0; 668 } else { 669 if (input->dest_ctl == 670 ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QGROUP) 671 fdir_fltr_ctx.toq = input->q_region; 672 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO; 673 fdir_fltr_ctx.qindex = input->q_index; 674 } 675 fdir_fltr_ctx.cnt_ena = input->cnt_ena; 676 fdir_fltr_ctx.cnt_index = input->cnt_index; 677 fdir_fltr_ctx.fd_vsi = ice_get_hw_vsi_num(hw, input->dest_vsi); 678 fdir_fltr_ctx.evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_FALSE; 679 if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER) 680 fdir_fltr_ctx.toq_prio = 0; 681 else 682 fdir_fltr_ctx.toq_prio = 3; 683 fdir_fltr_ctx.pcmd = add ? ICE_FXD_FLTR_QW1_PCMD_ADD : 684 ICE_FXD_FLTR_QW1_PCMD_REMOVE; 685 fdir_fltr_ctx.swap = ICE_FXD_FLTR_QW1_SWAP_NOT_SET; 686 fdir_fltr_ctx.comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO; 687 fdir_fltr_ctx.comp_report = input->comp_report; 688 fdir_fltr_ctx.fdid_prio = input->fdid_prio; 689 fdir_fltr_ctx.desc_prof = 1; 690 fdir_fltr_ctx.desc_prof_prio = 3; 691 ice_set_fd_desc_val(&fdir_fltr_ctx, fdesc); 692 } 693 694 /** 695 * ice_alloc_fd_res_cntr - obtain counter resource for FD type 696 * @hw: pointer to the hardware structure 697 * @cntr_id: returns counter index 698 */ 699 int ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id) 700 { 701 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK, 702 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id); 703 } 704 705 /** 706 * ice_free_fd_res_cntr - Free counter resource for FD type 707 * @hw: pointer to the hardware structure 708 * @cntr_id: counter index to be freed 709 */ 710 int ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id) 711 { 712 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK, 713 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id); 714 } 715 716 /** 717 * ice_alloc_fd_guar_item - allocate resource for FD guaranteed entries 718 * @hw: pointer to the hardware structure 719 * @cntr_id: returns counter index 720 * @num_fltr: number of filter entries to be allocated 721 */ 722 int ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr) 723 { 724 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES, 725 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr, 726 cntr_id); 727 } 728 729 /** 730 * ice_alloc_fd_shrd_item - allocate resource for flow director shared entries 731 * @hw: pointer to the hardware structure 732 * @cntr_id: returns counter index 733 * @num_fltr: number of filter entries to be allocated 734 */ 735 int ice_alloc_fd_shrd_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr) 736 { 737 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES, 738 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr, 739 cntr_id); 740 } 741 742 /** 743 * ice_get_fdir_cnt_all - get the number of Flow Director filters 744 * @hw: hardware data structure 745 * 746 * Returns the number of filters available on device 747 */ 748 int ice_get_fdir_cnt_all(struct ice_hw *hw) 749 { 750 return hw->func_caps.fd_fltr_guar + hw->func_caps.fd_fltr_best_effort; 751 } 752 753 /** 754 * ice_pkt_insert_ipv6_addr - insert a be32 IPv6 address into a memory buffer 755 * @pkt: packet buffer 756 * @offset: offset into buffer 757 * @addr: IPv6 address to convert and insert into pkt at offset 758 */ 759 static void ice_pkt_insert_ipv6_addr(u8 *pkt, int offset, __be32 *addr) 760 { 761 int idx; 762 763 for (idx = 0; idx < ICE_IPV6_ADDR_LEN_AS_U32; idx++) 764 memcpy(pkt + offset + idx * sizeof(*addr), &addr[idx], 765 sizeof(*addr)); 766 } 767 768 /** 769 * ice_pkt_insert_u6_qfi - insert a u6 value QFI into a memory buffer for GTPU 770 * @pkt: packet buffer 771 * @offset: offset into buffer 772 * @data: 8 bit value to convert and insert into pkt at offset 773 * 774 * This function is designed for inserting QFI (6 bits) for GTPU. 775 */ 776 static void ice_pkt_insert_u6_qfi(u8 *pkt, int offset, u8 data) 777 { 778 u8 ret; 779 780 ret = (data & 0x3F) + (*(pkt + offset) & 0xC0); 781 memcpy(pkt + offset, &ret, sizeof(ret)); 782 } 783 784 /** 785 * ice_pkt_insert_u8 - insert a u8 value into a memory buffer. 786 * @pkt: packet buffer 787 * @offset: offset into buffer 788 * @data: 8 bit value to convert and insert into pkt at offset 789 */ 790 static void ice_pkt_insert_u8(u8 *pkt, int offset, u8 data) 791 { 792 memcpy(pkt + offset, &data, sizeof(data)); 793 } 794 795 /** 796 * ice_pkt_insert_u8_tc - insert a u8 value into a memory buffer for TC ipv6. 797 * @pkt: packet buffer 798 * @offset: offset into buffer 799 * @data: 8 bit value to convert and insert into pkt at offset 800 * 801 * This function is designed for inserting Traffic Class (TC) for IPv6, 802 * since that TC is not aligned in number of bytes. Here we split it out 803 * into two part and fill each byte with data copy from pkt, then insert 804 * the two bytes data one by one. 805 */ 806 static void ice_pkt_insert_u8_tc(u8 *pkt, int offset, u8 data) 807 { 808 u8 high, low; 809 810 high = (data >> 4) + (*(pkt + offset) & 0xF0); 811 memcpy(pkt + offset, &high, sizeof(high)); 812 813 low = (*(pkt + offset + 1) & 0x0F) + ((data & 0x0F) << 4); 814 memcpy(pkt + offset + 1, &low, sizeof(low)); 815 } 816 817 /** 818 * ice_pkt_insert_u16 - insert a be16 value into a memory buffer 819 * @pkt: packet buffer 820 * @offset: offset into buffer 821 * @data: 16 bit value to convert and insert into pkt at offset 822 */ 823 static void ice_pkt_insert_u16(u8 *pkt, int offset, __be16 data) 824 { 825 memcpy(pkt + offset, &data, sizeof(data)); 826 } 827 828 /** 829 * ice_pkt_insert_u32 - insert a be32 value into a memory buffer 830 * @pkt: packet buffer 831 * @offset: offset into buffer 832 * @data: 32 bit value to convert and insert into pkt at offset 833 */ 834 static void ice_pkt_insert_u32(u8 *pkt, int offset, __be32 data) 835 { 836 memcpy(pkt + offset, &data, sizeof(data)); 837 } 838 839 /** 840 * ice_pkt_insert_mac_addr - insert a MAC addr into a memory buffer. 841 * @pkt: packet buffer 842 * @addr: MAC address to convert and insert into pkt at offset 843 */ 844 static void ice_pkt_insert_mac_addr(u8 *pkt, u8 *addr) 845 { 846 ether_addr_copy(pkt, addr); 847 } 848 849 /** 850 * ice_fdir_get_gen_prgm_pkt - generate a training packet 851 * @hw: pointer to the hardware structure 852 * @input: flow director filter data structure 853 * @pkt: pointer to return filter packet 854 * @frag: generate a fragment packet 855 * @tun: true implies generate a tunnel packet 856 */ 857 int 858 ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input, 859 u8 *pkt, bool frag, bool tun) 860 { 861 enum ice_fltr_ptype flow; 862 u16 tnl_port; 863 u8 *loc; 864 u16 idx; 865 866 if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) { 867 switch (input->ip.v4.proto) { 868 case IPPROTO_TCP: 869 flow = ICE_FLTR_PTYPE_NONF_IPV4_TCP; 870 break; 871 case IPPROTO_UDP: 872 flow = ICE_FLTR_PTYPE_NONF_IPV4_UDP; 873 break; 874 case IPPROTO_SCTP: 875 flow = ICE_FLTR_PTYPE_NONF_IPV4_SCTP; 876 break; 877 default: 878 flow = ICE_FLTR_PTYPE_NONF_IPV4_OTHER; 879 break; 880 } 881 } else if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) { 882 switch (input->ip.v6.proto) { 883 case IPPROTO_TCP: 884 flow = ICE_FLTR_PTYPE_NONF_IPV6_TCP; 885 break; 886 case IPPROTO_UDP: 887 flow = ICE_FLTR_PTYPE_NONF_IPV6_UDP; 888 break; 889 case IPPROTO_SCTP: 890 flow = ICE_FLTR_PTYPE_NONF_IPV6_SCTP; 891 break; 892 default: 893 flow = ICE_FLTR_PTYPE_NONF_IPV6_OTHER; 894 break; 895 } 896 } else { 897 flow = input->flow_type; 898 } 899 900 for (idx = 0; idx < ICE_FDIR_NUM_PKT; idx++) 901 if (ice_fdir_pkt[idx].flow == flow) 902 break; 903 if (idx == ICE_FDIR_NUM_PKT) 904 return -EINVAL; 905 if (!tun) { 906 memcpy(pkt, ice_fdir_pkt[idx].pkt, ice_fdir_pkt[idx].pkt_len); 907 loc = pkt; 908 } else { 909 if (!ice_get_open_tunnel_port(hw, &tnl_port, TNL_ALL)) 910 return -ENOENT; 911 if (!ice_fdir_pkt[idx].tun_pkt) 912 return -EINVAL; 913 memcpy(pkt, ice_fdir_pkt[idx].tun_pkt, 914 ice_fdir_pkt[idx].tun_pkt_len); 915 ice_pkt_insert_u16(pkt, ICE_IPV4_UDP_DST_PORT_OFFSET, 916 htons(tnl_port)); 917 loc = &pkt[ICE_FDIR_TUN_PKT_OFF]; 918 } 919 920 /* Reverse the src and dst, since the HW expects them to be from Tx 921 * perspective. The input from user is from Rx filter perspective. 922 */ 923 switch (flow) { 924 case ICE_FLTR_PTYPE_NONF_ETH: 925 ice_pkt_insert_mac_addr(loc, input->eth.h_dest); 926 ice_pkt_insert_mac_addr(loc + ETH_ALEN, input->eth.h_source); 927 if (input->ext_data.vlan_tag || input->ext_data.vlan_type) { 928 ice_pkt_insert_u16(loc, ICE_ETH_TYPE_F_OFFSET, 929 input->ext_data.vlan_type); 930 ice_pkt_insert_u16(loc, ICE_ETH_VLAN_TCI_OFFSET, 931 input->ext_data.vlan_tag); 932 ice_pkt_insert_u16(loc, ICE_ETH_TYPE_VLAN_OFFSET, 933 input->eth.h_proto); 934 } else { 935 ice_pkt_insert_u16(loc, ICE_ETH_TYPE_F_OFFSET, 936 input->eth.h_proto); 937 } 938 break; 939 case ICE_FLTR_PTYPE_NONF_IPV4_TCP: 940 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 941 input->ip.v4.src_ip); 942 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_DST_PORT_OFFSET, 943 input->ip.v4.src_port); 944 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 945 input->ip.v4.dst_ip); 946 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET, 947 input->ip.v4.dst_port); 948 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos); 949 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl); 950 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 951 if (frag) 952 loc[20] = ICE_FDIR_IPV4_PKT_FLAG_MF; 953 break; 954 case ICE_FLTR_PTYPE_NONF_IPV4_UDP: 955 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 956 input->ip.v4.src_ip); 957 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_DST_PORT_OFFSET, 958 input->ip.v4.src_port); 959 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 960 input->ip.v4.dst_ip); 961 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET, 962 input->ip.v4.dst_port); 963 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos); 964 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl); 965 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 966 ice_pkt_insert_mac_addr(loc + ETH_ALEN, 967 input->ext_data.src_mac); 968 break; 969 case ICE_FLTR_PTYPE_NONF_IPV4_SCTP: 970 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 971 input->ip.v4.src_ip); 972 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_DST_PORT_OFFSET, 973 input->ip.v4.src_port); 974 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 975 input->ip.v4.dst_ip); 976 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_SRC_PORT_OFFSET, 977 input->ip.v4.dst_port); 978 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos); 979 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl); 980 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 981 break; 982 case ICE_FLTR_PTYPE_NONF_IPV4_OTHER: 983 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 984 input->ip.v4.src_ip); 985 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 986 input->ip.v4.dst_ip); 987 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos); 988 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl); 989 ice_pkt_insert_u8(loc, ICE_IPV4_PROTO_OFFSET, 990 input->ip.v4.proto); 991 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 992 break; 993 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP: 994 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP: 995 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP: 996 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER: 997 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 998 input->ip.v4.src_ip); 999 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 1000 input->ip.v4.dst_ip); 1001 ice_pkt_insert_u32(loc, ICE_IPV4_GTPU_TEID_OFFSET, 1002 input->gtpu_data.teid); 1003 ice_pkt_insert_u6_qfi(loc, ICE_IPV4_GTPU_QFI_OFFSET, 1004 input->gtpu_data.qfi); 1005 break; 1006 case ICE_FLTR_PTYPE_NONF_IPV4_L2TPV3: 1007 ice_pkt_insert_u32(loc, ICE_IPV4_L2TPV3_SESS_ID_OFFSET, 1008 input->l2tpv3_data.session_id); 1009 break; 1010 case ICE_FLTR_PTYPE_NONF_IPV6_L2TPV3: 1011 ice_pkt_insert_u32(loc, ICE_IPV6_L2TPV3_SESS_ID_OFFSET, 1012 input->l2tpv3_data.session_id); 1013 break; 1014 case ICE_FLTR_PTYPE_NONF_IPV4_ESP: 1015 ice_pkt_insert_u32(loc, ICE_IPV4_ESP_SPI_OFFSET, 1016 input->ip.v4.sec_parm_idx); 1017 break; 1018 case ICE_FLTR_PTYPE_NONF_IPV6_ESP: 1019 ice_pkt_insert_u32(loc, ICE_IPV6_ESP_SPI_OFFSET, 1020 input->ip.v6.sec_parm_idx); 1021 break; 1022 case ICE_FLTR_PTYPE_NONF_IPV4_AH: 1023 ice_pkt_insert_u32(loc, ICE_IPV4_AH_SPI_OFFSET, 1024 input->ip.v4.sec_parm_idx); 1025 break; 1026 case ICE_FLTR_PTYPE_NONF_IPV6_AH: 1027 ice_pkt_insert_u32(loc, ICE_IPV6_AH_SPI_OFFSET, 1028 input->ip.v6.sec_parm_idx); 1029 break; 1030 case ICE_FLTR_PTYPE_NONF_IPV4_NAT_T_ESP: 1031 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 1032 input->ip.v4.src_ip); 1033 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 1034 input->ip.v4.dst_ip); 1035 ice_pkt_insert_u32(loc, ICE_IPV4_NAT_T_ESP_SPI_OFFSET, 1036 input->ip.v4.sec_parm_idx); 1037 break; 1038 case ICE_FLTR_PTYPE_NONF_IPV6_NAT_T_ESP: 1039 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 1040 input->ip.v6.src_ip); 1041 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 1042 input->ip.v6.dst_ip); 1043 ice_pkt_insert_u32(loc, ICE_IPV6_NAT_T_ESP_SPI_OFFSET, 1044 input->ip.v6.sec_parm_idx); 1045 break; 1046 case ICE_FLTR_PTYPE_NONF_IPV4_PFCP_NODE: 1047 case ICE_FLTR_PTYPE_NONF_IPV4_PFCP_SESSION: 1048 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET, 1049 input->ip.v4.dst_port); 1050 break; 1051 case ICE_FLTR_PTYPE_NONF_IPV6_PFCP_NODE: 1052 case ICE_FLTR_PTYPE_NONF_IPV6_PFCP_SESSION: 1053 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET, 1054 input->ip.v6.dst_port); 1055 break; 1056 case ICE_FLTR_PTYPE_NON_IP_L2: 1057 ice_pkt_insert_u16(loc, ICE_MAC_ETHTYPE_OFFSET, 1058 input->ext_data.ether_type); 1059 break; 1060 case ICE_FLTR_PTYPE_NONF_IPV6_TCP: 1061 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 1062 input->ip.v6.src_ip); 1063 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 1064 input->ip.v6.dst_ip); 1065 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_DST_PORT_OFFSET, 1066 input->ip.v6.src_port); 1067 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET, 1068 input->ip.v6.dst_port); 1069 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc); 1070 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim); 1071 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 1072 break; 1073 case ICE_FLTR_PTYPE_NONF_IPV6_UDP: 1074 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 1075 input->ip.v6.src_ip); 1076 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 1077 input->ip.v6.dst_ip); 1078 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_DST_PORT_OFFSET, 1079 input->ip.v6.src_port); 1080 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET, 1081 input->ip.v6.dst_port); 1082 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc); 1083 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim); 1084 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 1085 break; 1086 case ICE_FLTR_PTYPE_NONF_IPV6_SCTP: 1087 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 1088 input->ip.v6.src_ip); 1089 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 1090 input->ip.v6.dst_ip); 1091 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_DST_PORT_OFFSET, 1092 input->ip.v6.src_port); 1093 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET, 1094 input->ip.v6.dst_port); 1095 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc); 1096 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim); 1097 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 1098 break; 1099 case ICE_FLTR_PTYPE_NONF_IPV6_OTHER: 1100 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 1101 input->ip.v6.src_ip); 1102 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 1103 input->ip.v6.dst_ip); 1104 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc); 1105 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim); 1106 ice_pkt_insert_u8(loc, ICE_IPV6_PROTO_OFFSET, 1107 input->ip.v6.proto); 1108 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 1109 break; 1110 default: 1111 return -EINVAL; 1112 } 1113 1114 if (input->flex_fltr) 1115 ice_pkt_insert_u16(loc, input->flex_offset, input->flex_word); 1116 1117 return 0; 1118 } 1119 1120 /** 1121 * ice_fdir_has_frag - does flow type have 2 ptypes 1122 * @flow: flow ptype 1123 * 1124 * returns true is there is a fragment packet for this ptype 1125 */ 1126 bool ice_fdir_has_frag(enum ice_fltr_ptype flow) 1127 { 1128 if (flow == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) 1129 return true; 1130 else 1131 return false; 1132 } 1133 1134 /** 1135 * ice_fdir_find_fltr_by_idx - find filter with idx 1136 * @hw: pointer to hardware structure 1137 * @fltr_idx: index to find. 1138 * 1139 * Returns pointer to filter if found or null 1140 */ 1141 struct ice_fdir_fltr * 1142 ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx) 1143 { 1144 struct ice_fdir_fltr *rule; 1145 1146 list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) { 1147 /* rule ID found in the list */ 1148 if (fltr_idx == rule->fltr_id) 1149 return rule; 1150 if (fltr_idx < rule->fltr_id) 1151 break; 1152 } 1153 return NULL; 1154 } 1155 1156 /** 1157 * ice_fdir_list_add_fltr - add a new node to the flow director filter list 1158 * @hw: hardware structure 1159 * @fltr: filter node to add to structure 1160 */ 1161 void ice_fdir_list_add_fltr(struct ice_hw *hw, struct ice_fdir_fltr *fltr) 1162 { 1163 struct ice_fdir_fltr *rule, *parent = NULL; 1164 1165 list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) { 1166 /* rule ID found or pass its spot in the list */ 1167 if (rule->fltr_id >= fltr->fltr_id) 1168 break; 1169 parent = rule; 1170 } 1171 1172 if (parent) 1173 list_add(&fltr->fltr_node, &parent->fltr_node); 1174 else 1175 list_add(&fltr->fltr_node, &hw->fdir_list_head); 1176 } 1177 1178 /** 1179 * ice_fdir_update_cntrs - increment / decrement filter counter 1180 * @hw: pointer to hardware structure 1181 * @flow: filter flow type 1182 * @add: true implies filters added 1183 */ 1184 void 1185 ice_fdir_update_cntrs(struct ice_hw *hw, enum ice_fltr_ptype flow, bool add) 1186 { 1187 int incr; 1188 1189 incr = add ? 1 : -1; 1190 hw->fdir_active_fltr += incr; 1191 1192 if (flow == ICE_FLTR_PTYPE_NONF_NONE || flow >= ICE_FLTR_PTYPE_MAX) 1193 ice_debug(hw, ICE_DBG_SW, "Unknown filter type %d\n", flow); 1194 else 1195 hw->fdir_fltr_cnt[flow] += incr; 1196 } 1197 1198 /** 1199 * ice_cmp_ipv6_addr - compare 2 IP v6 addresses 1200 * @a: IP v6 address 1201 * @b: IP v6 address 1202 * 1203 * Returns 0 on equal, returns non-0 if different 1204 */ 1205 static int ice_cmp_ipv6_addr(__be32 *a, __be32 *b) 1206 { 1207 return memcmp(a, b, 4 * sizeof(__be32)); 1208 } 1209 1210 /** 1211 * ice_fdir_comp_rules - compare 2 filters 1212 * @a: a Flow Director filter data structure 1213 * @b: a Flow Director filter data structure 1214 * 1215 * Returns true if the filters match 1216 */ 1217 static bool 1218 ice_fdir_comp_rules(struct ice_fdir_fltr *a, struct ice_fdir_fltr *b) 1219 { 1220 enum ice_fltr_ptype flow_type = a->flow_type; 1221 1222 /* The calling function already checks that the two filters have the 1223 * same flow_type. 1224 */ 1225 switch (flow_type) { 1226 case ICE_FLTR_PTYPE_NONF_ETH: 1227 if (!memcmp(&a->eth, &b->eth, sizeof(a->eth))) 1228 return true; 1229 break; 1230 case ICE_FLTR_PTYPE_NONF_IPV4_TCP: 1231 case ICE_FLTR_PTYPE_NONF_IPV4_UDP: 1232 case ICE_FLTR_PTYPE_NONF_IPV4_SCTP: 1233 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip && 1234 a->ip.v4.src_ip == b->ip.v4.src_ip && 1235 a->ip.v4.dst_port == b->ip.v4.dst_port && 1236 a->ip.v4.src_port == b->ip.v4.src_port) 1237 return true; 1238 break; 1239 case ICE_FLTR_PTYPE_NONF_IPV4_OTHER: 1240 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip && 1241 a->ip.v4.src_ip == b->ip.v4.src_ip && 1242 a->ip.v4.l4_header == b->ip.v4.l4_header && 1243 a->ip.v4.proto == b->ip.v4.proto && 1244 a->ip.v4.ip_ver == b->ip.v4.ip_ver && 1245 a->ip.v4.tos == b->ip.v4.tos) 1246 return true; 1247 break; 1248 case ICE_FLTR_PTYPE_NONF_IPV6_UDP: 1249 case ICE_FLTR_PTYPE_NONF_IPV6_TCP: 1250 case ICE_FLTR_PTYPE_NONF_IPV6_SCTP: 1251 if (a->ip.v6.dst_port == b->ip.v6.dst_port && 1252 a->ip.v6.src_port == b->ip.v6.src_port && 1253 !ice_cmp_ipv6_addr(a->ip.v6.dst_ip, 1254 b->ip.v6.dst_ip) && 1255 !ice_cmp_ipv6_addr(a->ip.v6.src_ip, 1256 b->ip.v6.src_ip)) 1257 return true; 1258 break; 1259 case ICE_FLTR_PTYPE_NONF_IPV6_OTHER: 1260 if (a->ip.v6.dst_port == b->ip.v6.dst_port && 1261 a->ip.v6.src_port == b->ip.v6.src_port) 1262 return true; 1263 break; 1264 default: 1265 break; 1266 } 1267 1268 return false; 1269 } 1270 1271 /** 1272 * ice_fdir_is_dup_fltr - test if filter is already in list for PF 1273 * @hw: hardware data structure 1274 * @input: Flow Director filter data structure 1275 * 1276 * Returns true if the filter is found in the list 1277 */ 1278 bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input) 1279 { 1280 struct ice_fdir_fltr *rule; 1281 bool ret = false; 1282 1283 list_for_each_entry(rule, &hw->fdir_list_head, fltr_node) { 1284 if (rule->flow_type != input->flow_type) 1285 continue; 1286 1287 ret = ice_fdir_comp_rules(rule, input); 1288 if (ret) { 1289 if (rule->fltr_id == input->fltr_id && 1290 rule->q_index != input->q_index) 1291 ret = false; 1292 else 1293 break; 1294 } 1295 } 1296 1297 return ret; 1298 } 1299