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 /** 356 * ice_set_dflt_val_fd_desc 357 * @fd_fltr_ctx: pointer to fd filter descriptor 358 */ 359 void 360 ice_set_dflt_val_fd_desc(struct ice_fd_fltr_desc_ctx *fd_fltr_ctx) 361 { 362 fd_fltr_ctx->comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO; 363 fd_fltr_ctx->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL; 364 fd_fltr_ctx->fd_space = ICE_FXD_FLTR_QW0_FD_SPACE_GUAR_BEST; 365 fd_fltr_ctx->cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS; 366 fd_fltr_ctx->evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_TRUE; 367 fd_fltr_ctx->toq = ICE_FXD_FLTR_QW0_TO_Q_EQUALS_QINDEX; 368 fd_fltr_ctx->toq_prio = ICE_FXD_FLTR_QW0_TO_Q_PRIO1; 369 fd_fltr_ctx->dpu_recipe = ICE_FXD_FLTR_QW0_DPU_RECIPE_DFLT; 370 fd_fltr_ctx->drop = ICE_FXD_FLTR_QW0_DROP_NO; 371 fd_fltr_ctx->flex_prio = ICE_FXD_FLTR_QW0_FLEX_PRI_NONE; 372 fd_fltr_ctx->flex_mdid = ICE_FXD_FLTR_QW0_FLEX_MDID0; 373 fd_fltr_ctx->flex_val = ICE_FXD_FLTR_QW0_FLEX_VAL0; 374 fd_fltr_ctx->dtype = ICE_TX_DESC_DTYPE_FLTR_PROG; 375 fd_fltr_ctx->desc_prof_prio = ICE_FXD_FLTR_QW1_PROF_PRIO_ZERO; 376 fd_fltr_ctx->desc_prof = ICE_FXD_FLTR_QW1_PROF_ZERO; 377 fd_fltr_ctx->swap = ICE_FXD_FLTR_QW1_SWAP_SET; 378 fd_fltr_ctx->fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_ONE; 379 fd_fltr_ctx->fdid_mdid = ICE_FXD_FLTR_QW1_FDID_MDID_FD; 380 fd_fltr_ctx->fdid = ICE_FXD_FLTR_QW1_FDID_ZERO; 381 } 382 383 /** 384 * ice_fdir_get_prgm_desc - set a fdir descriptor from a fdir filter struct 385 * @hw: pointer to the hardware structure 386 * @input: filter 387 * @fdesc: filter descriptor 388 * @add: if add is true, this is an add operation, false implies delete 389 */ 390 void 391 ice_fdir_get_prgm_desc(struct ice_hw *hw, struct ice_fdir_fltr *input, 392 struct ice_fltr_desc *fdesc, bool add) 393 { 394 struct ice_fd_fltr_desc_ctx fdir_fltr_ctx = { 0 }; 395 396 /* set default context info */ 397 ice_set_dflt_val_fd_desc(&fdir_fltr_ctx); 398 399 /* change sideband filtering values */ 400 fdir_fltr_ctx.fdid = input->fltr_id; 401 if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DROP_PKT) { 402 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_YES; 403 fdir_fltr_ctx.qindex = 0; 404 } else if (input->dest_ctl == 405 ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER) { 406 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO; 407 fdir_fltr_ctx.qindex = 0; 408 } else { 409 if (input->dest_ctl == 410 ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QGROUP) 411 fdir_fltr_ctx.toq = input->q_region; 412 fdir_fltr_ctx.drop = ICE_FXD_FLTR_QW0_DROP_NO; 413 fdir_fltr_ctx.qindex = input->q_index; 414 } 415 fdir_fltr_ctx.cnt_ena = input->cnt_ena; 416 fdir_fltr_ctx.cnt_index = input->cnt_index; 417 fdir_fltr_ctx.fd_vsi = ice_get_hw_vsi_num(hw, input->dest_vsi); 418 fdir_fltr_ctx.evict_ena = ICE_FXD_FLTR_QW0_EVICT_ENA_FALSE; 419 if (input->dest_ctl == ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER) 420 fdir_fltr_ctx.toq_prio = 0; 421 else 422 fdir_fltr_ctx.toq_prio = 3; 423 fdir_fltr_ctx.pcmd = (add) ? ICE_FXD_FLTR_QW1_PCMD_ADD : 424 ICE_FXD_FLTR_QW1_PCMD_REMOVE; 425 fdir_fltr_ctx.swap = ICE_FXD_FLTR_QW1_SWAP_NOT_SET; 426 fdir_fltr_ctx.comp_q = ICE_FXD_FLTR_QW0_COMP_Q_ZERO; 427 fdir_fltr_ctx.comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW; 428 fdir_fltr_ctx.fdid_prio = input->fdid_prio; 429 fdir_fltr_ctx.desc_prof = 1; 430 fdir_fltr_ctx.desc_prof_prio = 3; 431 ice_set_fd_desc_val(&fdir_fltr_ctx, fdesc); 432 } 433 434 /** 435 * ice_set_fd_desc_val 436 * @ctx: pointer to fd filter descriptor context 437 * @fdir_desc: populated with fd filter descriptor values 438 */ 439 void 440 ice_set_fd_desc_val(struct ice_fd_fltr_desc_ctx *ctx, 441 struct ice_fltr_desc *fdir_desc) 442 { 443 u64 qword; 444 445 /* prep QW0 of FD filter programming desc */ 446 qword = ((u64)ctx->qindex << ICE_FXD_FLTR_QW0_QINDEX_S) & 447 ICE_FXD_FLTR_QW0_QINDEX_M; 448 qword |= ((u64)ctx->comp_q << ICE_FXD_FLTR_QW0_COMP_Q_S) & 449 ICE_FXD_FLTR_QW0_COMP_Q_M; 450 qword |= ((u64)ctx->comp_report << ICE_FXD_FLTR_QW0_COMP_REPORT_S) & 451 ICE_FXD_FLTR_QW0_COMP_REPORT_M; 452 qword |= ((u64)ctx->fd_space << ICE_FXD_FLTR_QW0_FD_SPACE_S) & 453 ICE_FXD_FLTR_QW0_FD_SPACE_M; 454 qword |= ((u64)ctx->cnt_index << ICE_FXD_FLTR_QW0_STAT_CNT_S) & 455 ICE_FXD_FLTR_QW0_STAT_CNT_M; 456 qword |= ((u64)ctx->cnt_ena << ICE_FXD_FLTR_QW0_STAT_ENA_S) & 457 ICE_FXD_FLTR_QW0_STAT_ENA_M; 458 qword |= ((u64)ctx->evict_ena << ICE_FXD_FLTR_QW0_EVICT_ENA_S) & 459 ICE_FXD_FLTR_QW0_EVICT_ENA_M; 460 qword |= ((u64)ctx->toq << ICE_FXD_FLTR_QW0_TO_Q_S) & 461 ICE_FXD_FLTR_QW0_TO_Q_M; 462 qword |= ((u64)ctx->toq_prio << ICE_FXD_FLTR_QW0_TO_Q_PRI_S) & 463 ICE_FXD_FLTR_QW0_TO_Q_PRI_M; 464 qword |= ((u64)ctx->dpu_recipe << ICE_FXD_FLTR_QW0_DPU_RECIPE_S) & 465 ICE_FXD_FLTR_QW0_DPU_RECIPE_M; 466 qword |= ((u64)ctx->drop << ICE_FXD_FLTR_QW0_DROP_S) & 467 ICE_FXD_FLTR_QW0_DROP_M; 468 qword |= ((u64)ctx->flex_prio << ICE_FXD_FLTR_QW0_FLEX_PRI_S) & 469 ICE_FXD_FLTR_QW0_FLEX_PRI_M; 470 qword |= ((u64)ctx->flex_mdid << ICE_FXD_FLTR_QW0_FLEX_MDID_S) & 471 ICE_FXD_FLTR_QW0_FLEX_MDID_M; 472 qword |= ((u64)ctx->flex_val << ICE_FXD_FLTR_QW0_FLEX_VAL_S) & 473 ICE_FXD_FLTR_QW0_FLEX_VAL_M; 474 fdir_desc->qidx_compq_space_stat = CPU_TO_LE64(qword); 475 476 /* prep QW1 of FD filter programming desc */ 477 qword = ((u64)ctx->dtype << ICE_FXD_FLTR_QW1_DTYPE_S) & 478 ICE_FXD_FLTR_QW1_DTYPE_M; 479 qword |= ((u64)ctx->pcmd << ICE_FXD_FLTR_QW1_PCMD_S) & 480 ICE_FXD_FLTR_QW1_PCMD_M; 481 qword |= ((u64)ctx->desc_prof_prio << ICE_FXD_FLTR_QW1_PROF_PRI_S) & 482 ICE_FXD_FLTR_QW1_PROF_PRI_M; 483 qword |= ((u64)ctx->desc_prof << ICE_FXD_FLTR_QW1_PROF_S) & 484 ICE_FXD_FLTR_QW1_PROF_M; 485 qword |= ((u64)ctx->fd_vsi << ICE_FXD_FLTR_QW1_FD_VSI_S) & 486 ICE_FXD_FLTR_QW1_FD_VSI_M; 487 qword |= ((u64)ctx->swap << ICE_FXD_FLTR_QW1_SWAP_S) & 488 ICE_FXD_FLTR_QW1_SWAP_M; 489 qword |= ((u64)ctx->fdid_prio << ICE_FXD_FLTR_QW1_FDID_PRI_S) & 490 ICE_FXD_FLTR_QW1_FDID_PRI_M; 491 qword |= ((u64)ctx->fdid_mdid << ICE_FXD_FLTR_QW1_FDID_MDID_S) & 492 ICE_FXD_FLTR_QW1_FDID_MDID_M; 493 qword |= ((u64)ctx->fdid << ICE_FXD_FLTR_QW1_FDID_S) & 494 ICE_FXD_FLTR_QW1_FDID_M; 495 fdir_desc->dtype_cmd_vsi_fdid = CPU_TO_LE64(qword); 496 } 497 498 /** 499 * ice_alloc_fd_res_cntr - obtain counter resource for FD type 500 * @hw: pointer to the hardware structure 501 * @cntr_id: returns counter index 502 */ 503 enum ice_status ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id) 504 { 505 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK, 506 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id); 507 } 508 509 /** 510 * ice_free_fd_res_cntr - Free counter resource for FD type 511 * @hw: pointer to the hardware structure 512 * @cntr_id: counter index to be freed 513 */ 514 enum ice_status ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id) 515 { 516 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_COUNTER_BLOCK, 517 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, cntr_id); 518 } 519 520 /** 521 * ice_alloc_fd_guar_item - allocate resource for FD guaranteed entries 522 * @hw: pointer to the hardware structure 523 * @cntr_id: returns counter index 524 * @num_fltr: number of filter entries to be allocated 525 */ 526 enum ice_status 527 ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr) 528 { 529 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES, 530 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr, 531 cntr_id); 532 } 533 534 /** 535 * ice_free_fd_guar_item - Free flow director guaranteed entries 536 * @hw: pointer to the hardware structure 537 * @cntr_id: counter index that needs to be freed 538 * @num_fltr: number of filters to be freed 539 */ 540 enum ice_status 541 ice_free_fd_guar_item(struct ice_hw *hw, u16 cntr_id, u16 num_fltr) 542 { 543 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_GUARANTEED_ENTRIES, 544 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr, 545 cntr_id); 546 } 547 548 /** 549 * ice_alloc_fd_shrd_item - allocate resource for flow director shared entries 550 * @hw: pointer to the hardware structure 551 * @cntr_id: returns counter index 552 * @num_fltr: number of filter entries to be allocated 553 */ 554 enum ice_status 555 ice_alloc_fd_shrd_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr) 556 { 557 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES, 558 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr, 559 cntr_id); 560 } 561 562 /** 563 * ice_free_fd_shrd_item - Free flow director shared entries 564 * @hw: pointer to the hardware structure 565 * @cntr_id: counter index that needs to be freed 566 * @num_fltr: number of filters to be freed 567 */ 568 enum ice_status 569 ice_free_fd_shrd_item(struct ice_hw *hw, u16 cntr_id, u16 num_fltr) 570 { 571 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_FDIR_SHARED_ENTRIES, 572 ICE_AQC_RES_TYPE_FLAG_DEDICATED, num_fltr, 573 cntr_id); 574 } 575 576 /** 577 * ice_get_fdir_cnt_all - get the number of Flow Director filters 578 * @hw: hardware data structure 579 * 580 * Returns the number of filters available on device 581 */ 582 int ice_get_fdir_cnt_all(struct ice_hw *hw) 583 { 584 return hw->func_caps.fd_fltr_guar + 585 hw->func_caps.fd_fltr_best_effort; 586 } 587 588 /** 589 * ice_pkt_insert_ipv6_addr - insert a be32 IPv6 address into a memory buffer. 590 * @pkt: packet buffer 591 * @offset: offset into buffer 592 * @addr: IPv6 address to convert and insert into pkt at offset 593 */ 594 static void ice_pkt_insert_ipv6_addr(u8 *pkt, int offset, __be32 *addr) 595 { 596 int idx; 597 598 for (idx = 0; idx < ICE_IPV6_ADDR_LEN_AS_U32; idx++) 599 ice_memcpy(pkt + offset + idx * sizeof(*addr), &addr[idx], 600 sizeof(*addr), ICE_NONDMA_TO_NONDMA); 601 } 602 603 /** 604 * ice_pkt_insert_u6_qfi - insert a u6 value qfi into a memory buffer for gtpu 605 * @pkt: packet buffer 606 * @offset: offset into buffer 607 * @data: 8 bit value to convert and insert into pkt at offset 608 * 609 * This function is designed for inserting qfi (6 bits) for gtpu. 610 */ 611 static void ice_pkt_insert_u6_qfi(u8 *pkt, int offset, u8 data) 612 { 613 u8 ret; 614 615 ret = (data & 0x3F) + (*(pkt + offset) & 0xC0); 616 ice_memcpy(pkt + offset, &ret, sizeof(ret), ICE_NONDMA_TO_NONDMA); 617 } 618 619 /** 620 * ice_pkt_insert_u8 - insert a u8 value into a memory buffer. 621 * @pkt: packet buffer 622 * @offset: offset into buffer 623 * @data: 8 bit value to convert and insert into pkt at offset 624 */ 625 static void ice_pkt_insert_u8(u8 *pkt, int offset, u8 data) 626 { 627 ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA); 628 } 629 630 /** 631 * ice_pkt_insert_u8_tc - insert a u8 value into a memory buffer for tc ipv6. 632 * @pkt: packet buffer 633 * @offset: offset into buffer 634 * @data: 8 bit value to convert and insert into pkt at offset 635 * 636 * This function is designed for inserting Traffic Class (tc) for IPv6, 637 * since that tc is not aligned in number of bytes. Here we split it out 638 * into two part and fill each byte with data copy from pkt, then insert 639 * the two bytes data one by one. 640 */ 641 static void ice_pkt_insert_u8_tc(u8 *pkt, int offset, u8 data) 642 { 643 u8 high, low; 644 645 high = (data >> 4) + (*(pkt + offset) & 0xF0); 646 ice_memcpy(pkt + offset, &high, sizeof(high), ICE_NONDMA_TO_NONDMA); 647 648 low = (*(pkt + offset + 1) & 0x0F) + ((data & 0x0F) << 4); 649 ice_memcpy(pkt + offset + 1, &low, sizeof(low), ICE_NONDMA_TO_NONDMA); 650 } 651 652 /** 653 * ice_pkt_insert_u16 - insert a be16 value into a memory buffer. 654 * @pkt: packet buffer 655 * @offset: offset into buffer 656 * @data: 16 bit value to convert and insert into pkt at offset 657 */ 658 static void ice_pkt_insert_u16(u8 *pkt, int offset, __be16 data) 659 { 660 ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA); 661 } 662 663 /** 664 * ice_pkt_insert_u32 - insert a be32 value into a memory buffer. 665 * @pkt: packet buffer 666 * @offset: offset into buffer 667 * @data: 32 bit value to convert and insert into pkt at offset 668 */ 669 static void ice_pkt_insert_u32(u8 *pkt, int offset, __be32 data) 670 { 671 ice_memcpy(pkt + offset, &data, sizeof(data), ICE_NONDMA_TO_NONDMA); 672 } 673 674 /** 675 * ice_pkt_insert_mac_addr - insert a MAC addr into a memory buffer. 676 * @pkt: packet buffer 677 * @offset: offset into buffer 678 * @addr: MAC address to convert and insert into pkt at offset 679 */ 680 static void ice_pkt_insert_mac_addr(u8 *pkt, u8 *addr) 681 { 682 ice_memcpy(pkt, addr, ETH_ALEN, ICE_NONDMA_TO_NONDMA); 683 } 684 685 /** 686 * ice_fdir_get_gen_prgm_pkt - generate a training packet 687 * @hw: pointer to the hardware structure 688 * @input: flow director filter data structure 689 * @pkt: pointer to return filter packet 690 * @frag: generate a fragment packet 691 * @tun: true implies generate a tunnel packet 692 */ 693 enum ice_status 694 ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input, 695 u8 *pkt, bool frag, bool tun) 696 { 697 enum ice_fltr_ptype flow; 698 u16 tnl_port; 699 u8 *loc; 700 u16 idx; 701 702 if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) { 703 switch (input->ip.v4.proto) { 704 case ICE_IP_PROTO_TCP: 705 flow = ICE_FLTR_PTYPE_NONF_IPV4_TCP; 706 break; 707 case ICE_IP_PROTO_UDP: 708 flow = ICE_FLTR_PTYPE_NONF_IPV4_UDP; 709 break; 710 case ICE_IP_PROTO_SCTP: 711 flow = ICE_FLTR_PTYPE_NONF_IPV4_SCTP; 712 break; 713 default: 714 flow = ICE_FLTR_PTYPE_NONF_IPV4_OTHER; 715 break; 716 } 717 } else if (input->flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) { 718 switch (input->ip.v6.proto) { 719 case ICE_IP_PROTO_TCP: 720 flow = ICE_FLTR_PTYPE_NONF_IPV6_TCP; 721 break; 722 case ICE_IP_PROTO_UDP: 723 flow = ICE_FLTR_PTYPE_NONF_IPV6_UDP; 724 break; 725 case ICE_IP_PROTO_SCTP: 726 flow = ICE_FLTR_PTYPE_NONF_IPV6_SCTP; 727 break; 728 default: 729 flow = ICE_FLTR_PTYPE_NONF_IPV6_OTHER; 730 break; 731 } 732 } else { 733 flow = input->flow_type; 734 } 735 736 for (idx = 0; idx < ICE_FDIR_NUM_PKT; idx++) 737 if (ice_fdir_pkt[idx].flow == flow) 738 break; 739 if (idx == ICE_FDIR_NUM_PKT) 740 return ICE_ERR_PARAM; 741 if (!tun) { 742 ice_memcpy(pkt, ice_fdir_pkt[idx].pkt, 743 ice_fdir_pkt[idx].pkt_len, ICE_NONDMA_TO_NONDMA); 744 loc = pkt; 745 } else { 746 if (!ice_get_open_tunnel_port(hw, TNL_ALL, &tnl_port)) 747 return ICE_ERR_DOES_NOT_EXIST; 748 if (!ice_fdir_pkt[idx].tun_pkt) 749 return ICE_ERR_PARAM; 750 ice_memcpy(pkt, ice_fdir_pkt[idx].tun_pkt, 751 ice_fdir_pkt[idx].tun_pkt_len, ICE_NONDMA_TO_NONDMA); 752 ice_pkt_insert_u16(pkt, ICE_IPV4_UDP_DST_PORT_OFFSET, 753 HTONS(tnl_port)); 754 loc = &pkt[ICE_FDIR_TUN_PKT_OFF]; 755 } 756 757 switch (flow) { 758 case ICE_FLTR_PTYPE_NONF_IPV4_TCP: 759 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 760 input->ip.v4.dst_ip); 761 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_DST_PORT_OFFSET, 762 input->ip.v4.dst_port); 763 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 764 input->ip.v4.src_ip); 765 ice_pkt_insert_u16(loc, ICE_IPV4_TCP_SRC_PORT_OFFSET, 766 input->ip.v4.src_port); 767 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos); 768 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl); 769 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 770 if (frag) 771 loc[20] = ICE_FDIR_IPV4_PKT_FLAG_DF; 772 break; 773 case ICE_FLTR_PTYPE_NONF_IPV4_UDP: 774 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 775 input->ip.v4.dst_ip); 776 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_DST_PORT_OFFSET, 777 input->ip.v4.dst_port); 778 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 779 input->ip.v4.src_ip); 780 ice_pkt_insert_u16(loc, ICE_IPV4_UDP_SRC_PORT_OFFSET, 781 input->ip.v4.src_port); 782 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos); 783 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl); 784 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 785 break; 786 case ICE_FLTR_PTYPE_NONF_IPV4_SCTP: 787 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 788 input->ip.v4.dst_ip); 789 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_DST_PORT_OFFSET, 790 input->ip.v4.dst_port); 791 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 792 input->ip.v4.src_ip); 793 ice_pkt_insert_u16(loc, ICE_IPV4_SCTP_SRC_PORT_OFFSET, 794 input->ip.v4.src_port); 795 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos); 796 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl); 797 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 798 break; 799 case ICE_FLTR_PTYPE_NONF_IPV4_OTHER: 800 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 801 input->ip.v4.dst_ip); 802 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 803 input->ip.v4.src_ip); 804 ice_pkt_insert_u8(loc, ICE_IPV4_TOS_OFFSET, input->ip.v4.tos); 805 ice_pkt_insert_u8(loc, ICE_IPV4_TTL_OFFSET, input->ip.v4.ttl); 806 ice_pkt_insert_u8(loc, ICE_IPV4_PROTO_OFFSET, 807 input->ip.v4.proto); 808 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 809 break; 810 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP: 811 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP: 812 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP: 813 case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER: 814 ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET, 815 input->ip.v4.src_ip); 816 ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET, 817 input->ip.v4.dst_ip); 818 ice_pkt_insert_u32(loc, ICE_IPV4_GTPU_TEID_OFFSET, 819 input->gtpu_data.teid); 820 ice_pkt_insert_u6_qfi(loc, ICE_IPV4_GTPU_QFI_OFFSET, 821 input->gtpu_data.qfi); 822 break; 823 case ICE_FLTR_PTYPE_NONF_IPV6_TCP: 824 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 825 input->ip.v6.dst_ip); 826 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 827 input->ip.v6.src_ip); 828 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_DST_PORT_OFFSET, 829 input->ip.v6.dst_port); 830 ice_pkt_insert_u16(loc, ICE_IPV6_TCP_SRC_PORT_OFFSET, 831 input->ip.v6.src_port); 832 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc); 833 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim); 834 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 835 break; 836 case ICE_FLTR_PTYPE_NONF_IPV6_UDP: 837 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 838 input->ip.v6.dst_ip); 839 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 840 input->ip.v6.src_ip); 841 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_DST_PORT_OFFSET, 842 input->ip.v6.dst_port); 843 ice_pkt_insert_u16(loc, ICE_IPV6_UDP_SRC_PORT_OFFSET, 844 input->ip.v6.src_port); 845 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc); 846 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim); 847 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 848 break; 849 case ICE_FLTR_PTYPE_NONF_IPV6_SCTP: 850 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 851 input->ip.v6.dst_ip); 852 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 853 input->ip.v6.src_ip); 854 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_DST_PORT_OFFSET, 855 input->ip.v6.dst_port); 856 ice_pkt_insert_u16(loc, ICE_IPV6_SCTP_SRC_PORT_OFFSET, 857 input->ip.v6.src_port); 858 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc); 859 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim); 860 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 861 break; 862 case ICE_FLTR_PTYPE_NONF_IPV6_OTHER: 863 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_DST_ADDR_OFFSET, 864 input->ip.v6.dst_ip); 865 ice_pkt_insert_ipv6_addr(loc, ICE_IPV6_SRC_ADDR_OFFSET, 866 input->ip.v6.src_ip); 867 ice_pkt_insert_u8_tc(loc, ICE_IPV6_TC_OFFSET, input->ip.v6.tc); 868 ice_pkt_insert_u8(loc, ICE_IPV6_HLIM_OFFSET, input->ip.v6.hlim); 869 ice_pkt_insert_u8(loc, ICE_IPV6_PROTO_OFFSET, 870 input->ip.v6.proto); 871 ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac); 872 break; 873 default: 874 return ICE_ERR_PARAM; 875 } 876 877 if (input->flex_fltr) 878 ice_pkt_insert_u16(loc, input->flex_offset, input->flex_word); 879 880 return ICE_SUCCESS; 881 } 882 883 /** 884 * ice_fdir_get_prgm_pkt - generate a training packet 885 * @input: flow director filter data structure 886 * @pkt: pointer to return filter packet 887 * @frag: generate a fragment packet 888 */ 889 enum ice_status 890 ice_fdir_get_prgm_pkt(struct ice_fdir_fltr *input, u8 *pkt, bool frag) 891 { 892 return ice_fdir_get_gen_prgm_pkt(NULL, input, pkt, frag, false); 893 } 894 895 /** 896 * ice_fdir_has_frag - does flow type have 2 ptypes 897 * @flow: flow ptype 898 * 899 * returns true is there is a fragment packet for this ptype 900 */ 901 bool ice_fdir_has_frag(enum ice_fltr_ptype flow) 902 { 903 if (flow == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) 904 return true; 905 else 906 return false; 907 } 908 909 /** 910 * ice_fdir_find_by_idx - find filter with idx 911 * @hw: pointer to hardware structure 912 * @fltr_idx: index to find. 913 * 914 * Returns pointer to filter if found or null 915 */ 916 struct ice_fdir_fltr * 917 ice_fdir_find_fltr_by_idx(struct ice_hw *hw, u32 fltr_idx) 918 { 919 struct ice_fdir_fltr *rule = NULL; 920 921 LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr, 922 fltr_node) { 923 /* rule ID found in the list */ 924 if (fltr_idx == rule->fltr_id) 925 return rule; 926 if (fltr_idx < rule->fltr_id) 927 break; 928 } 929 return NULL; 930 } 931 932 /** 933 * ice_fdir_list_add_fltr - add a new node to the flow director filter list 934 * @hw: hardware structure 935 * @fltr: filter node to add to structure 936 */ 937 void ice_fdir_list_add_fltr(struct ice_hw *hw, struct ice_fdir_fltr *fltr) 938 { 939 struct ice_fdir_fltr *rule, *parent = NULL; 940 941 LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr, 942 fltr_node) { 943 /* rule ID found or pass its spot in the list */ 944 if (rule->fltr_id >= fltr->fltr_id) 945 break; 946 parent = rule; 947 } 948 949 if (parent) 950 LIST_ADD_AFTER(&fltr->fltr_node, &parent->fltr_node); 951 else 952 LIST_ADD(&fltr->fltr_node, &hw->fdir_list_head); 953 } 954 955 /** 956 * ice_fdir_update_cntrs - increment / decrement filter counter 957 * @hw: pointer to hardware structure 958 * @flow: filter flow type 959 * @add: true implies filters added 960 */ 961 void 962 ice_fdir_update_cntrs(struct ice_hw *hw, enum ice_fltr_ptype flow, bool add) 963 { 964 int incr; 965 966 incr = (add) ? 1 : -1; 967 hw->fdir_active_fltr += incr; 968 if (flow == ICE_FLTR_PTYPE_NONF_NONE || flow >= ICE_FLTR_PTYPE_MAX) 969 ice_debug(hw, ICE_DBG_SW, "Unknown filter type %d\n", flow); 970 else 971 hw->fdir_fltr_cnt[flow] += incr; 972 } 973 974 /** 975 * ice_cmp_ipv6_addr - compare 2 IP v6 addresses 976 * @a: IP v6 address 977 * @b: IP v6 address 978 * 979 * Returns 0 on equal, returns non-0 if different 980 */ 981 static int ice_cmp_ipv6_addr(__be32 *a, __be32 *b) 982 { 983 return memcmp(a, b, 4 * sizeof(__be32)); 984 } 985 986 /** 987 * ice_fdir_comp_ipv6_rules - compare 2 filters 988 * @a: a Flow Director filter data structure 989 * @b: a Flow Director filter data structure 990 * @v6: bool true if v6 filter 991 * 992 * Returns true if the filters match 993 */ 994 static bool 995 ice_fdir_comp_rules(struct ice_fdir_fltr *a, struct ice_fdir_fltr *b, bool v6) 996 { 997 enum ice_fltr_ptype flow_type = a->flow_type; 998 999 /* The calling function already checks that the two filters have the 1000 * same flow_type. 1001 */ 1002 if (!v6) { 1003 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP || 1004 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP || 1005 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP) { 1006 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip && 1007 a->ip.v4.src_ip == b->ip.v4.src_ip && 1008 a->ip.v4.dst_port == b->ip.v4.dst_port && 1009 a->ip.v4.src_port == b->ip.v4.src_port) 1010 return true; 1011 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) { 1012 if (a->ip.v4.dst_ip == b->ip.v4.dst_ip && 1013 a->ip.v4.src_ip == b->ip.v4.src_ip && 1014 a->ip.v4.l4_header == b->ip.v4.l4_header && 1015 a->ip.v4.proto == b->ip.v4.proto && 1016 a->ip.v4.ip_ver == b->ip.v4.ip_ver && 1017 a->ip.v4.tos == b->ip.v4.tos) 1018 return true; 1019 } 1020 } else { 1021 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP || 1022 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_TCP || 1023 flow_type == ICE_FLTR_PTYPE_NONF_IPV6_SCTP) { 1024 if (a->ip.v6.dst_port == b->ip.v6.dst_port && 1025 a->ip.v6.src_port == b->ip.v6.src_port && 1026 !ice_cmp_ipv6_addr(a->ip.v6.dst_ip, 1027 b->ip.v6.dst_ip) && 1028 !ice_cmp_ipv6_addr(a->ip.v6.src_ip, 1029 b->ip.v6.src_ip)) 1030 return true; 1031 } else if (flow_type == ICE_FLTR_PTYPE_NONF_IPV6_OTHER) { 1032 if (a->ip.v6.dst_port == b->ip.v6.dst_port && 1033 a->ip.v6.src_port == b->ip.v6.src_port) 1034 return true; 1035 } 1036 } 1037 1038 return false; 1039 } 1040 1041 /** 1042 * ice_fdir_is_dup_fltr - test if filter is already in list for PF 1043 * @hw: hardware data structure 1044 * @input: Flow Director filter data structure 1045 * 1046 * Returns true if the filter is found in the list 1047 */ 1048 bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input) 1049 { 1050 enum ice_fltr_ptype flow_type; 1051 struct ice_fdir_fltr *rule; 1052 bool ret = false; 1053 1054 rule = NULL; 1055 1056 LIST_FOR_EACH_ENTRY(rule, &hw->fdir_list_head, ice_fdir_fltr, 1057 fltr_node) { 1058 if (rule->flow_type == input->flow_type) { 1059 flow_type = input->flow_type; 1060 if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_TCP || 1061 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP || 1062 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_SCTP || 1063 flow_type == ICE_FLTR_PTYPE_NONF_IPV4_OTHER) 1064 ret = ice_fdir_comp_rules(rule, input, false); 1065 else 1066 ret = ice_fdir_comp_rules(rule, input, true); 1067 if (ret) { 1068 if (rule->fltr_id == input->fltr_id && 1069 rule->q_index != input->q_index) 1070 ret = false; 1071 else 1072 break; 1073 } 1074 } 1075 } 1076 1077 return ret; 1078 } 1079 1080 /** 1081 * ice_clear_vsi_fd_table - admin command to clear FD table for a VSI 1082 * @hw: hardware data structure 1083 * @vsi_num: vsi_num (HW VSI num) 1084 * 1085 * Clears FD table entries by issuing admin command (direct, 0x0B06) 1086 * Must to pass valid vsi_num as returned by "AddVSI". 1087 */ 1088 enum ice_status ice_clear_vsi_fd_table(struct ice_hw *hw, u16 vsi_num) 1089 { 1090 struct ice_aqc_clear_fd_table *cmd; 1091 struct ice_aq_desc desc; 1092 1093 cmd = &desc.params.clear_fd_table; 1094 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_fd_table); 1095 cmd->clear_type = CL_FD_VM_VF_TYPE_VSI_IDX; 1096 1097 cmd->vsi_index = CPU_TO_LE16(vsi_num); 1098 return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 1099 } 1100 1101 /** 1102 * ice_clear_pf_fd_table - admin command to clear FD table for PF 1103 * @hw: hardware data structure 1104 * 1105 * Clears FD table entries for a PF by issuing admin command (direct, 0x0B06) 1106 */ 1107 enum ice_status ice_clear_pf_fd_table(struct ice_hw *hw) 1108 { 1109 struct ice_aqc_clear_fd_table *cmd; 1110 struct ice_aq_desc desc; 1111 1112 cmd = &desc.params.clear_fd_table; 1113 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_fd_table); 1114 cmd->clear_type = CL_FD_VM_VF_TYPE_PF_IDX; 1115 /* vsi_index must be 0 to clear FD table for a PF */ 1116 cmd->vsi_index = CPU_TO_LE16(0); 1117 1118 return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 1119 } 1120