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