1 /* * SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2018 NXP 3 */ 4 5 #include <sys/queue.h> 6 #include <stdio.h> 7 #include <errno.h> 8 #include <stdint.h> 9 #include <string.h> 10 #include <unistd.h> 11 #include <stdarg.h> 12 13 #include <rte_ethdev.h> 14 #include <rte_log.h> 15 #include <rte_eth_ctrl.h> 16 #include <rte_malloc.h> 17 #include <rte_flow_driver.h> 18 #include <rte_tailq.h> 19 20 #include <fsl_dpni.h> 21 #include <fsl_dpkg.h> 22 23 #include <dpaa2_ethdev.h> 24 #include <dpaa2_pmd_logs.h> 25 26 struct rte_flow { 27 struct dpni_rule_cfg rule; 28 uint8_t key_size; 29 uint8_t tc_id; 30 uint8_t flow_type; 31 uint8_t index; 32 enum rte_flow_action_type action; 33 uint16_t flow_id; 34 }; 35 36 /* Layout for rule compositions for supported patterns */ 37 /* TODO: Current design only supports Ethernet + IPv4 based classification. */ 38 /* So corresponding offset macros are valid only. Rest are placeholder for */ 39 /* now. Once support for other netwrok headers will be added then */ 40 /* corresponding macros will be updated with correct values*/ 41 #define DPAA2_CLS_RULE_OFFSET_ETH 0 /*Start of buffer*/ 42 #define DPAA2_CLS_RULE_OFFSET_VLAN 14 /* DPAA2_CLS_RULE_OFFSET_ETH */ 43 /* + Sizeof Eth fields */ 44 #define DPAA2_CLS_RULE_OFFSET_IPV4 14 /* DPAA2_CLS_RULE_OFFSET_VLAN */ 45 /* + Sizeof VLAN fields */ 46 #define DPAA2_CLS_RULE_OFFSET_IPV6 25 /* DPAA2_CLS_RULE_OFFSET_IPV4 */ 47 /* + Sizeof IPV4 fields */ 48 #define DPAA2_CLS_RULE_OFFSET_ICMP 58 /* DPAA2_CLS_RULE_OFFSET_IPV6 */ 49 /* + Sizeof IPV6 fields */ 50 #define DPAA2_CLS_RULE_OFFSET_UDP 60 /* DPAA2_CLS_RULE_OFFSET_ICMP */ 51 /* + Sizeof ICMP fields */ 52 #define DPAA2_CLS_RULE_OFFSET_TCP 64 /* DPAA2_CLS_RULE_OFFSET_UDP */ 53 /* + Sizeof UDP fields */ 54 #define DPAA2_CLS_RULE_OFFSET_SCTP 68 /* DPAA2_CLS_RULE_OFFSET_TCP */ 55 /* + Sizeof TCP fields */ 56 #define DPAA2_CLS_RULE_OFFSET_GRE 72 /* DPAA2_CLS_RULE_OFFSET_SCTP */ 57 /* + Sizeof SCTP fields */ 58 59 static const 60 enum rte_flow_item_type dpaa2_supported_pattern_type[] = { 61 RTE_FLOW_ITEM_TYPE_END, 62 RTE_FLOW_ITEM_TYPE_ETH, 63 RTE_FLOW_ITEM_TYPE_VLAN, 64 RTE_FLOW_ITEM_TYPE_IPV4, 65 RTE_FLOW_ITEM_TYPE_IPV6, 66 RTE_FLOW_ITEM_TYPE_ICMP, 67 RTE_FLOW_ITEM_TYPE_UDP, 68 RTE_FLOW_ITEM_TYPE_TCP, 69 RTE_FLOW_ITEM_TYPE_SCTP, 70 RTE_FLOW_ITEM_TYPE_GRE, 71 }; 72 73 static const 74 enum rte_flow_action_type dpaa2_supported_action_type[] = { 75 RTE_FLOW_ACTION_TYPE_END, 76 RTE_FLOW_ACTION_TYPE_QUEUE, 77 RTE_FLOW_ACTION_TYPE_RSS 78 }; 79 80 enum rte_filter_type dpaa2_filter_type = RTE_ETH_FILTER_NONE; 81 static const void *default_mask; 82 83 static int 84 dpaa2_configure_flow_eth(struct rte_flow *flow, 85 struct rte_eth_dev *dev, 86 const struct rte_flow_attr *attr, 87 const struct rte_flow_item *pattern, 88 const struct rte_flow_action actions[] __rte_unused, 89 struct rte_flow_error *error __rte_unused) 90 { 91 int index, j = 0; 92 size_t key_iova; 93 size_t mask_iova; 94 int device_configured = 0, entry_found = 0; 95 uint32_t group; 96 const struct rte_flow_item_eth *spec, *mask; 97 98 /* TODO: Currently upper bound of range parameter is not implemented */ 99 const struct rte_flow_item_eth *last __rte_unused; 100 struct dpaa2_dev_priv *priv = dev->data->dev_private; 101 102 group = attr->group; 103 104 /* DPAA2 platform has a limitation that extract parameter can not be */ 105 /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/ 106 /* TODO: pattern is an array of 9 elements where 9th pattern element */ 107 /* is for QoS table and 1-8th pattern element is for FS tables. */ 108 /* It can be changed to macro. */ 109 if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 110 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 111 DPKG_MAX_NUM_OF_EXTRACTS); 112 return -ENOTSUP; 113 } 114 115 if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 116 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 117 DPKG_MAX_NUM_OF_EXTRACTS); 118 return -ENOTSUP; 119 } 120 121 for (j = 0; j < priv->pattern[8].item_count; j++) { 122 if (priv->pattern[8].pattern_type[j] != pattern->type) { 123 continue; 124 } else { 125 entry_found = 1; 126 break; 127 } 128 } 129 130 if (!entry_found) { 131 priv->pattern[8].pattern_type[j] = pattern->type; 132 priv->pattern[8].item_count++; 133 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; 134 } 135 136 entry_found = 0; 137 for (j = 0; j < priv->pattern[group].item_count; j++) { 138 if (priv->pattern[group].pattern_type[j] != pattern->type) { 139 continue; 140 } else { 141 entry_found = 1; 142 break; 143 } 144 } 145 146 if (!entry_found) { 147 priv->pattern[group].pattern_type[j] = pattern->type; 148 priv->pattern[group].item_count++; 149 device_configured |= DPAA2_FS_TABLE_RECONFIGURE; 150 } 151 152 /* Get traffic class index and flow id to be configured */ 153 flow->tc_id = group; 154 flow->index = attr->priority; 155 156 if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { 157 index = priv->extract.qos_key_cfg.num_extracts; 158 priv->extract.qos_key_cfg.extracts[index].type = 159 DPKG_EXTRACT_FROM_HDR; 160 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 161 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_ETH; 162 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_ETH_SA; 163 index++; 164 165 priv->extract.qos_key_cfg.extracts[index].type = 166 DPKG_EXTRACT_FROM_HDR; 167 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 168 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_ETH; 169 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_ETH_DA; 170 index++; 171 172 priv->extract.qos_key_cfg.extracts[index].type = 173 DPKG_EXTRACT_FROM_HDR; 174 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 175 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_ETH; 176 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_ETH_TYPE; 177 index++; 178 179 priv->extract.qos_key_cfg.num_extracts = index; 180 } 181 182 if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { 183 index = priv->extract.fs_key_cfg[group].num_extracts; 184 priv->extract.fs_key_cfg[group].extracts[index].type = 185 DPKG_EXTRACT_FROM_HDR; 186 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 187 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_ETH; 188 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_ETH_SA; 189 index++; 190 191 priv->extract.fs_key_cfg[group].extracts[index].type = 192 DPKG_EXTRACT_FROM_HDR; 193 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 194 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_ETH; 195 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_ETH_DA; 196 index++; 197 198 priv->extract.fs_key_cfg[group].extracts[index].type = 199 DPKG_EXTRACT_FROM_HDR; 200 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 201 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_ETH; 202 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_ETH_TYPE; 203 index++; 204 205 priv->extract.fs_key_cfg[group].num_extracts = index; 206 } 207 208 /* Parse pattern list to get the matching parameters */ 209 spec = (const struct rte_flow_item_eth *)pattern->spec; 210 last = (const struct rte_flow_item_eth *)pattern->last; 211 mask = (const struct rte_flow_item_eth *) 212 (pattern->mask ? pattern->mask : default_mask); 213 214 /* Key rule */ 215 key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_ETH; 216 memcpy((void *)key_iova, (const void *)(spec->src.addr_bytes), 217 sizeof(struct ether_addr)); 218 key_iova += sizeof(struct ether_addr); 219 memcpy((void *)key_iova, (const void *)(spec->dst.addr_bytes), 220 sizeof(struct ether_addr)); 221 key_iova += sizeof(struct ether_addr); 222 memcpy((void *)key_iova, (const void *)(&spec->type), 223 sizeof(rte_be16_t)); 224 225 /* Key mask */ 226 mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_ETH; 227 memcpy((void *)mask_iova, (const void *)(mask->src.addr_bytes), 228 sizeof(struct ether_addr)); 229 mask_iova += sizeof(struct ether_addr); 230 memcpy((void *)mask_iova, (const void *)(mask->dst.addr_bytes), 231 sizeof(struct ether_addr)); 232 mask_iova += sizeof(struct ether_addr); 233 memcpy((void *)mask_iova, (const void *)(&mask->type), 234 sizeof(rte_be16_t)); 235 236 flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_ETH + 237 ((2 * sizeof(struct ether_addr)) + 238 sizeof(rte_be16_t))); 239 return device_configured; 240 } 241 242 static int 243 dpaa2_configure_flow_vlan(struct rte_flow *flow, 244 struct rte_eth_dev *dev, 245 const struct rte_flow_attr *attr, 246 const struct rte_flow_item *pattern, 247 const struct rte_flow_action actions[] __rte_unused, 248 struct rte_flow_error *error __rte_unused) 249 { 250 int index, j = 0; 251 size_t key_iova; 252 size_t mask_iova; 253 int device_configured = 0, entry_found = 0; 254 uint32_t group; 255 const struct rte_flow_item_vlan *spec, *mask; 256 257 const struct rte_flow_item_vlan *last __rte_unused; 258 struct dpaa2_dev_priv *priv = dev->data->dev_private; 259 260 group = attr->group; 261 262 /* DPAA2 platform has a limitation that extract parameter can not be */ 263 /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/ 264 if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 265 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 266 DPKG_MAX_NUM_OF_EXTRACTS); 267 return -ENOTSUP; 268 } 269 270 if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 271 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 272 DPKG_MAX_NUM_OF_EXTRACTS); 273 return -ENOTSUP; 274 } 275 276 for (j = 0; j < priv->pattern[8].item_count; j++) { 277 if (priv->pattern[8].pattern_type[j] != pattern->type) { 278 continue; 279 } else { 280 entry_found = 1; 281 break; 282 } 283 } 284 285 if (!entry_found) { 286 priv->pattern[8].pattern_type[j] = pattern->type; 287 priv->pattern[8].item_count++; 288 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; 289 } 290 291 entry_found = 0; 292 for (j = 0; j < priv->pattern[group].item_count; j++) { 293 if (priv->pattern[group].pattern_type[j] != pattern->type) { 294 continue; 295 } else { 296 entry_found = 1; 297 break; 298 } 299 } 300 301 if (!entry_found) { 302 priv->pattern[group].pattern_type[j] = pattern->type; 303 priv->pattern[group].item_count++; 304 device_configured |= DPAA2_FS_TABLE_RECONFIGURE; 305 } 306 307 308 /* Get traffic class index and flow id to be configured */ 309 flow->tc_id = group; 310 flow->index = attr->priority; 311 312 if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { 313 index = priv->extract.qos_key_cfg.num_extracts; 314 priv->extract.qos_key_cfg.extracts[index].type = 315 DPKG_EXTRACT_FROM_HDR; 316 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 317 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_VLAN; 318 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_VLAN_TCI; 319 priv->extract.qos_key_cfg.num_extracts++; 320 } 321 322 if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { 323 index = priv->extract.fs_key_cfg[group].num_extracts; 324 priv->extract.fs_key_cfg[group].extracts[index].type = 325 DPKG_EXTRACT_FROM_HDR; 326 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 327 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_VLAN; 328 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_VLAN_TCI; 329 priv->extract.fs_key_cfg[group].num_extracts++; 330 } 331 332 /* Parse pattern list to get the matching parameters */ 333 spec = (const struct rte_flow_item_vlan *)pattern->spec; 334 last = (const struct rte_flow_item_vlan *)pattern->last; 335 mask = (const struct rte_flow_item_vlan *) 336 (pattern->mask ? pattern->mask : default_mask); 337 338 key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_VLAN; 339 memcpy((void *)key_iova, (const void *)(&spec->tci), 340 sizeof(rte_be16_t)); 341 342 mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_VLAN; 343 memcpy((void *)mask_iova, (const void *)(&mask->tci), 344 sizeof(rte_be16_t)); 345 346 flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_VLAN + sizeof(rte_be16_t)); 347 return device_configured; 348 } 349 350 static int 351 dpaa2_configure_flow_ipv4(struct rte_flow *flow, 352 struct rte_eth_dev *dev, 353 const struct rte_flow_attr *attr, 354 const struct rte_flow_item *pattern, 355 const struct rte_flow_action actions[] __rte_unused, 356 struct rte_flow_error *error __rte_unused) 357 { 358 int index, j = 0; 359 size_t key_iova; 360 size_t mask_iova; 361 int device_configured = 0, entry_found = 0; 362 uint32_t group; 363 const struct rte_flow_item_ipv4 *spec, *mask; 364 365 const struct rte_flow_item_ipv4 *last __rte_unused; 366 struct dpaa2_dev_priv *priv = dev->data->dev_private; 367 368 group = attr->group; 369 370 /* DPAA2 platform has a limitation that extract parameter can not be */ 371 /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/ 372 if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 373 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 374 DPKG_MAX_NUM_OF_EXTRACTS); 375 return -ENOTSUP; 376 } 377 378 if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 379 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 380 DPKG_MAX_NUM_OF_EXTRACTS); 381 return -ENOTSUP; 382 } 383 384 for (j = 0; j < priv->pattern[8].item_count; j++) { 385 if (priv->pattern[8].pattern_type[j] != pattern->type) { 386 continue; 387 } else { 388 entry_found = 1; 389 break; 390 } 391 } 392 393 if (!entry_found) { 394 priv->pattern[8].pattern_type[j] = pattern->type; 395 priv->pattern[8].item_count++; 396 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; 397 } 398 399 entry_found = 0; 400 for (j = 0; j < priv->pattern[group].item_count; j++) { 401 if (priv->pattern[group].pattern_type[j] != pattern->type) { 402 continue; 403 } else { 404 entry_found = 1; 405 break; 406 } 407 } 408 409 if (!entry_found) { 410 priv->pattern[group].pattern_type[j] = pattern->type; 411 priv->pattern[group].item_count++; 412 device_configured |= DPAA2_FS_TABLE_RECONFIGURE; 413 } 414 415 /* Get traffic class index and flow id to be configured */ 416 flow->tc_id = group; 417 flow->index = attr->priority; 418 419 if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { 420 index = priv->extract.qos_key_cfg.num_extracts; 421 priv->extract.qos_key_cfg.extracts[index].type = 422 DPKG_EXTRACT_FROM_HDR; 423 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 424 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; 425 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_SRC; 426 index++; 427 428 priv->extract.qos_key_cfg.extracts[index].type = 429 DPKG_EXTRACT_FROM_HDR; 430 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 431 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; 432 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_DST; 433 index++; 434 435 priv->extract.qos_key_cfg.extracts[index].type = 436 DPKG_EXTRACT_FROM_HDR; 437 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 438 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; 439 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; 440 index++; 441 442 priv->extract.qos_key_cfg.num_extracts = index; 443 } 444 445 if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { 446 index = priv->extract.fs_key_cfg[group].num_extracts; 447 priv->extract.fs_key_cfg[group].extracts[index].type = 448 DPKG_EXTRACT_FROM_HDR; 449 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 450 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; 451 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_SRC; 452 index++; 453 454 priv->extract.fs_key_cfg[group].extracts[index].type = 455 DPKG_EXTRACT_FROM_HDR; 456 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 457 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; 458 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_DST; 459 index++; 460 461 priv->extract.fs_key_cfg[group].extracts[index].type = 462 DPKG_EXTRACT_FROM_HDR; 463 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 464 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; 465 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; 466 index++; 467 468 priv->extract.fs_key_cfg[group].num_extracts = index; 469 } 470 471 /* Parse pattern list to get the matching parameters */ 472 spec = (const struct rte_flow_item_ipv4 *)pattern->spec; 473 last = (const struct rte_flow_item_ipv4 *)pattern->last; 474 mask = (const struct rte_flow_item_ipv4 *) 475 (pattern->mask ? pattern->mask : default_mask); 476 477 key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_IPV4; 478 memcpy((void *)key_iova, (const void *)&spec->hdr.src_addr, 479 sizeof(uint32_t)); 480 key_iova += sizeof(uint32_t); 481 memcpy((void *)key_iova, (const void *)&spec->hdr.dst_addr, 482 sizeof(uint32_t)); 483 key_iova += sizeof(uint32_t); 484 memcpy((void *)key_iova, (const void *)&spec->hdr.next_proto_id, 485 sizeof(uint8_t)); 486 487 mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_IPV4; 488 memcpy((void *)mask_iova, (const void *)&mask->hdr.src_addr, 489 sizeof(uint32_t)); 490 mask_iova += sizeof(uint32_t); 491 memcpy((void *)mask_iova, (const void *)&mask->hdr.dst_addr, 492 sizeof(uint32_t)); 493 mask_iova += sizeof(uint32_t); 494 memcpy((void *)mask_iova, (const void *)&mask->hdr.next_proto_id, 495 sizeof(uint8_t)); 496 497 flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_IPV4 + 498 (2 * sizeof(uint32_t)) + sizeof(uint8_t)); 499 500 return device_configured; 501 } 502 503 static int 504 dpaa2_configure_flow_ipv6(struct rte_flow *flow, 505 struct rte_eth_dev *dev, 506 const struct rte_flow_attr *attr, 507 const struct rte_flow_item *pattern, 508 const struct rte_flow_action actions[] __rte_unused, 509 struct rte_flow_error *error __rte_unused) 510 { 511 int index, j = 0; 512 size_t key_iova; 513 size_t mask_iova; 514 int device_configured = 0, entry_found = 0; 515 uint32_t group; 516 const struct rte_flow_item_ipv6 *spec, *mask; 517 518 const struct rte_flow_item_ipv6 *last __rte_unused; 519 struct dpaa2_dev_priv *priv = dev->data->dev_private; 520 521 group = attr->group; 522 523 /* DPAA2 platform has a limitation that extract parameter can not be */ 524 /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/ 525 if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 526 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 527 DPKG_MAX_NUM_OF_EXTRACTS); 528 return -ENOTSUP; 529 } 530 531 if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 532 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 533 DPKG_MAX_NUM_OF_EXTRACTS); 534 return -ENOTSUP; 535 } 536 537 for (j = 0; j < priv->pattern[8].item_count; j++) { 538 if (priv->pattern[8].pattern_type[j] != pattern->type) { 539 continue; 540 } else { 541 entry_found = 1; 542 break; 543 } 544 } 545 546 if (!entry_found) { 547 priv->pattern[8].pattern_type[j] = pattern->type; 548 priv->pattern[8].item_count++; 549 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; 550 } 551 552 entry_found = 0; 553 for (j = 0; j < priv->pattern[group].item_count; j++) { 554 if (priv->pattern[group].pattern_type[j] != pattern->type) { 555 continue; 556 } else { 557 entry_found = 1; 558 break; 559 } 560 } 561 562 if (!entry_found) { 563 priv->pattern[group].pattern_type[j] = pattern->type; 564 priv->pattern[group].item_count++; 565 device_configured |= DPAA2_FS_TABLE_RECONFIGURE; 566 } 567 568 /* Get traffic class index and flow id to be configured */ 569 flow->tc_id = group; 570 flow->index = attr->priority; 571 572 if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { 573 index = priv->extract.qos_key_cfg.num_extracts; 574 priv->extract.qos_key_cfg.extracts[index].type = 575 DPKG_EXTRACT_FROM_HDR; 576 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 577 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; 578 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_SRC; 579 index++; 580 581 priv->extract.qos_key_cfg.extracts[index].type = 582 DPKG_EXTRACT_FROM_HDR; 583 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 584 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; 585 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_DST; 586 index++; 587 588 priv->extract.qos_key_cfg.num_extracts = index; 589 } 590 591 if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { 592 index = priv->extract.fs_key_cfg[group].num_extracts; 593 priv->extract.fs_key_cfg[group].extracts[index].type = 594 DPKG_EXTRACT_FROM_HDR; 595 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 596 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; 597 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_SRC; 598 index++; 599 600 priv->extract.fs_key_cfg[group].extracts[index].type = 601 DPKG_EXTRACT_FROM_HDR; 602 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 603 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; 604 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_DST; 605 index++; 606 607 priv->extract.fs_key_cfg[group].num_extracts = index; 608 } 609 610 /* Parse pattern list to get the matching parameters */ 611 spec = (const struct rte_flow_item_ipv6 *)pattern->spec; 612 last = (const struct rte_flow_item_ipv6 *)pattern->last; 613 mask = (const struct rte_flow_item_ipv6 *) 614 (pattern->mask ? pattern->mask : default_mask); 615 616 key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_IPV6; 617 memcpy((void *)key_iova, (const void *)(spec->hdr.src_addr), 618 sizeof(spec->hdr.src_addr)); 619 key_iova += sizeof(spec->hdr.src_addr); 620 memcpy((void *)key_iova, (const void *)(spec->hdr.dst_addr), 621 sizeof(spec->hdr.dst_addr)); 622 623 mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_IPV6; 624 memcpy((void *)mask_iova, (const void *)(mask->hdr.src_addr), 625 sizeof(mask->hdr.src_addr)); 626 mask_iova += sizeof(mask->hdr.src_addr); 627 memcpy((void *)mask_iova, (const void *)(mask->hdr.dst_addr), 628 sizeof(mask->hdr.dst_addr)); 629 630 flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_IPV6 + 631 sizeof(spec->hdr.src_addr) + 632 sizeof(mask->hdr.dst_addr)); 633 return device_configured; 634 } 635 636 static int 637 dpaa2_configure_flow_icmp(struct rte_flow *flow, 638 struct rte_eth_dev *dev, 639 const struct rte_flow_attr *attr, 640 const struct rte_flow_item *pattern, 641 const struct rte_flow_action actions[] __rte_unused, 642 struct rte_flow_error *error __rte_unused) 643 { 644 int index, j = 0; 645 size_t key_iova; 646 size_t mask_iova; 647 int device_configured = 0, entry_found = 0; 648 uint32_t group; 649 const struct rte_flow_item_icmp *spec, *mask; 650 651 const struct rte_flow_item_icmp *last __rte_unused; 652 struct dpaa2_dev_priv *priv = dev->data->dev_private; 653 654 group = attr->group; 655 656 /* DPAA2 platform has a limitation that extract parameter can not be */ 657 /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/ 658 if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 659 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 660 DPKG_MAX_NUM_OF_EXTRACTS); 661 return -ENOTSUP; 662 } 663 664 if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 665 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 666 DPKG_MAX_NUM_OF_EXTRACTS); 667 return -ENOTSUP; 668 } 669 670 for (j = 0; j < priv->pattern[8].item_count; j++) { 671 if (priv->pattern[8].pattern_type[j] != pattern->type) { 672 continue; 673 } else { 674 entry_found = 1; 675 break; 676 } 677 } 678 679 if (!entry_found) { 680 priv->pattern[8].pattern_type[j] = pattern->type; 681 priv->pattern[8].item_count++; 682 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; 683 } 684 685 entry_found = 0; 686 for (j = 0; j < priv->pattern[group].item_count; j++) { 687 if (priv->pattern[group].pattern_type[j] != pattern->type) { 688 continue; 689 } else { 690 entry_found = 1; 691 break; 692 } 693 } 694 695 if (!entry_found) { 696 priv->pattern[group].pattern_type[j] = pattern->type; 697 priv->pattern[group].item_count++; 698 device_configured |= DPAA2_FS_TABLE_RECONFIGURE; 699 } 700 701 /* Get traffic class index and flow id to be configured */ 702 flow->tc_id = group; 703 flow->index = attr->priority; 704 705 if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { 706 index = priv->extract.qos_key_cfg.num_extracts; 707 priv->extract.qos_key_cfg.extracts[index].type = 708 DPKG_EXTRACT_FROM_HDR; 709 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 710 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_ICMP; 711 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_ICMP_TYPE; 712 index++; 713 714 priv->extract.qos_key_cfg.extracts[index].type = 715 DPKG_EXTRACT_FROM_HDR; 716 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 717 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_ICMP; 718 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_ICMP_CODE; 719 index++; 720 721 priv->extract.qos_key_cfg.num_extracts = index; 722 } 723 724 if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { 725 index = priv->extract.fs_key_cfg[group].num_extracts; 726 priv->extract.fs_key_cfg[group].extracts[index].type = 727 DPKG_EXTRACT_FROM_HDR; 728 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 729 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_ICMP; 730 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_ICMP_TYPE; 731 index++; 732 733 priv->extract.fs_key_cfg[group].extracts[index].type = 734 DPKG_EXTRACT_FROM_HDR; 735 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 736 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_ICMP; 737 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_ICMP_CODE; 738 index++; 739 740 priv->extract.fs_key_cfg[group].num_extracts = index; 741 } 742 743 /* Parse pattern list to get the matching parameters */ 744 spec = (const struct rte_flow_item_icmp *)pattern->spec; 745 last = (const struct rte_flow_item_icmp *)pattern->last; 746 mask = (const struct rte_flow_item_icmp *) 747 (pattern->mask ? pattern->mask : default_mask); 748 749 key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_ICMP; 750 memcpy((void *)key_iova, (const void *)&spec->hdr.icmp_type, 751 sizeof(uint8_t)); 752 key_iova += sizeof(uint8_t); 753 memcpy((void *)key_iova, (const void *)&spec->hdr.icmp_code, 754 sizeof(uint8_t)); 755 756 mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_ICMP; 757 memcpy((void *)mask_iova, (const void *)&mask->hdr.icmp_type, 758 sizeof(uint8_t)); 759 key_iova += sizeof(uint8_t); 760 memcpy((void *)mask_iova, (const void *)&mask->hdr.icmp_code, 761 sizeof(uint8_t)); 762 763 flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_ICMP + 764 (2 * sizeof(uint8_t))); 765 766 return device_configured; 767 } 768 769 static int 770 dpaa2_configure_flow_udp(struct rte_flow *flow, 771 struct rte_eth_dev *dev, 772 const struct rte_flow_attr *attr, 773 const struct rte_flow_item *pattern, 774 const struct rte_flow_action actions[] __rte_unused, 775 struct rte_flow_error *error __rte_unused) 776 { 777 int index, j = 0; 778 size_t key_iova; 779 size_t mask_iova; 780 int device_configured = 0, entry_found = 0; 781 uint32_t group; 782 const struct rte_flow_item_udp *spec, *mask; 783 784 const struct rte_flow_item_udp *last __rte_unused; 785 struct dpaa2_dev_priv *priv = dev->data->dev_private; 786 787 group = attr->group; 788 789 /* DPAA2 platform has a limitation that extract parameter can not be */ 790 /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/ 791 if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 792 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 793 DPKG_MAX_NUM_OF_EXTRACTS); 794 return -ENOTSUP; 795 } 796 797 if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 798 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 799 DPKG_MAX_NUM_OF_EXTRACTS); 800 return -ENOTSUP; 801 } 802 803 for (j = 0; j < priv->pattern[8].item_count; j++) { 804 if (priv->pattern[8].pattern_type[j] != pattern->type) { 805 continue; 806 } else { 807 entry_found = 1; 808 break; 809 } 810 } 811 812 if (!entry_found) { 813 priv->pattern[8].pattern_type[j] = pattern->type; 814 priv->pattern[8].item_count++; 815 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; 816 } 817 818 entry_found = 0; 819 for (j = 0; j < priv->pattern[group].item_count; j++) { 820 if (priv->pattern[group].pattern_type[j] != pattern->type) { 821 continue; 822 } else { 823 entry_found = 1; 824 break; 825 } 826 } 827 828 if (!entry_found) { 829 priv->pattern[group].pattern_type[j] = pattern->type; 830 priv->pattern[group].item_count++; 831 device_configured |= DPAA2_FS_TABLE_RECONFIGURE; 832 } 833 834 /* Get traffic class index and flow id to be configured */ 835 flow->tc_id = group; 836 flow->index = attr->priority; 837 838 if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { 839 index = priv->extract.qos_key_cfg.num_extracts; 840 priv->extract.qos_key_cfg.extracts[index].type = 841 DPKG_EXTRACT_FROM_HDR; 842 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 843 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; 844 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; 845 index++; 846 847 priv->extract.qos_key_cfg.extracts[index].type = 848 DPKG_EXTRACT_FROM_HDR; 849 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 850 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_UDP; 851 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_UDP_PORT_SRC; 852 index++; 853 854 priv->extract.qos_key_cfg.extracts[index].type = DPKG_EXTRACT_FROM_HDR; 855 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 856 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_UDP; 857 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_UDP_PORT_DST; 858 index++; 859 860 priv->extract.qos_key_cfg.num_extracts = index; 861 } 862 863 if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { 864 index = priv->extract.fs_key_cfg[group].num_extracts; 865 priv->extract.fs_key_cfg[group].extracts[index].type = 866 DPKG_EXTRACT_FROM_HDR; 867 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 868 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; 869 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; 870 index++; 871 872 priv->extract.fs_key_cfg[group].extracts[index].type = 873 DPKG_EXTRACT_FROM_HDR; 874 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 875 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_UDP; 876 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_UDP_PORT_SRC; 877 index++; 878 879 priv->extract.fs_key_cfg[group].extracts[index].type = 880 DPKG_EXTRACT_FROM_HDR; 881 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 882 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_UDP; 883 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_UDP_PORT_DST; 884 index++; 885 886 priv->extract.fs_key_cfg[group].num_extracts = index; 887 } 888 889 /* Parse pattern list to get the matching parameters */ 890 spec = (const struct rte_flow_item_udp *)pattern->spec; 891 last = (const struct rte_flow_item_udp *)pattern->last; 892 mask = (const struct rte_flow_item_udp *) 893 (pattern->mask ? pattern->mask : default_mask); 894 895 key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_IPV4 + 896 (2 * sizeof(uint32_t)); 897 memset((void *)key_iova, 0x11, sizeof(uint8_t)); 898 key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_UDP; 899 memcpy((void *)key_iova, (const void *)(&spec->hdr.src_port), 900 sizeof(uint16_t)); 901 key_iova += sizeof(uint16_t); 902 memcpy((void *)key_iova, (const void *)(&spec->hdr.dst_port), 903 sizeof(uint16_t)); 904 905 mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_UDP; 906 memcpy((void *)mask_iova, (const void *)(&mask->hdr.src_port), 907 sizeof(uint16_t)); 908 mask_iova += sizeof(uint16_t); 909 memcpy((void *)mask_iova, (const void *)(&mask->hdr.dst_port), 910 sizeof(uint16_t)); 911 912 flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_UDP + 913 (2 * sizeof(uint16_t))); 914 915 return device_configured; 916 } 917 918 static int 919 dpaa2_configure_flow_tcp(struct rte_flow *flow, 920 struct rte_eth_dev *dev, 921 const struct rte_flow_attr *attr, 922 const struct rte_flow_item *pattern, 923 const struct rte_flow_action actions[] __rte_unused, 924 struct rte_flow_error *error __rte_unused) 925 { 926 int index, j = 0; 927 size_t key_iova; 928 size_t mask_iova; 929 int device_configured = 0, entry_found = 0; 930 uint32_t group; 931 const struct rte_flow_item_tcp *spec, *mask; 932 933 const struct rte_flow_item_tcp *last __rte_unused; 934 struct dpaa2_dev_priv *priv = dev->data->dev_private; 935 936 group = attr->group; 937 938 /* DPAA2 platform has a limitation that extract parameter can not be */ 939 /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too.*/ 940 if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 941 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 942 DPKG_MAX_NUM_OF_EXTRACTS); 943 return -ENOTSUP; 944 } 945 946 if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 947 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 948 DPKG_MAX_NUM_OF_EXTRACTS); 949 return -ENOTSUP; 950 } 951 952 for (j = 0; j < priv->pattern[8].item_count; j++) { 953 if (priv->pattern[8].pattern_type[j] != pattern->type) { 954 continue; 955 } else { 956 entry_found = 1; 957 break; 958 } 959 } 960 961 if (!entry_found) { 962 priv->pattern[8].pattern_type[j] = pattern->type; 963 priv->pattern[8].item_count++; 964 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; 965 } 966 967 entry_found = 0; 968 for (j = 0; j < priv->pattern[group].item_count; j++) { 969 if (priv->pattern[group].pattern_type[j] != pattern->type) { 970 continue; 971 } else { 972 entry_found = 1; 973 break; 974 } 975 } 976 977 if (!entry_found) { 978 priv->pattern[group].pattern_type[j] = pattern->type; 979 priv->pattern[group].item_count++; 980 device_configured |= DPAA2_FS_TABLE_RECONFIGURE; 981 } 982 983 /* Get traffic class index and flow id to be configured */ 984 flow->tc_id = group; 985 flow->index = attr->priority; 986 987 if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { 988 index = priv->extract.qos_key_cfg.num_extracts; 989 priv->extract.qos_key_cfg.extracts[index].type = 990 DPKG_EXTRACT_FROM_HDR; 991 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 992 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; 993 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; 994 index++; 995 996 priv->extract.qos_key_cfg.extracts[index].type = 997 DPKG_EXTRACT_FROM_HDR; 998 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 999 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_TCP; 1000 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_TCP_PORT_SRC; 1001 index++; 1002 1003 priv->extract.qos_key_cfg.extracts[index].type = 1004 DPKG_EXTRACT_FROM_HDR; 1005 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 1006 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_TCP; 1007 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_TCP_PORT_DST; 1008 index++; 1009 1010 priv->extract.qos_key_cfg.num_extracts = index; 1011 } 1012 1013 if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { 1014 index = priv->extract.fs_key_cfg[group].num_extracts; 1015 priv->extract.fs_key_cfg[group].extracts[index].type = 1016 DPKG_EXTRACT_FROM_HDR; 1017 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 1018 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; 1019 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; 1020 index++; 1021 1022 priv->extract.fs_key_cfg[group].extracts[index].type = 1023 DPKG_EXTRACT_FROM_HDR; 1024 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 1025 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_TCP; 1026 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_TCP_PORT_SRC; 1027 index++; 1028 1029 priv->extract.fs_key_cfg[group].extracts[index].type = 1030 DPKG_EXTRACT_FROM_HDR; 1031 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 1032 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_TCP; 1033 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_TCP_PORT_DST; 1034 index++; 1035 1036 priv->extract.fs_key_cfg[group].num_extracts = index; 1037 } 1038 1039 /* Parse pattern list to get the matching parameters */ 1040 spec = (const struct rte_flow_item_tcp *)pattern->spec; 1041 last = (const struct rte_flow_item_tcp *)pattern->last; 1042 mask = (const struct rte_flow_item_tcp *) 1043 (pattern->mask ? pattern->mask : default_mask); 1044 1045 key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_IPV4 + 1046 (2 * sizeof(uint32_t)); 1047 memset((void *)key_iova, 0x06, sizeof(uint8_t)); 1048 key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_TCP; 1049 memcpy((void *)key_iova, (const void *)(&spec->hdr.src_port), 1050 sizeof(uint16_t)); 1051 key_iova += sizeof(uint16_t); 1052 memcpy((void *)key_iova, (const void *)(&spec->hdr.dst_port), 1053 sizeof(uint16_t)); 1054 1055 mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_TCP; 1056 memcpy((void *)mask_iova, (const void *)(&mask->hdr.src_port), 1057 sizeof(uint16_t)); 1058 mask_iova += sizeof(uint16_t); 1059 memcpy((void *)mask_iova, (const void *)(&mask->hdr.dst_port), 1060 sizeof(uint16_t)); 1061 1062 flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_TCP + 1063 (2 * sizeof(uint16_t))); 1064 1065 return device_configured; 1066 } 1067 1068 static int 1069 dpaa2_configure_flow_sctp(struct rte_flow *flow, 1070 struct rte_eth_dev *dev, 1071 const struct rte_flow_attr *attr, 1072 const struct rte_flow_item *pattern, 1073 const struct rte_flow_action actions[] __rte_unused, 1074 struct rte_flow_error *error __rte_unused) 1075 { 1076 int index, j = 0; 1077 size_t key_iova; 1078 size_t mask_iova; 1079 int device_configured = 0, entry_found = 0; 1080 uint32_t group; 1081 const struct rte_flow_item_sctp *spec, *mask; 1082 1083 const struct rte_flow_item_sctp *last __rte_unused; 1084 struct dpaa2_dev_priv *priv = dev->data->dev_private; 1085 1086 group = attr->group; 1087 1088 /* DPAA2 platform has a limitation that extract parameter can not be */ 1089 /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too. */ 1090 if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 1091 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 1092 DPKG_MAX_NUM_OF_EXTRACTS); 1093 return -ENOTSUP; 1094 } 1095 1096 if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 1097 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 1098 DPKG_MAX_NUM_OF_EXTRACTS); 1099 return -ENOTSUP; 1100 } 1101 1102 for (j = 0; j < priv->pattern[8].item_count; j++) { 1103 if (priv->pattern[8].pattern_type[j] != pattern->type) { 1104 continue; 1105 } else { 1106 entry_found = 1; 1107 break; 1108 } 1109 } 1110 1111 if (!entry_found) { 1112 priv->pattern[8].pattern_type[j] = pattern->type; 1113 priv->pattern[8].item_count++; 1114 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; 1115 } 1116 1117 entry_found = 0; 1118 for (j = 0; j < priv->pattern[group].item_count; j++) { 1119 if (priv->pattern[group].pattern_type[j] != pattern->type) { 1120 continue; 1121 } else { 1122 entry_found = 1; 1123 break; 1124 } 1125 } 1126 1127 if (!entry_found) { 1128 priv->pattern[group].pattern_type[j] = pattern->type; 1129 priv->pattern[group].item_count++; 1130 device_configured |= DPAA2_FS_TABLE_RECONFIGURE; 1131 } 1132 1133 /* Get traffic class index and flow id to be configured */ 1134 flow->tc_id = group; 1135 flow->index = attr->priority; 1136 1137 if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { 1138 index = priv->extract.qos_key_cfg.num_extracts; 1139 priv->extract.qos_key_cfg.extracts[index].type = 1140 DPKG_EXTRACT_FROM_HDR; 1141 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 1142 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_IP; 1143 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; 1144 index++; 1145 1146 priv->extract.qos_key_cfg.extracts[index].type = 1147 DPKG_EXTRACT_FROM_HDR; 1148 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 1149 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_SCTP; 1150 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_SCTP_PORT_SRC; 1151 index++; 1152 1153 priv->extract.qos_key_cfg.extracts[index].type = 1154 DPKG_EXTRACT_FROM_HDR; 1155 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 1156 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_SCTP; 1157 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_SCTP_PORT_DST; 1158 index++; 1159 1160 priv->extract.qos_key_cfg.num_extracts = index; 1161 } 1162 1163 if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { 1164 index = priv->extract.fs_key_cfg[group].num_extracts; 1165 priv->extract.fs_key_cfg[group].extracts[index].type = 1166 DPKG_EXTRACT_FROM_HDR; 1167 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 1168 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_IP; 1169 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_IP_PROTO; 1170 index++; 1171 1172 priv->extract.fs_key_cfg[group].extracts[index].type = 1173 DPKG_EXTRACT_FROM_HDR; 1174 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 1175 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_SCTP; 1176 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_SCTP_PORT_SRC; 1177 index++; 1178 1179 priv->extract.fs_key_cfg[group].extracts[index].type = 1180 DPKG_EXTRACT_FROM_HDR; 1181 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 1182 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_SCTP; 1183 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_SCTP_PORT_DST; 1184 index++; 1185 1186 priv->extract.fs_key_cfg[group].num_extracts = index; 1187 } 1188 1189 /* Parse pattern list to get the matching parameters */ 1190 spec = (const struct rte_flow_item_sctp *)pattern->spec; 1191 last = (const struct rte_flow_item_sctp *)pattern->last; 1192 mask = (const struct rte_flow_item_sctp *) 1193 (pattern->mask ? pattern->mask : default_mask); 1194 1195 key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_IPV4 + 1196 (2 * sizeof(uint32_t)); 1197 memset((void *)key_iova, 0x84, sizeof(uint8_t)); 1198 key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_SCTP; 1199 memcpy((void *)key_iova, (const void *)(&spec->hdr.src_port), 1200 sizeof(uint16_t)); 1201 key_iova += sizeof(uint16_t); 1202 memcpy((void *)key_iova, (const void *)(&spec->hdr.dst_port), 1203 sizeof(uint16_t)); 1204 1205 mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_SCTP; 1206 memcpy((void *)mask_iova, (const void *)(&mask->hdr.src_port), 1207 sizeof(uint16_t)); 1208 mask_iova += sizeof(uint16_t); 1209 memcpy((void *)mask_iova, (const void *)(&mask->hdr.dst_port), 1210 sizeof(uint16_t)); 1211 1212 flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_SCTP + 1213 (2 * sizeof(uint16_t))); 1214 return device_configured; 1215 } 1216 1217 static int 1218 dpaa2_configure_flow_gre(struct rte_flow *flow, 1219 struct rte_eth_dev *dev, 1220 const struct rte_flow_attr *attr, 1221 const struct rte_flow_item *pattern, 1222 const struct rte_flow_action actions[] __rte_unused, 1223 struct rte_flow_error *error __rte_unused) 1224 { 1225 int index, j = 0; 1226 size_t key_iova; 1227 size_t mask_iova; 1228 int device_configured = 0, entry_found = 0; 1229 uint32_t group; 1230 const struct rte_flow_item_gre *spec, *mask; 1231 1232 const struct rte_flow_item_gre *last __rte_unused; 1233 struct dpaa2_dev_priv *priv = dev->data->dev_private; 1234 1235 group = attr->group; 1236 1237 /* DPAA2 platform has a limitation that extract parameter can not be */ 1238 /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too. */ 1239 if (priv->pattern[8].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 1240 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 1241 DPKG_MAX_NUM_OF_EXTRACTS); 1242 return -ENOTSUP; 1243 } 1244 1245 if (priv->pattern[group].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) { 1246 DPAA2_PMD_ERR("Maximum limit for different pattern type = %d\n", 1247 DPKG_MAX_NUM_OF_EXTRACTS); 1248 return -ENOTSUP; 1249 } 1250 1251 for (j = 0; j < priv->pattern[8].item_count; j++) { 1252 if (priv->pattern[8].pattern_type[j] != pattern->type) { 1253 continue; 1254 } else { 1255 entry_found = 1; 1256 break; 1257 } 1258 } 1259 1260 if (!entry_found) { 1261 priv->pattern[8].pattern_type[j] = pattern->type; 1262 priv->pattern[8].item_count++; 1263 device_configured |= DPAA2_QOS_TABLE_RECONFIGURE; 1264 } 1265 1266 entry_found = 0; 1267 for (j = 0; j < priv->pattern[group].item_count; j++) { 1268 if (priv->pattern[group].pattern_type[j] != pattern->type) { 1269 continue; 1270 } else { 1271 entry_found = 1; 1272 break; 1273 } 1274 } 1275 1276 if (!entry_found) { 1277 priv->pattern[group].pattern_type[j] = pattern->type; 1278 priv->pattern[group].item_count++; 1279 device_configured |= DPAA2_FS_TABLE_RECONFIGURE; 1280 } 1281 1282 /* Get traffic class index and flow id to be configured */ 1283 flow->tc_id = group; 1284 flow->index = attr->priority; 1285 1286 if (device_configured & DPAA2_QOS_TABLE_RECONFIGURE) { 1287 index = priv->extract.qos_key_cfg.num_extracts; 1288 priv->extract.qos_key_cfg.extracts[index].type = 1289 DPKG_EXTRACT_FROM_HDR; 1290 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 1291 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.prot = NET_PROT_GRE; 1292 priv->extract.qos_key_cfg.extracts[index].extract.from_hdr.field = NH_FLD_GRE_TYPE; 1293 index++; 1294 1295 priv->extract.qos_key_cfg.num_extracts = index; 1296 } 1297 1298 if (device_configured & DPAA2_FS_TABLE_RECONFIGURE) { 1299 index = priv->extract.fs_key_cfg[group].num_extracts; 1300 priv->extract.fs_key_cfg[group].extracts[index].type = 1301 DPKG_EXTRACT_FROM_HDR; 1302 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.type = DPKG_FULL_FIELD; 1303 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.prot = NET_PROT_GRE; 1304 priv->extract.fs_key_cfg[group].extracts[index].extract.from_hdr.field = NH_FLD_GRE_TYPE; 1305 index++; 1306 1307 priv->extract.fs_key_cfg[group].num_extracts = index; 1308 } 1309 1310 /* Parse pattern list to get the matching parameters */ 1311 spec = (const struct rte_flow_item_gre *)pattern->spec; 1312 last = (const struct rte_flow_item_gre *)pattern->last; 1313 mask = (const struct rte_flow_item_gre *) 1314 (pattern->mask ? pattern->mask : default_mask); 1315 1316 key_iova = flow->rule.key_iova + DPAA2_CLS_RULE_OFFSET_GRE; 1317 memcpy((void *)key_iova, (const void *)(&spec->protocol), 1318 sizeof(rte_be16_t)); 1319 1320 mask_iova = flow->rule.mask_iova + DPAA2_CLS_RULE_OFFSET_GRE; 1321 memcpy((void *)mask_iova, (const void *)(&mask->protocol), 1322 sizeof(rte_be16_t)); 1323 1324 flow->rule.key_size = (DPAA2_CLS_RULE_OFFSET_GRE + sizeof(rte_be16_t)); 1325 1326 return device_configured; 1327 } 1328 1329 static int 1330 dpaa2_generic_flow_set(struct rte_flow *flow, 1331 struct rte_eth_dev *dev, 1332 const struct rte_flow_attr *attr, 1333 const struct rte_flow_item pattern[], 1334 const struct rte_flow_action actions[], 1335 struct rte_flow_error *error) 1336 { 1337 const struct rte_flow_action_queue *dest_queue; 1338 const struct rte_flow_action_rss *rss_conf; 1339 uint16_t index; 1340 int is_keycfg_configured = 0, end_of_list = 0; 1341 int ret = 0, i = 0, j = 0; 1342 struct dpni_attr nic_attr; 1343 struct dpni_rx_tc_dist_cfg tc_cfg; 1344 struct dpni_qos_tbl_cfg qos_cfg; 1345 struct dpkg_profile_cfg key_cfg; 1346 struct dpni_fs_action_cfg action; 1347 struct dpaa2_dev_priv *priv = dev->data->dev_private; 1348 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 1349 size_t param; 1350 1351 /* Parse pattern list to get the matching parameters */ 1352 while (!end_of_list) { 1353 switch (pattern[i].type) { 1354 case RTE_FLOW_ITEM_TYPE_ETH: 1355 is_keycfg_configured = dpaa2_configure_flow_eth(flow, 1356 dev, 1357 attr, 1358 &pattern[i], 1359 actions, 1360 error); 1361 break; 1362 case RTE_FLOW_ITEM_TYPE_VLAN: 1363 is_keycfg_configured = dpaa2_configure_flow_vlan(flow, 1364 dev, 1365 attr, 1366 &pattern[i], 1367 actions, 1368 error); 1369 break; 1370 case RTE_FLOW_ITEM_TYPE_IPV4: 1371 is_keycfg_configured = dpaa2_configure_flow_ipv4(flow, 1372 dev, 1373 attr, 1374 &pattern[i], 1375 actions, 1376 error); 1377 break; 1378 case RTE_FLOW_ITEM_TYPE_IPV6: 1379 is_keycfg_configured = dpaa2_configure_flow_ipv6(flow, 1380 dev, 1381 attr, 1382 &pattern[i], 1383 actions, 1384 error); 1385 break; 1386 case RTE_FLOW_ITEM_TYPE_ICMP: 1387 is_keycfg_configured = dpaa2_configure_flow_icmp(flow, 1388 dev, 1389 attr, 1390 &pattern[i], 1391 actions, 1392 error); 1393 break; 1394 case RTE_FLOW_ITEM_TYPE_UDP: 1395 is_keycfg_configured = dpaa2_configure_flow_udp(flow, 1396 dev, 1397 attr, 1398 &pattern[i], 1399 actions, 1400 error); 1401 break; 1402 case RTE_FLOW_ITEM_TYPE_TCP: 1403 is_keycfg_configured = dpaa2_configure_flow_tcp(flow, 1404 dev, 1405 attr, 1406 &pattern[i], 1407 actions, 1408 error); 1409 break; 1410 case RTE_FLOW_ITEM_TYPE_SCTP: 1411 is_keycfg_configured = dpaa2_configure_flow_sctp(flow, 1412 dev, attr, 1413 &pattern[i], 1414 actions, 1415 error); 1416 break; 1417 case RTE_FLOW_ITEM_TYPE_GRE: 1418 is_keycfg_configured = dpaa2_configure_flow_gre(flow, 1419 dev, 1420 attr, 1421 &pattern[i], 1422 actions, 1423 error); 1424 break; 1425 case RTE_FLOW_ITEM_TYPE_END: 1426 end_of_list = 1; 1427 break; /*End of List*/ 1428 default: 1429 DPAA2_PMD_ERR("Invalid action type"); 1430 ret = -ENOTSUP; 1431 break; 1432 } 1433 i++; 1434 } 1435 1436 /* Let's parse action on matching traffic */ 1437 end_of_list = 0; 1438 while (!end_of_list) { 1439 switch (actions[j].type) { 1440 case RTE_FLOW_ACTION_TYPE_QUEUE: 1441 dest_queue = (const struct rte_flow_action_queue *)(actions[j].conf); 1442 flow->flow_id = dest_queue->index; 1443 flow->action = RTE_FLOW_ACTION_TYPE_QUEUE; 1444 memset(&action, 0, sizeof(struct dpni_fs_action_cfg)); 1445 action.flow_id = flow->flow_id; 1446 if (is_keycfg_configured & DPAA2_QOS_TABLE_RECONFIGURE) { 1447 if (dpkg_prepare_key_cfg(&priv->extract.qos_key_cfg, 1448 (uint8_t *)(size_t)priv->extract.qos_extract_param) < 0) { 1449 DPAA2_PMD_ERR( 1450 "Unable to prepare extract parameters"); 1451 return -1; 1452 } 1453 1454 memset(&qos_cfg, 0, sizeof(struct dpni_qos_tbl_cfg)); 1455 qos_cfg.discard_on_miss = true; 1456 qos_cfg.keep_entries = true; 1457 qos_cfg.key_cfg_iova = (size_t)priv->extract.qos_extract_param; 1458 ret = dpni_set_qos_table(dpni, CMD_PRI_LOW, 1459 priv->token, &qos_cfg); 1460 if (ret < 0) { 1461 DPAA2_PMD_ERR( 1462 "Distribution cannot be configured.(%d)" 1463 , ret); 1464 return -1; 1465 } 1466 } 1467 if (is_keycfg_configured & DPAA2_FS_TABLE_RECONFIGURE) { 1468 if (dpkg_prepare_key_cfg(&priv->extract.fs_key_cfg[flow->tc_id], 1469 (uint8_t *)(size_t)priv->extract.fs_extract_param[flow->tc_id]) < 0) { 1470 DPAA2_PMD_ERR( 1471 "Unable to prepare extract parameters"); 1472 return -1; 1473 } 1474 1475 memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg)); 1476 tc_cfg.dist_size = priv->nb_rx_queues / priv->num_rx_tc; 1477 tc_cfg.dist_mode = DPNI_DIST_MODE_FS; 1478 tc_cfg.key_cfg_iova = 1479 (uint64_t)priv->extract.fs_extract_param[flow->tc_id]; 1480 tc_cfg.fs_cfg.miss_action = DPNI_FS_MISS_DROP; 1481 tc_cfg.fs_cfg.keep_entries = true; 1482 ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW, 1483 priv->token, 1484 flow->tc_id, &tc_cfg); 1485 if (ret < 0) { 1486 DPAA2_PMD_ERR( 1487 "Distribution cannot be configured.(%d)" 1488 , ret); 1489 return -1; 1490 } 1491 } 1492 /* Configure QoS table first */ 1493 memset(&nic_attr, 0, sizeof(struct dpni_attr)); 1494 ret = dpni_get_attributes(dpni, CMD_PRI_LOW, 1495 priv->token, &nic_attr); 1496 if (ret < 0) { 1497 DPAA2_PMD_ERR( 1498 "Failure to get attribute. dpni@%p err code(%d)\n", 1499 dpni, ret); 1500 return ret; 1501 } 1502 1503 action.flow_id = action.flow_id % nic_attr.num_rx_tcs; 1504 index = flow->index + (flow->tc_id * nic_attr.fs_entries); 1505 ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW, 1506 priv->token, &flow->rule, 1507 flow->tc_id, index); 1508 if (ret < 0) { 1509 DPAA2_PMD_ERR( 1510 "Error in addnig entry to QoS table(%d)", ret); 1511 return ret; 1512 } 1513 1514 /* Then Configure FS table */ 1515 ret = dpni_add_fs_entry(dpni, CMD_PRI_LOW, priv->token, 1516 flow->tc_id, flow->index, 1517 &flow->rule, &action); 1518 if (ret < 0) { 1519 DPAA2_PMD_ERR( 1520 "Error in adding entry to FS table(%d)", ret); 1521 return ret; 1522 } 1523 break; 1524 case RTE_FLOW_ACTION_TYPE_RSS: 1525 ret = dpni_get_attributes(dpni, CMD_PRI_LOW, 1526 priv->token, &nic_attr); 1527 if (ret < 0) { 1528 DPAA2_PMD_ERR( 1529 "Failure to get attribute. dpni@%p err code(%d)\n", 1530 dpni, ret); 1531 return ret; 1532 } 1533 rss_conf = (const struct rte_flow_action_rss *)(actions[j].conf); 1534 for (i = 0; i < (int)rss_conf->queue_num; i++) { 1535 if (rss_conf->queue[i] < (attr->group * nic_attr.num_queues) || 1536 rss_conf->queue[i] >= ((attr->group + 1) * nic_attr.num_queues)) { 1537 DPAA2_PMD_ERR( 1538 "Queue/Group combination are not supported\n"); 1539 return -ENOTSUP; 1540 } 1541 } 1542 1543 flow->action = RTE_FLOW_ACTION_TYPE_RSS; 1544 ret = dpaa2_distset_to_dpkg_profile_cfg(rss_conf->types, 1545 &key_cfg); 1546 if (ret < 0) { 1547 DPAA2_PMD_ERR( 1548 "unable to set flow distribution.please check queue config\n"); 1549 return ret; 1550 } 1551 1552 /* Allocate DMA'ble memory to write the rules */ 1553 param = (size_t)rte_malloc(NULL, 256, 64); 1554 if (!param) { 1555 DPAA2_PMD_ERR("Memory allocation failure\n"); 1556 return -1; 1557 } 1558 1559 if (dpkg_prepare_key_cfg(&key_cfg, (uint8_t *)param) < 0) { 1560 DPAA2_PMD_ERR( 1561 "Unable to prepare extract parameters"); 1562 rte_free((void *)param); 1563 return -1; 1564 } 1565 1566 memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg)); 1567 tc_cfg.dist_size = rss_conf->queue_num; 1568 tc_cfg.dist_mode = DPNI_DIST_MODE_HASH; 1569 tc_cfg.key_cfg_iova = (size_t)param; 1570 tc_cfg.fs_cfg.miss_action = DPNI_FS_MISS_DROP; 1571 1572 ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW, 1573 priv->token, flow->tc_id, 1574 &tc_cfg); 1575 if (ret < 0) { 1576 DPAA2_PMD_ERR( 1577 "Distribution cannot be configured: %d\n", ret); 1578 rte_free((void *)param); 1579 return -1; 1580 } 1581 1582 rte_free((void *)param); 1583 if (is_keycfg_configured & DPAA2_FS_TABLE_RECONFIGURE) { 1584 if (dpkg_prepare_key_cfg(&priv->extract.qos_key_cfg, 1585 (uint8_t *)(size_t)priv->extract.qos_extract_param) < 0) { 1586 DPAA2_PMD_ERR( 1587 "Unable to prepare extract parameters"); 1588 return -1; 1589 } 1590 memset(&qos_cfg, 0, 1591 sizeof(struct dpni_qos_tbl_cfg)); 1592 qos_cfg.discard_on_miss = true; 1593 qos_cfg.keep_entries = true; 1594 qos_cfg.key_cfg_iova = (size_t)priv->extract.qos_extract_param; 1595 ret = dpni_set_qos_table(dpni, CMD_PRI_LOW, 1596 priv->token, &qos_cfg); 1597 if (ret < 0) { 1598 DPAA2_PMD_ERR( 1599 "Distribution can not be configured(%d)\n", 1600 ret); 1601 return -1; 1602 } 1603 } 1604 1605 /* Add Rule into QoS table */ 1606 index = flow->index + (flow->tc_id * nic_attr.fs_entries); 1607 ret = dpni_add_qos_entry(dpni, CMD_PRI_LOW, priv->token, 1608 &flow->rule, flow->tc_id, 1609 index); 1610 if (ret < 0) { 1611 DPAA2_PMD_ERR( 1612 "Error in entry addition in QoS table(%d)", 1613 ret); 1614 return ret; 1615 } 1616 break; 1617 case RTE_FLOW_ACTION_TYPE_END: 1618 end_of_list = 1; 1619 break; 1620 default: 1621 DPAA2_PMD_ERR("Invalid action type"); 1622 ret = -ENOTSUP; 1623 break; 1624 } 1625 j++; 1626 } 1627 1628 return ret; 1629 } 1630 1631 static inline int 1632 dpaa2_dev_verify_attr(struct dpni_attr *dpni_attr, 1633 const struct rte_flow_attr *attr) 1634 { 1635 int ret = 0; 1636 1637 if (unlikely(attr->group >= dpni_attr->num_rx_tcs)) { 1638 DPAA2_PMD_ERR("Priority group is out of range\n"); 1639 ret = -ENOTSUP; 1640 } 1641 if (unlikely(attr->priority >= dpni_attr->fs_entries)) { 1642 DPAA2_PMD_ERR("Priority within the group is out of range\n"); 1643 ret = -ENOTSUP; 1644 } 1645 if (unlikely(attr->egress)) { 1646 DPAA2_PMD_ERR( 1647 "Flow configuration is not supported on egress side\n"); 1648 ret = -ENOTSUP; 1649 } 1650 if (unlikely(!attr->ingress)) { 1651 DPAA2_PMD_ERR("Ingress flag must be configured\n"); 1652 ret = -EINVAL; 1653 } 1654 return ret; 1655 } 1656 1657 static inline void 1658 dpaa2_dev_update_default_mask(const struct rte_flow_item *pattern) 1659 { 1660 switch (pattern->type) { 1661 case RTE_FLOW_ITEM_TYPE_ETH: 1662 default_mask = (const void *)&rte_flow_item_eth_mask; 1663 break; 1664 case RTE_FLOW_ITEM_TYPE_VLAN: 1665 default_mask = (const void *)&rte_flow_item_vlan_mask; 1666 break; 1667 case RTE_FLOW_ITEM_TYPE_IPV4: 1668 default_mask = (const void *)&rte_flow_item_ipv4_mask; 1669 break; 1670 case RTE_FLOW_ITEM_TYPE_IPV6: 1671 default_mask = (const void *)&rte_flow_item_ipv6_mask; 1672 break; 1673 case RTE_FLOW_ITEM_TYPE_ICMP: 1674 default_mask = (const void *)&rte_flow_item_icmp_mask; 1675 break; 1676 case RTE_FLOW_ITEM_TYPE_UDP: 1677 default_mask = (const void *)&rte_flow_item_udp_mask; 1678 break; 1679 case RTE_FLOW_ITEM_TYPE_TCP: 1680 default_mask = (const void *)&rte_flow_item_tcp_mask; 1681 break; 1682 case RTE_FLOW_ITEM_TYPE_SCTP: 1683 default_mask = (const void *)&rte_flow_item_sctp_mask; 1684 break; 1685 case RTE_FLOW_ITEM_TYPE_GRE: 1686 default_mask = (const void *)&rte_flow_item_gre_mask; 1687 break; 1688 default: 1689 DPAA2_PMD_ERR("Invalid pattern type"); 1690 } 1691 } 1692 1693 static inline int 1694 dpaa2_dev_verify_patterns(struct dpaa2_dev_priv *dev_priv, 1695 const struct rte_flow_item pattern[]) 1696 { 1697 unsigned int i, j, k, is_found = 0; 1698 int ret = 0; 1699 1700 for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) { 1701 for (i = 0; i < RTE_DIM(dpaa2_supported_pattern_type); i++) { 1702 if (dpaa2_supported_pattern_type[i] == pattern[j].type) { 1703 is_found = 1; 1704 break; 1705 } 1706 } 1707 if (!is_found) { 1708 ret = -ENOTSUP; 1709 break; 1710 } 1711 } 1712 /* Lets verify other combinations of given pattern rules */ 1713 for (j = 0; pattern[j].type != RTE_FLOW_ITEM_TYPE_END; j++) { 1714 if (!pattern[j].spec) { 1715 ret = -EINVAL; 1716 break; 1717 } 1718 if ((pattern[j].last) && (!pattern[j].mask)) 1719 dpaa2_dev_update_default_mask(&pattern[j]); 1720 } 1721 1722 /* DPAA2 platform has a limitation that extract parameter can not be */ 1723 /* more than DPKG_MAX_NUM_OF_EXTRACTS. Verify this limitation too. */ 1724 for (i = 0; pattern[i].type != RTE_FLOW_ITEM_TYPE_END; i++) { 1725 for (j = 0; j < MAX_TCS + 1; j++) { 1726 for (k = 0; k < DPKG_MAX_NUM_OF_EXTRACTS; j++) { 1727 if (dev_priv->pattern[j].pattern_type[k] == pattern[i].type) 1728 break; 1729 } 1730 if (dev_priv->pattern[j].item_count >= DPKG_MAX_NUM_OF_EXTRACTS) 1731 ret = -ENOTSUP; 1732 } 1733 } 1734 return ret; 1735 } 1736 1737 static inline int 1738 dpaa2_dev_verify_actions(const struct rte_flow_action actions[]) 1739 { 1740 unsigned int i, j, is_found = 0; 1741 int ret = 0; 1742 1743 for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) { 1744 for (i = 0; i < RTE_DIM(dpaa2_supported_action_type); i++) { 1745 if (dpaa2_supported_action_type[i] == actions[j].type) { 1746 is_found = 1; 1747 break; 1748 } 1749 } 1750 if (!is_found) { 1751 ret = -ENOTSUP; 1752 break; 1753 } 1754 } 1755 for (j = 0; actions[j].type != RTE_FLOW_ACTION_TYPE_END; j++) { 1756 if ((actions[j].type != RTE_FLOW_ACTION_TYPE_DROP) && (!actions[j].conf)) 1757 ret = -EINVAL; 1758 } 1759 return ret; 1760 } 1761 1762 static 1763 int dpaa2_flow_validate(struct rte_eth_dev *dev, 1764 const struct rte_flow_attr *flow_attr, 1765 const struct rte_flow_item pattern[], 1766 const struct rte_flow_action actions[], 1767 struct rte_flow_error *error __rte_unused) 1768 { 1769 struct dpaa2_dev_priv *priv = dev->data->dev_private; 1770 struct dpni_attr dpni_attr; 1771 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 1772 uint16_t token = priv->token; 1773 int ret = 0; 1774 1775 memset(&dpni_attr, 0, sizeof(struct dpni_attr)); 1776 ret = dpni_get_attributes(dpni, CMD_PRI_LOW, token, &dpni_attr); 1777 if (ret < 0) { 1778 DPAA2_PMD_ERR( 1779 "Failure to get dpni@%p attribute, err code %d\n", 1780 dpni, ret); 1781 return ret; 1782 } 1783 1784 /* Verify input attributes */ 1785 ret = dpaa2_dev_verify_attr(&dpni_attr, flow_attr); 1786 if (ret < 0) { 1787 DPAA2_PMD_ERR( 1788 "Invalid attributes are given\n"); 1789 goto not_valid_params; 1790 } 1791 /* Verify input pattern list */ 1792 ret = dpaa2_dev_verify_patterns(priv, pattern); 1793 if (ret < 0) { 1794 DPAA2_PMD_ERR( 1795 "Invalid pattern list is given\n"); 1796 goto not_valid_params; 1797 } 1798 /* Verify input action list */ 1799 ret = dpaa2_dev_verify_actions(actions); 1800 if (ret < 0) { 1801 DPAA2_PMD_ERR( 1802 "Invalid action list is given\n"); 1803 goto not_valid_params; 1804 } 1805 not_valid_params: 1806 return ret; 1807 } 1808 1809 static 1810 struct rte_flow *dpaa2_flow_create(struct rte_eth_dev *dev, 1811 const struct rte_flow_attr *attr, 1812 const struct rte_flow_item pattern[], 1813 const struct rte_flow_action actions[], 1814 struct rte_flow_error *error) 1815 { 1816 struct rte_flow *flow = NULL; 1817 size_t key_iova = 0, mask_iova = 0; 1818 int ret; 1819 1820 flow = rte_malloc(NULL, sizeof(struct rte_flow), RTE_CACHE_LINE_SIZE); 1821 if (!flow) { 1822 DPAA2_PMD_ERR("Failure to allocate memory for flow"); 1823 return NULL; 1824 } 1825 /* Allocate DMA'ble memory to write the rules */ 1826 key_iova = (size_t)rte_malloc(NULL, 256, 64); 1827 if (!key_iova) { 1828 DPAA2_PMD_ERR( 1829 "Memory allocation failure for rule configration\n"); 1830 goto creation_error; 1831 } 1832 mask_iova = (size_t)rte_malloc(NULL, 256, 64); 1833 if (!mask_iova) { 1834 DPAA2_PMD_ERR( 1835 "Memory allocation failure for rule configration\n"); 1836 goto creation_error; 1837 } 1838 1839 flow->rule.key_iova = key_iova; 1840 flow->rule.mask_iova = mask_iova; 1841 flow->rule.key_size = 0; 1842 1843 switch (dpaa2_filter_type) { 1844 case RTE_ETH_FILTER_GENERIC: 1845 ret = dpaa2_generic_flow_set(flow, dev, attr, pattern, 1846 actions, error); 1847 if (ret < 0) { 1848 DPAA2_PMD_ERR( 1849 "Failure to create flow, return code (%d)", ret); 1850 goto creation_error; 1851 } 1852 break; 1853 default: 1854 DPAA2_PMD_ERR("Filter type (%d) not supported", 1855 dpaa2_filter_type); 1856 break; 1857 } 1858 1859 return flow; 1860 1861 creation_error: 1862 if (flow) 1863 rte_free((void *)flow); 1864 if (key_iova) 1865 rte_free((void *)key_iova); 1866 if (mask_iova) 1867 rte_free((void *)mask_iova); 1868 return NULL; 1869 } 1870 1871 static 1872 int dpaa2_flow_destroy(struct rte_eth_dev *dev, 1873 struct rte_flow *flow, 1874 struct rte_flow_error *error __rte_unused) 1875 { 1876 int ret = 0; 1877 struct dpaa2_dev_priv *priv = dev->data->dev_private; 1878 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 1879 1880 switch (flow->action) { 1881 case RTE_FLOW_ACTION_TYPE_QUEUE: 1882 /* Remove entry from QoS table first */ 1883 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, priv->token, 1884 &flow->rule); 1885 if (ret < 0) { 1886 DPAA2_PMD_ERR( 1887 "Error in adding entry to QoS table(%d)", ret); 1888 goto error; 1889 } 1890 1891 /* Then remove entry from FS table */ 1892 ret = dpni_remove_fs_entry(dpni, CMD_PRI_LOW, priv->token, 1893 flow->tc_id, &flow->rule); 1894 if (ret < 0) { 1895 DPAA2_PMD_ERR( 1896 "Error in entry addition in FS table(%d)", ret); 1897 goto error; 1898 } 1899 break; 1900 case RTE_FLOW_ACTION_TYPE_RSS: 1901 ret = dpni_remove_qos_entry(dpni, CMD_PRI_LOW, priv->token, 1902 &flow->rule); 1903 if (ret < 0) { 1904 DPAA2_PMD_ERR( 1905 "Error in entry addition in QoS table(%d)", ret); 1906 goto error; 1907 } 1908 break; 1909 default: 1910 DPAA2_PMD_ERR( 1911 "Action type (%d) is not supported", flow->action); 1912 ret = -ENOTSUP; 1913 break; 1914 } 1915 1916 /* Now free the flow */ 1917 rte_free(flow); 1918 1919 error: 1920 return ret; 1921 } 1922 1923 static int 1924 dpaa2_flow_flush(struct rte_eth_dev *dev, 1925 struct rte_flow_error *error __rte_unused) 1926 { 1927 int ret = 0, tc_id; 1928 struct dpni_rx_tc_dist_cfg tc_cfg; 1929 struct dpni_qos_tbl_cfg qos_cfg; 1930 struct dpaa2_dev_priv *priv = dev->data->dev_private; 1931 struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; 1932 1933 /* Reset QoS table */ 1934 qos_cfg.default_tc = 0; 1935 qos_cfg.discard_on_miss = false; 1936 qos_cfg.keep_entries = false; 1937 qos_cfg.key_cfg_iova = priv->extract.qos_extract_param; 1938 ret = dpni_set_qos_table(dpni, CMD_PRI_LOW, priv->token, &qos_cfg); 1939 if (ret < 0) 1940 DPAA2_PMD_ERR( 1941 "QoS table is not reset to default: %d\n", ret); 1942 1943 for (tc_id = 0; tc_id < priv->num_rx_tc; tc_id++) { 1944 /* Reset FS table */ 1945 memset(&tc_cfg, 0, sizeof(struct dpni_rx_tc_dist_cfg)); 1946 ret = dpni_set_rx_tc_dist(dpni, CMD_PRI_LOW, priv->token, 1947 tc_id, &tc_cfg); 1948 if (ret < 0) 1949 DPAA2_PMD_ERR( 1950 "Error (%d) in flushing entries for TC (%d)", 1951 ret, tc_id); 1952 } 1953 return ret; 1954 } 1955 1956 static int 1957 dpaa2_flow_query(struct rte_eth_dev *dev __rte_unused, 1958 struct rte_flow *flow __rte_unused, 1959 const struct rte_flow_action *actions __rte_unused, 1960 void *data __rte_unused, 1961 struct rte_flow_error *error __rte_unused) 1962 { 1963 return 0; 1964 } 1965 1966 const struct rte_flow_ops dpaa2_flow_ops = { 1967 .create = dpaa2_flow_create, 1968 .validate = dpaa2_flow_validate, 1969 .destroy = dpaa2_flow_destroy, 1970 .flush = dpaa2_flow_flush, 1971 .query = dpaa2_flow_query, 1972 }; 1973