1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2001-2019 3 */ 4 5 #include "ice_common.h" 6 #include "ice_fdir.h" 7 8 /* These are training packet headers used to program flow director filters. */ 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_tcpv6_pkt[] = { 106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 107 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 108 0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 0x00, 0x00, 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, 0x00, 0x00, 112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 114 0x00, 0x00, 0x50, 0x00, 0x20, 0x00, 0x00, 0x00, 115 0x00, 0x00, 116 }; 117 118 static const u8 ice_fdir_udpv6_pkt[] = { 119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 120 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 121 0x00, 0x00, 0x00, 0x08, 0x11, 0x40, 0x00, 0x00, 122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 126 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 127 }; 128 129 static const u8 ice_fdir_sctpv6_pkt[] = { 130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 131 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 132 0x00, 0x00, 0x00, 0x0C, 0x84, 0x40, 0x00, 0x00, 133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 138 0x00, 0x00, 139 }; 140 141 static const u8 ice_fdir_ipv6_pkt[] = { 142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 143 0x00, 0x00, 0x00, 0x00, 0x86, 0xDD, 0x60, 0x00, 144 0x00, 0x00, 0x00, 0x00, 0x3B, 0x40, 0x00, 0x00, 145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 149 }; 150 151 static const u8 ice_fdir_tcp4_tun_pkt[] = { 152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 153 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 154 0x00, 0x5a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 157 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 160 0x45, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0x00, 161 0x40, 0x06, 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 0x50, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 165 }; 166 167 static const u8 ice_fdir_udp4_tun_pkt[] = { 168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 169 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 170 0x00, 0x4e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 173 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 176 0x45, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x40, 0x00, 177 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 179 0x00, 0x00, 0x00, 0x00, 180 }; 181 182 static const u8 ice_fdir_sctp4_tun_pkt[] = { 183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 184 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 185 0x00, 0x52, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 188 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 191 0x45, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 192 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 195 }; 196 197 static const u8 ice_fdir_ip4_tun_pkt[] = { 198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 199 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 200 0x00, 0x46, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 203 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 206 0x45, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 207 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 208 0x00, 0x00, 0x00, 0x00, 209 }; 210 211 static const u8 ice_fdir_tcp6_tun_pkt[] = { 212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 213 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 214 0x00, 0x6e, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 217 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 220 0x60, 0x00, 0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 221 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 222 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 223 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 226 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x20, 0x00, 227 0x00, 0x00, 0x00, 0x00, 228 }; 229 230 static const u8 ice_fdir_udp6_tun_pkt[] = { 231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 232 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 233 0x00, 0x62, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 234 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 236 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 239 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x11, 0x40, 240 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 241 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 245 }; 246 247 static const u8 ice_fdir_sctp6_tun_pkt[] = { 248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 249 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 250 0x00, 0x66, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 252 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 253 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 255 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 256 0x60, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x84, 0x40, 257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 259 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 263 }; 264 265 static const u8 ice_fdir_ip6_tun_pkt[] = { 266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 267 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 268 0x00, 0x5a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 269 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 271 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 274 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x40, 275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 276 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 277 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 278 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 279 }; 280 281 /* Flow Director no-op training packet table */ 282 static const struct ice_fdir_base_pkt ice_fdir_pkt[] = { 283 { 284 ICE_FLTR_PTYPE_NONF_IPV4_TCP, 285 sizeof(ice_fdir_tcpv4_pkt), ice_fdir_tcpv4_pkt, 286 sizeof(ice_fdir_tcp4_tun_pkt), ice_fdir_tcp4_tun_pkt, 287 }, 288 { 289 ICE_FLTR_PTYPE_NONF_IPV4_UDP, 290 sizeof(ice_fdir_udpv4_pkt), ice_fdir_udpv4_pkt, 291 sizeof(ice_fdir_udp4_tun_pkt), ice_fdir_udp4_tun_pkt, 292 }, 293 { 294 ICE_FLTR_PTYPE_NONF_IPV4_SCTP, 295 sizeof(ice_fdir_sctpv4_pkt), ice_fdir_sctpv4_pkt, 296 sizeof(ice_fdir_sctp4_tun_pkt), ice_fdir_sctp4_tun_pkt, 297 }, 298 { 299 ICE_FLTR_PTYPE_NONF_IPV4_OTHER, 300 sizeof(ice_fdir_ipv4_pkt), ice_fdir_ipv4_pkt, 301 sizeof(ice_fdir_ip4_tun_pkt), ice_fdir_ip4_tun_pkt, 302 }, 303 { 304 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP, 305 sizeof(ice_fdir_udp4_gtpu4_pkt), 306 ice_fdir_udp4_gtpu4_pkt, 307 sizeof(ice_fdir_udp4_gtpu4_pkt), 308 ice_fdir_udp4_gtpu4_pkt, 309 }, 310 { 311 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP, 312 sizeof(ice_fdir_tcp4_gtpu4_pkt), 313 ice_fdir_tcp4_gtpu4_pkt, 314 sizeof(ice_fdir_tcp4_gtpu4_pkt), 315 ice_fdir_tcp4_gtpu4_pkt, 316 }, 317 { 318 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP, 319 sizeof(ice_fdir_icmp4_gtpu4_pkt), 320 ice_fdir_icmp4_gtpu4_pkt, 321 sizeof(ice_fdir_icmp4_gtpu4_pkt), 322 ice_fdir_icmp4_gtpu4_pkt, 323 }, 324 { 325 ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER, 326 sizeof(ice_fdir_ipv4_gtpu4_pkt), 327 ice_fdir_ipv4_gtpu4_pkt, 328 sizeof(ice_fdir_ipv4_gtpu4_pkt), 329 ice_fdir_ipv4_gtpu4_pkt, 330 }, 331 { 332 ICE_FLTR_PTYPE_NONF_IPV6_TCP, 333 sizeof(ice_fdir_tcpv6_pkt), ice_fdir_tcpv6_pkt, 334 sizeof(ice_fdir_tcp6_tun_pkt), ice_fdir_tcp6_tun_pkt, 335 }, 336 { 337 ICE_FLTR_PTYPE_NONF_IPV6_UDP, 338 sizeof(ice_fdir_udpv6_pkt), ice_fdir_udpv6_pkt, 339 sizeof(ice_fdir_udp6_tun_pkt), ice_fdir_udp6_tun_pkt, 340 }, 341 { 342 ICE_FLTR_PTYPE_NONF_IPV6_SCTP, 343 sizeof(ice_fdir_sctpv6_pkt), ice_fdir_sctpv6_pkt, 344 sizeof(ice_fdir_sctp6_tun_pkt), ice_fdir_sctp6_tun_pkt, 345 }, 346 { 347 ICE_FLTR_PTYPE_NONF_IPV6_OTHER, 348 sizeof(ice_fdir_ipv6_pkt), ice_fdir_ipv6_pkt, 349 sizeof(ice_fdir_ip6_tun_pkt), ice_fdir_ip6_tun_pkt, 350 }, 351 }; 352 353 #define ICE_FDIR_NUM_PKT ARRAY_SIZE(ice_fdir_pkt) 354 355 /* Flow Direcotr (FD) filter program descriptor Context */ 356 static const struct ice_ctx_ele ice_fd_fltr_desc_ctx_info[] = { 357 /* Field Width LSB */ 358 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, qindex, 11, 0), 359 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, comp_q, 1, 11), 360 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, comp_report, 2, 12), 361 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, fd_space, 2, 14), 362 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, cnt_index, 13, 16), 363 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, cnt_ena, 2, 29), 364 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, evict_ena, 1, 31), 365 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, toq, 3, 32), 366 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, toq_prio, 3, 35), 367 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, dpu_recipe, 2, 38), 368 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, drop, 1, 40), 369 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, flex_prio, 3, 41), 370 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, flex_mdid, 4, 44), 371 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, flex_val, 16, 48), 372 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, dtype, 4, 64), 373 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, pcmd, 1, 68), 374 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, desc_prof_prio, 3, 69), 375 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, desc_prof, 6, 72), 376 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, fd_vsi, 10, 78), 377 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, swap, 1, 88), 378 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, fdid_prio, 3, 89), 379 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, fdid_mdid, 4, 92), 380 ICE_CTX_STORE(ice_fd_fltr_desc_ctx, fdid, 32, 96), 381 { 0 } 382 }; 383 384 /** 385 * ice_set_dflt_val_fd_desc 386 * @fd_fltr_ctx: pointer to fd filter descriptor 387 */ 388 void 389 ice_set_dflt_val_fd_desc(struct ice_fd_fltr_desc_ctx *fd_fltr_ctx) 390 { 391 fd_fltr_ctx->comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO; 392 fd_fltr_ctx->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL; 393 fd_fltr_ctx->fd_space = ICE_FXD_FLTR_QW0_FD_SPACE_GUAR_BEST; 394 fd_fltr_ctx->cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS; 395 fd_fltr_ctx->evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_TRUE; 396 fd_fltr_ctx->toq = ICE_FXD_FLTR_QW0_TO_Q_EQUALS_QINDEX; 397 fd_fltr_ctx->toq_prio = ICE_FXD_FLTR_QW0_TO_Q_PRIO1; 398 fd_fltr_ctx->dpu_recipe = ICE_FXD_FLTR_QW0_DPU_RECIPE_DFLT; 399 fd_fltr_ctx->drop = ICE_FXD_FLTR_QW0_DROP_NO; 400 fd_fltr_ctx->flex_prio = ICE_FXD_FLTR_QW0_FLEX_PRI_NONE; 401 fd_fltr_ctx->flex_mdid = ICE_FXD_FLTR_QW0_FLEX_MDID0; 402 fd_fltr_ctx->flex_val = ICE_FXD_FLTR_QW0_FLEX_VAL0; 403 fd_fltr_ctx->dtype = ICE_TX_DESC_DTYPE_FLTR_PROG; 404 fd_fltr_ctx->desc_prof_prio = ICE_FXD_FLTR_QW1_PROF_PRIO_ZERO; 405 fd_fltr_ctx->desc_prof = ICE_FXD_FLTR_QW1_PROF_ZERO; 406 fd_fltr_ctx->swap = ICE_FXD_FLTR_QW1_SWAP_SET; 407 fd_fltr_ctx->fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_ONE; 408 fd_fltr_ctx->fdid_mdid = ICE_FXD_FLTR_QW1_FDID_MDID_FD; 409 fd_fltr_ctx->fdid = ICE_FXD_FLTR_QW1_FDID_ZERO; 410 } 411 412 /** 413 * ice_fdir_get_prgm_desc - set a fdir descriptor from a fdir filter struct 414 * @hw: pointer to the hardware structure 415 * @input: filter 416 * @fdesc: filter descriptor 417 * @add: if add is true, this is an add operation, false implies delete 418 */ 419 void 420 ice_fdir_get_prgm_desc(struct ice_hw *hw, struct ice_fdir_fltr *input, 421 struct ice_fltr_desc *fdesc, bool add) 422 { 423 struct ice_fd_fltr_desc_ctx fdir_fltr_ctx = { 0 }; 424 425 /* set default context info */ 426 ice_set_dflt_val_fd_desc(&fdir_fltr_ctx); 427 428 /* change sideband filtering values */ 429 fdir_fltr_ctx.fdid = input->fltr_id; 430 if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DROP_PKT) { 431 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_YES; 432 fdir_fltr_ctx.qindex = 0; 433 } else { 434 if (input->dest_ctl == 435 ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QGROUP) 436 fdir_fltr_ctx.toq = input->q_region; 437 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO; 438 fdir_fltr_ctx.qindex = input->q_index; 439 } 440 fdir_fltr_ctx.cnt_ena = input->cnt_ena; 441 fdir_fltr_ctx.cnt_index = input->cnt_index; 442 fdir_fltr_ctx.fd_vsi = ice_get_hw_vsi_num(hw, input->dest_vsi); 443 fdir_fltr_ctx.evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_FALSE; 444 fdir_fltr_ctx.toq_prio = 3; 445 fdir_fltr_ctx.pcmd = (add) ? ICE_FXD_FLTR_QW1_PCMD_ADD : 446 ICE_FXD_FLTR_QW1_PCMD_REMOVE; 447 fdir_fltr_ctx.swap = ICE_FXD_FLTR_QW1_SWAP_NOT_SET; 448 fdir_fltr_ctx.comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO; 449 fdir_fltr_ctx.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW; 450 fdir_fltr_ctx.fdid_prio = 3; 451 fdir_fltr_ctx.desc_prof = 1; 452 fdir_fltr_ctx.desc_prof_prio = 3; 453 ice_set_fd_desc_val(&fdir_fltr_ctx, fdesc); 454 } 455 456 /** 457 * ice_set_fd_desc_val 458 * @fd_fltr_ctx: pointer to fd filter descriptor context 459 * @fdir_desc: populated with fd filter descriptor values 460 */ 461 void 462 ice_set_fd_desc_val(struct ice_fd_fltr_desc_ctx *fd_fltr_ctx, 463 struct ice_fltr_desc *fdir_desc) 464 { 465 u64 ctx_buf[2] = { 0 }; 466 467 ice_set_ctx((u8 *)fd_fltr_ctx, (u8 *)ctx_buf, 468 ice_fd_fltr_desc_ctx_info); 469 fdir_desc->qidx_compq_space_stat = CPU_TO_LE64(ctx_buf[0]); 470 fdir_desc->dtype_cmd_vsi_fdid = CPU_TO_LE64(ctx_buf[1]); 471 } 472 473 /** 474 * ice_alloc_fd_res_cntr - obtain counter resource for FD type 475 * @hw: pointer to the hardware structure 476 * @cntr_id: returns counter index 477 */ 478 enum ice_status ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id) 479 { 480 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK, 481 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id); 482 } 483 484 /** 485 * ice_free_fd_res_cntr - Free counter resource for FD type 486 * @hw: pointer to the hardware structure 487 * @cntr_id: counter index to be freed 488 */ 489 enum ice_status ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id) 490 { 491 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK, 492 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id); 493 } 494 495 /** 496 * ice_alloc_fd_guar_item - allocate resource for FD guaranteed entries 497 * @hw: pointer to the hardware structure 498 * @cntr_id: returns counter index 499 * @num_fltr: number of filter entries to be allocated 500 */ 501 enum ice_status 502 ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr) 503 { 504 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES, 505 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr, 506 cntr_id); 507 } 508 509 /** 510 * ice_free_fd_guar_item - Free flow director guaranteed entries 511 * @hw: pointer to the hardware structure 512 * @cntr_id: counter index that needs to be freed 513 * @num_fltr: number of filters to be freed 514 */ 515 enum ice_status 516 ice_free_fd_guar_item(struct ice_hw *hw, u16 cntr_id, u16 num_fltr) 517 { 518 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES, 519 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr, 520 cntr_id); 521 } 522 523 /** 524 * ice_alloc_fd_shrd_item - allocate resource for flow director shared entries 525 * @hw: pointer to the hardware structure 526 * @cntr_id: returns counter index 527 * @num_fltr: number of filter entries to be allocated 528 */ 529 enum ice_status 530 ice_alloc_fd_shrd_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr) 531 { 532 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES, 533 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr, 534 cntr_id); 535 } 536 537 /** 538 * ice_free_fd_shrd_item - Free flow director shared entries 539 * @hw: pointer to the hardware structure 540 * @cntr_id: counter index that needs to be freed 541 * @num_fltr: number of filters to be freed 542 */ 543 enum ice_status 544 ice_free_fd_shrd_item(struct ice_hw *hw, u16 cntr_id, u16 num_fltr) 545 { 546 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES, 547 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr, 548 cntr_id); 549 } 550 551 /** 552 * ice_get_fdir_cnt_all - get the number of Flow Director filters 553 * @hw: hardware data structure 554 * 555 * Returns the number of filters available on device 556 */ 557 int ice_get_fdir_cnt_all(struct ice_hw *hw) 558 { 559 return hw->func_caps.fd_fltr_guar + 560 hw->func_caps.fd_fltr_best_effort; 561 } 562 563 /** 564 * ice_pkt_insert_ipv6_addr - insert a be32 IPv6 address into a memory buffer. 565 * @pkt: packet buffer 566 * @offset: offset into buffer 567 * @addr: IPv6 address to convert and insert into pkt at offset 568 */ 569 static void ice_pkt_insert_ipv6_addr(u8 *pkt, int offset, __be32 *addr) 570 { 571 int idx; 572 573 for (idx = 0; idx < ICE_IPV6_ADDR_LEN_AS_U32; idx++) 574 ice_memcpy(pkt + offset + idx * sizeof(*addr), &addr[idx], 575 sizeof(*addr), ICE_NONDMA_TO_NONDMA); 576 } 577 578 /** 579 * ice_pkt_insert_u6_qfi - insert a u6 value qfi into a memory buffer for gtpu 580 * @pkt: packet buffer 581 * @offset: offset into buffer 582 * @data: 8 bit value to convert and insert into pkt at offset 583 * 584 * This function is designed for inserting qfi (6 bits) for gtpu. 585 */ 586 static void ice_pkt_insert_u6_qfi(u8 *pkt, int offset, u8 data) 587 { 588 u8 ret; 589 590 ret = (data & 0x3F) + (*(pkt + offset) & 0xC0); 591 ice_memcpy(pkt + offset, &ret, sizeof(ret), ICE_NONDMA_TO_NONDMA); 592 } 593 594 /** 595 * ice_pkt_insert_u8 - insert a u8 value into a memory buffer. 596 * @pkt: packet buffer 597 * @offset: offset into buffer 598 * @data: 8 bit value to convert and insert into pkt at offset 599 */ 600 static void ice_pkt_insert_u8(u8 *pkt, int offset, u8 data) 601 { 602 ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA); 603 } 604 605 /** 606 * ice_pkt_insert_u8_tc - insert a u8 value into a memory buffer for tc ipv6. 607 * @pkt: packet buffer 608 * @offset: offset into buffer 609 * @data: 8 bit value to convert and insert into pkt at offset 610 * 611 * This function is designed for inserting Traffic Class (tc) for IPv6, 612 * since that tc is not aligned in number of bytes. Here we split it out 613 * into two part and fill each byte with data copy from pkt, then insert 614 * the two bytes data one by one. 615 */ 616 static void ice_pkt_insert_u8_tc(u8 *pkt, int offset, u8 data) 617 { 618 u8 high, low; 619 620 high = (data >> 4) + (*(pkt + offset) & 0xF0); 621 ice_memcpy(pkt + offset, &high, sizeof(high), ICE_NONDMA_TO_NONDMA); 622 623 low = (*(pkt + offset + 1) & 0x0F) + ((data & 0x0F) << 4); 624 ice_memcpy(pkt + offset + 1, &low, sizeof(low), ICE_NONDMA_TO_NONDMA); 625 } 626 627 /** 628 * ice_pkt_insert_u16 - insert a be16 value into a memory buffer. 629 * @pkt: packet buffer 630 * @offset: offset into buffer 631 * @data: 16 bit value to convert and insert into pkt at offset 632 */ 633 static void ice_pkt_insert_u16(u8 *pkt, int offset, __be16 data) 634 { 635 ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA); 636 } 637 638 /** 639 * ice_pkt_insert_u32 - insert a be32 value into a memory buffer. 640 * @pkt: packet buffer 641 * @offset: offset into buffer 642 * @data: 32 bit value to convert and insert into pkt at offset 643 */ 644 static void ice_pkt_insert_u32(u8 *pkt, int offset, __be32 data) 645 { 646 ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA); 647 } 648 649 /** 650 * ice_pkt_insert_mac_addr - insert a MAC addr into a memory buffer. 651 * @pkt: packet buffer 652 * @offset: offset into buffer 653 * @addr: MAC address to convert and insert into pkt at offset 654 */ 655 static void ice_pkt_insert_mac_addr(u8 *pkt, u8 *addr) 656 { 657 ice_memcpy(pkt, addr, ETH_ALEN, ICE_NONDMA_TO_NONDMA); 658 } 659 660 /** 661 * ice_fdir_get_gen_prgm_pkt - generate a training packet 662 * @hw: pointer to the hardware structure 663 * @input: flow director filter data structure 664 * @pkt: pointer to return filter packet 665 * @frag: generate a fragment packet 666 * @tun: true implies generate a tunnel packet 667 */ 668 enum ice_status 669 ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input, 670 u8 *pkt, bool frag, bool tun) 671 { 672 enum ice_fltr_ptype flow; 673 u16 tnl_port; 674 u8 *loc; 675 u16 idx; 676 677 if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) { 678 switch (input->ip.v4.proto) { 679 case ICE_IP_PROTO_TCP: 680 flow = ICE_FLTR_PTYPE_NONF_IPV4_TCP; 681 break; 682 case ICE_IP_PROTO_UDP: 683 flow = ICE_FLTR_PTYPE_NONF_IPV4_UDP; 684 break; 685 case ICE_IP_PROTO_SCTP: 686 flow = ICE_FLTR_PTYPE_NONF_IPV4_SCTP; 687 break; 688 default: 689 flow = ICE_FLTR_PTYPE_NONF_IPV4_OTHER; 690 break; 691 } 692 } else if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) { 693 switch (input->ip.v6.proto) { 694 case ICE_IP_PROTO_TCP: 695 flow = ICE_FLTR_PTYPE_NONF_IPV6_TCP; 696 break; 697 case ICE_IP_PROTO_UDP: 698 flow = ICE_FLTR_PTYPE_NONF_IPV6_UDP; 699 break; 700 case ICE_IP_PROTO_SCTP: 701 flow = ICE_FLTR_PTYPE_NONF_IPV6_SCTP; 702 break; 703 default: 704 flow = ICE_FLTR_PTYPE_NONF_IPV6_OTHER; 705 break; 706 } 707 } else { 708 flow = input->flow_type; 709 } 710 711 for (idx = 0; idx < ICE_FDIR_NUM_PKT; idx++) 712 if (ice_fdir_pkt[idx].flow == flow) 713 break; 714 if (idx == ICE_FDIR_NUM_PKT) 715 return ICE_ERR_PARAM; 716 if (!tun) { 717 ice_memcpy(pkt, ice_fdir_pkt[idx].pkt, 718 ice_fdir_pkt[idx].pkt_len, ICE_NONDMA_TO_NONDMA); 719 loc = pkt; 720 } else { 721 if (!ice_get_open_tunnel_port(hw, TNL_ALL, &tnl_port)) 722 return ICE_ERR_DOES_NOT_EXIST; 723 if (!ice_fdir_pkt[idx].tun_pkt) 724 return ICE_ERR_PARAM; 725 ice_memcpy(pkt, ice_fdir_pkt[idx].tun_pkt, 726 ice_fdir_pkt[idx].tun_pkt_len, ICE_NONDMA_TO_NONDMA); 727 ice_pkt_insert_u16(pkt, ICE_IPV4_UDP_DST_PORT_OFFSET, 728 HTONS(tnl_port)); 729 loc = &pkt[ICE_FDIR_TUN_PKT_OFF]; 730 } 731 732 switch (flow) { 733 case ICE_FLTR_PTYPE_NONF_IPV4_TCP: 734 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 735 input->ip.v4.dst_ip); 736 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_DST_PORT_OFFSET, 737 input->ip.v4.dst_port); 738 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 739 input->ip.v4.src_ip); 740 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET, 741 input->ip.v4.src_port); 742 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos); 743 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl); 744 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 745 if (frag) 746 loc[20] = ICE_FDIR_IPV4_PKT_FLAG_DF; 747 break; 748 case ICE_FLTR_PTYPE_NONF_IPV4_UDP: 749 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 750 input->ip.v4.dst_ip); 751 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_DST_PORT_OFFSET, 752 input->ip.v4.dst_port); 753 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 754 input->ip.v4.src_ip); 755 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET, 756 input->ip.v4.src_port); 757 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos); 758 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl); 759 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 760 break; 761 case ICE_FLTR_PTYPE_NONF_IPV4_SCTP: 762 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 763 input->ip.v4.dst_ip); 764 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_DST_PORT_OFFSET, 765 input->ip.v4.dst_port); 766 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 767 input->ip.v4.src_ip); 768 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_SRC_PORT_OFFSET, 769 input->ip.v4.src_port); 770 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos); 771 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl); 772 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 773 break; 774 case ICE_FLTR_PTYPE_NONF_IPV4_OTHER: 775 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 776 input->ip.v4.dst_ip); 777 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 778 input->ip.v4.src_ip); 779 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos); 780 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl); 781 ice_pkt_insert_u8(loc, ICE_IPV4_PROTO_OFFSET, 782 input->ip.v4.proto); 783 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 784 break; 785 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP: 786 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP: 787 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP: 788 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER: 789 ice_pkt_insert_u6_qfi(loc, ICE_IPV4_GTPU_QFI_OFFSET, 790 input->gtpu_data.qfi); 791 break; 792 case ICE_FLTR_PTYPE_NONF_IPV6_TCP: 793 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 794 input->ip.v6.dst_ip); 795 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 796 input->ip.v6.src_ip); 797 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_DST_PORT_OFFSET, 798 input->ip.v6.dst_port); 799 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET, 800 input->ip.v6.src_port); 801 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc); 802 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim); 803 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 804 break; 805 case ICE_FLTR_PTYPE_NONF_IPV6_UDP: 806 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 807 input->ip.v6.dst_ip); 808 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 809 input->ip.v6.src_ip); 810 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_DST_PORT_OFFSET, 811 input->ip.v6.dst_port); 812 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET, 813 input->ip.v6.src_port); 814 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc); 815 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim); 816 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 817 break; 818 case ICE_FLTR_PTYPE_NONF_IPV6_SCTP: 819 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 820 input->ip.v6.dst_ip); 821 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 822 input->ip.v6.src_ip); 823 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_DST_PORT_OFFSET, 824 input->ip.v6.dst_port); 825 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET, 826 input->ip.v6.src_port); 827 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc); 828 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim); 829 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 830 break; 831 case ICE_FLTR_PTYPE_NONF_IPV6_OTHER: 832 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 833 input->ip.v6.dst_ip); 834 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 835 input->ip.v6.src_ip); 836 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc); 837 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim); 838 ice_pkt_insert_u8(loc, ICE_IPV6_PROTO_OFFSET, 839 input->ip.v6.proto); 840 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 841 break; 842 default: 843 return ICE_ERR_PARAM; 844 } 845 846 if (input->flex_fltr) 847 ice_pkt_insert_u16(loc, input->flex_offset, input->flex_word); 848 849 return ICE_SUCCESS; 850 } 851 852 /** 853 * ice_fdir_get_prgm_pkt - generate a training packet 854 * @input: flow director filter data structure 855 * @pkt: pointer to return filter packet 856 * @frag: generate a fragment packet 857 */ 858 enum ice_status 859 ice_fdir_get_prgm_pkt(struct ice_fdir_fltr *input, u8 *pkt, bool frag) 860 { 861 return ice_fdir_get_gen_prgm_pkt(NULL, input, pkt, frag, false); 862 } 863 864 /** 865 * ice_fdir_has_frag - does flow type have 2 ptypes 866 * @flow: flow ptype 867 * 868 * returns true is there is a fragment packet for this ptype 869 */ 870 bool ice_fdir_has_frag(enum ice_fltr_ptype flow) 871 { 872 if (flow == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) 873 return true; 874 else 875 return false; 876 } 877 878 /** 879 * ice_fdir_find_by_idx - find filter with idx 880 * @hw: pointer to hardware structure 881 * @fltr_idx: index to find. 882 * 883 * Returns pointer to filter if found or null 884 */ 885 struct ice_fdir_fltr * 886 ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx) 887 { 888 struct ice_fdir_fltr *rule = NULL; 889 890 LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr, 891 fltr_node) { 892 /* rule ID found in the list */ 893 if (fltr_idx == rule->fltr_id) 894 return rule; 895 if (fltr_idx < rule->fltr_id) 896 break; 897 } 898 return NULL; 899 } 900 901 /** 902 * ice_fdir_list_add_fltr - add a new node to the flow director filter list 903 * @hw: hardware structure 904 * @fltr: filter node to add to structure 905 */ 906 void ice_fdir_list_add_fltr(struct ice_hw *hw, struct ice_fdir_fltr *fltr) 907 { 908 struct ice_fdir_fltr *rule, *parent = NULL; 909 910 LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr, 911 fltr_node) { 912 /* rule ID found or pass its spot in the list */ 913 if (rule->fltr_id >= fltr->fltr_id) 914 break; 915 parent = rule; 916 } 917 918 if (parent) 919 LIST_ADD_AFTER(&fltr->fltr_node, &parent->fltr_node); 920 else 921 LIST_ADD(&fltr->fltr_node, &hw->fdir_list_head); 922 } 923 924 /** 925 * ice_fdir_update_cntrs - increment / decrement filter counter 926 * @hw: pointer to hardware structure 927 * @flow: filter flow type 928 * @add: true implies filters added 929 */ 930 void 931 ice_fdir_update_cntrs(struct ice_hw *hw, enum ice_fltr_ptype flow, bool add) 932 { 933 int incr; 934 935 incr = (add) ? 1 : -1; 936 hw->fdir_active_fltr += incr; 937 if (flow == ICE_FLTR_PTYPE_NONF_NONE || flow >= ICE_FLTR_PTYPE_MAX) 938 ice_debug(hw, ICE_DBG_SW, "Unknown filter type %d\n", flow); 939 else 940 hw->fdir_fltr_cnt[flow] += incr; 941 } 942 943 /** 944 * ice_cmp_ipv6_addr - compare 2 IP v6 addresses 945 * @a: IP v6 address 946 * @b: IP v6 address 947 * 948 * Returns 0 on equal, returns non-0 if different 949 */ 950 static int ice_cmp_ipv6_addr(__be32 *a, __be32 *b) 951 { 952 return memcmp(a, b, 4 * sizeof(__be32)); 953 } 954 955 /** 956 * ice_fdir_comp_ipv6_rules - compare 2 filters 957 * @a: a Flow Director filter data structure 958 * @b: a Flow Director filter data structure 959 * @v6: bool true if v6 filter 960 * 961 * Returns true if the filters match 962 */ 963 static bool 964 ice_fdir_comp_rules(struct ice_fdir_fltr *a, struct ice_fdir_fltr *b, bool v6) 965 { 966 enum ice_fltr_ptype flow_type = a->flow_type; 967 968 /* The calling function already checks that the two filters have the 969 * same flow_type. 970 */ 971 if (!v6) { 972 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP || 973 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP || 974 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP) { 975 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip && 976 a->ip.v4.src_ip == b->ip.v4.src_ip && 977 a->ip.v4.dst_port == b->ip.v4.dst_port && 978 a->ip.v4.src_port == b->ip.v4.src_port) 979 return true; 980 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) { 981 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip && 982 a->ip.v4.src_ip == b->ip.v4.src_ip && 983 a->ip.v4.l4_header == b->ip.v4.l4_header && 984 a->ip.v4.proto == b->ip.v4.proto && 985 a->ip.v4.ip_ver == b->ip.v4.ip_ver && 986 a->ip.v4.tos == b->ip.v4.tos) 987 return true; 988 } 989 } else { 990 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP || 991 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_TCP || 992 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_SCTP) { 993 if (a->ip.v6.dst_port == b->ip.v6.dst_port && 994 a->ip.v6.src_port == b->ip.v6.src_port && 995 !ice_cmp_ipv6_addr(a->ip.v6.dst_ip, 996 b->ip.v6.dst_ip) && 997 !ice_cmp_ipv6_addr(a->ip.v6.src_ip, 998 b->ip.v6.src_ip)) 999 return true; 1000 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) { 1001 if (a->ip.v6.dst_port == b->ip.v6.dst_port && 1002 a->ip.v6.src_port == b->ip.v6.src_port) 1003 return true; 1004 } 1005 } 1006 1007 return false; 1008 } 1009 1010 /** 1011 * ice_fdir_is_dup_fltr - test if filter is already in list for PF 1012 * @hw: hardware data structure 1013 * @input: Flow Director filter data structure 1014 * 1015 * Returns true if the filter is found in the list 1016 */ 1017 bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input) 1018 { 1019 enum ice_fltr_ptype flow_type; 1020 struct ice_fdir_fltr *rule; 1021 bool ret = false; 1022 1023 rule = NULL; 1024 1025 LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr, 1026 fltr_node) { 1027 if (rule->flow_type == input->flow_type) { 1028 flow_type = input->flow_type; 1029 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP || 1030 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP || 1031 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP || 1032 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) 1033 ret = ice_fdir_comp_rules(rule, input, false); 1034 else 1035 ret = ice_fdir_comp_rules(rule, input, true); 1036 if (ret) { 1037 if (rule->fltr_id == input->fltr_id && 1038 rule->q_index != input->q_index) 1039 ret = false; 1040 else 1041 break; 1042 } 1043 } 1044 } 1045 1046 return ret; 1047 } 1048 1049 /** 1050 * ice_clear_vsi_fd_table - admin command to clear FD table for a VSI 1051 * @hw: hardware data structure 1052 * @vsi_num: vsi_num (HW VSI num) 1053 * 1054 * Clears FD table entries by issuing admin command (direct, 0x0B06) 1055 * Must to pass valid vsi_num as returned by "AddVSI". 1056 */ 1057 enum ice_status ice_clear_vsi_fd_table(struct ice_hw *hw, u16 vsi_num) 1058 { 1059 struct ice_aqc_clear_fd_table *cmd; 1060 struct ice_aq_desc desc; 1061 1062 cmd = &desc.params.clear_fd_table; 1063 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_fd_table); 1064 cmd->clear_type = CL_FD_VM_VF_TYPE_VSI_IDX; 1065 1066 cmd->vsi_index = CPU_TO_LE16(vsi_num); 1067 return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 1068 } 1069 1070 /** 1071 * ice_clear_pf_fd_table - admin command to clear FD table for PF 1072 * @hw: hardware data structure 1073 * 1074 * Clears FD table entries for a PF by issuing admin command (direct, 0x0B06) 1075 */ 1076 enum ice_status ice_clear_pf_fd_table(struct ice_hw *hw) 1077 { 1078 struct ice_aqc_clear_fd_table *cmd; 1079 struct ice_aq_desc desc; 1080 1081 cmd = &desc.params.clear_fd_table; 1082 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_fd_table); 1083 cmd->clear_type = CL_FD_VM_VF_TYPE_PF_IDX; 1084 /* vsi_index must be 0 to clear FD table for a PF */ 1085 cmd->vsi_index = CPU_TO_LE16(0); 1086 1087 return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 1088 } 1089