1 /* 2 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. 3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. 4 * 5 * This software is available to you under a choice of one of two 6 * licenses. You may choose to be licensed under the terms of the GNU 7 * General Public License (GPL) Version 2, available from the file 8 * COPYING in the main directory of this source tree, or the 9 * OpenIB.org BSD license below: 10 * 11 * Redistribution and use in source and binary forms, with or 12 * without modification, are permitted provided that the following 13 * conditions are met: 14 * 15 * - Redistributions of source code must retain the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer. 18 * 19 * - Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the following 21 * disclaimer in the documentation and/or other materials 22 * provided with the distribution. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 * SOFTWARE. 32 */ 33 34 #include <linux/string.h> 35 #include <linux/etherdevice.h> 36 37 #include <linux/mlx4/cmd.h> 38 #include <linux/export.h> 39 40 #include "mlx4.h" 41 42 static const u8 zero_gid[16]; /* automatically initialized to 0 */ 43 44 int mlx4_get_mgm_entry_size(struct mlx4_dev *dev) 45 { 46 return 1 << dev->oper_log_mgm_entry_size; 47 } 48 49 int mlx4_get_qp_per_mgm(struct mlx4_dev *dev) 50 { 51 return 4 * (mlx4_get_mgm_entry_size(dev) / 16 - 2); 52 } 53 54 static int mlx4_QP_FLOW_STEERING_ATTACH(struct mlx4_dev *dev, 55 struct mlx4_cmd_mailbox *mailbox, 56 u32 size, 57 u64 *reg_id) 58 { 59 u64 imm; 60 int err = 0; 61 62 err = mlx4_cmd_imm(dev, mailbox->dma, &imm, size, 0, 63 MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, 64 MLX4_CMD_NATIVE); 65 if (err) 66 return err; 67 *reg_id = imm; 68 69 return err; 70 } 71 72 static int mlx4_QP_FLOW_STEERING_DETACH(struct mlx4_dev *dev, u64 regid) 73 { 74 int err = 0; 75 76 err = mlx4_cmd(dev, regid, 0, 0, 77 MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A, 78 MLX4_CMD_NATIVE); 79 80 return err; 81 } 82 83 static int mlx4_READ_ENTRY(struct mlx4_dev *dev, int index, 84 struct mlx4_cmd_mailbox *mailbox) 85 { 86 return mlx4_cmd_box(dev, 0, mailbox->dma, index, 0, MLX4_CMD_READ_MCG, 87 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 88 } 89 90 static int mlx4_WRITE_ENTRY(struct mlx4_dev *dev, int index, 91 struct mlx4_cmd_mailbox *mailbox) 92 { 93 return mlx4_cmd(dev, mailbox->dma, index, 0, MLX4_CMD_WRITE_MCG, 94 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 95 } 96 97 static int mlx4_WRITE_PROMISC(struct mlx4_dev *dev, u8 port, u8 steer, 98 struct mlx4_cmd_mailbox *mailbox) 99 { 100 u32 in_mod; 101 102 in_mod = (u32) port << 16 | steer << 1; 103 return mlx4_cmd(dev, mailbox->dma, in_mod, 0x1, 104 MLX4_CMD_WRITE_MCG, MLX4_CMD_TIME_CLASS_A, 105 MLX4_CMD_NATIVE); 106 } 107 108 static int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, 109 u16 *hash, u8 op_mod) 110 { 111 u64 imm; 112 int err; 113 114 err = mlx4_cmd_imm(dev, mailbox->dma, &imm, 0, op_mod, 115 MLX4_CMD_MGID_HASH, MLX4_CMD_TIME_CLASS_A, 116 MLX4_CMD_NATIVE); 117 118 if (!err) 119 *hash = imm; 120 121 return err; 122 } 123 124 static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 port, 125 enum mlx4_steer_type steer, 126 u32 qpn) 127 { 128 struct mlx4_steer *s_steer; 129 struct mlx4_promisc_qp *pqp; 130 131 if (port < 1 || port > dev->caps.num_ports) 132 return NULL; 133 134 s_steer = &mlx4_priv(dev)->steer[port - 1]; 135 136 list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { 137 if (pqp->qpn == qpn) 138 return pqp; 139 } 140 /* not found */ 141 return NULL; 142 } 143 144 /* 145 * Add new entry to steering data structure. 146 * All promisc QPs should be added as well 147 */ 148 static int new_steering_entry(struct mlx4_dev *dev, u8 port, 149 enum mlx4_steer_type steer, 150 unsigned int index, u32 qpn) 151 { 152 struct mlx4_steer *s_steer; 153 struct mlx4_cmd_mailbox *mailbox; 154 struct mlx4_mgm *mgm; 155 u32 members_count; 156 struct mlx4_steer_index *new_entry; 157 struct mlx4_promisc_qp *pqp; 158 struct mlx4_promisc_qp *dqp = NULL; 159 u32 prot; 160 int err; 161 162 if (port < 1 || port > dev->caps.num_ports) 163 return -EINVAL; 164 165 s_steer = &mlx4_priv(dev)->steer[port - 1]; 166 new_entry = kzalloc(sizeof *new_entry, GFP_KERNEL); 167 if (!new_entry) 168 return -ENOMEM; 169 170 INIT_LIST_HEAD(&new_entry->duplicates); 171 new_entry->index = index; 172 list_add_tail(&new_entry->list, &s_steer->steer_entries[steer]); 173 174 /* If the given qpn is also a promisc qp, 175 * it should be inserted to duplicates list 176 */ 177 pqp = get_promisc_qp(dev, port, steer, qpn); 178 if (pqp) { 179 dqp = kmalloc(sizeof *dqp, GFP_KERNEL); 180 if (!dqp) { 181 err = -ENOMEM; 182 goto out_alloc; 183 } 184 dqp->qpn = qpn; 185 list_add_tail(&dqp->list, &new_entry->duplicates); 186 } 187 188 /* if no promisc qps for this vep, we are done */ 189 if (list_empty(&s_steer->promisc_qps[steer])) 190 return 0; 191 192 /* now need to add all the promisc qps to the new 193 * steering entry, as they should also receive the packets 194 * destined to this address */ 195 mailbox = mlx4_alloc_cmd_mailbox(dev); 196 if (IS_ERR(mailbox)) { 197 err = -ENOMEM; 198 goto out_alloc; 199 } 200 mgm = mailbox->buf; 201 202 err = mlx4_READ_ENTRY(dev, index, mailbox); 203 if (err) 204 goto out_mailbox; 205 206 members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 207 prot = be32_to_cpu(mgm->members_count) >> 30; 208 list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { 209 /* don't add already existing qpn */ 210 if (pqp->qpn == qpn) 211 continue; 212 if (members_count == dev->caps.num_qp_per_mgm) { 213 /* out of space */ 214 err = -ENOMEM; 215 goto out_mailbox; 216 } 217 218 /* add the qpn */ 219 mgm->qp[members_count++] = cpu_to_be32(pqp->qpn & MGM_QPN_MASK); 220 } 221 /* update the qps count and update the entry with all the promisc qps*/ 222 mgm->members_count = cpu_to_be32(members_count | (prot << 30)); 223 err = mlx4_WRITE_ENTRY(dev, index, mailbox); 224 225 out_mailbox: 226 mlx4_free_cmd_mailbox(dev, mailbox); 227 if (!err) 228 return 0; 229 out_alloc: 230 if (dqp) { 231 list_del(&dqp->list); 232 kfree(dqp); 233 } 234 list_del(&new_entry->list); 235 kfree(new_entry); 236 return err; 237 } 238 239 /* update the data structures with existing steering entry */ 240 static int existing_steering_entry(struct mlx4_dev *dev, u8 port, 241 enum mlx4_steer_type steer, 242 unsigned int index, u32 qpn) 243 { 244 struct mlx4_steer *s_steer; 245 struct mlx4_steer_index *tmp_entry, *entry = NULL; 246 struct mlx4_promisc_qp *pqp; 247 struct mlx4_promisc_qp *dqp; 248 249 if (port < 1 || port > dev->caps.num_ports) 250 return -EINVAL; 251 252 s_steer = &mlx4_priv(dev)->steer[port - 1]; 253 254 pqp = get_promisc_qp(dev, port, steer, qpn); 255 if (!pqp) 256 return 0; /* nothing to do */ 257 258 list_for_each_entry(tmp_entry, &s_steer->steer_entries[steer], list) { 259 if (tmp_entry->index == index) { 260 entry = tmp_entry; 261 break; 262 } 263 } 264 if (unlikely(!entry)) { 265 mlx4_warn(dev, "Steering entry at index %x is not registered\n", index); 266 return -EINVAL; 267 } 268 269 /* the given qpn is listed as a promisc qpn 270 * we need to add it as a duplicate to this entry 271 * for future references */ 272 list_for_each_entry(dqp, &entry->duplicates, list) { 273 if (qpn == dqp->qpn) 274 return 0; /* qp is already duplicated */ 275 } 276 277 /* add the qp as a duplicate on this index */ 278 dqp = kmalloc(sizeof *dqp, GFP_KERNEL); 279 if (!dqp) 280 return -ENOMEM; 281 dqp->qpn = qpn; 282 list_add_tail(&dqp->list, &entry->duplicates); 283 284 return 0; 285 } 286 287 /* Check whether a qpn is a duplicate on steering entry 288 * If so, it should not be removed from mgm */ 289 static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port, 290 enum mlx4_steer_type steer, 291 unsigned int index, u32 qpn) 292 { 293 struct mlx4_steer *s_steer; 294 struct mlx4_steer_index *tmp_entry, *entry = NULL; 295 struct mlx4_promisc_qp *dqp, *tmp_dqp; 296 297 if (port < 1 || port > dev->caps.num_ports) 298 return NULL; 299 300 s_steer = &mlx4_priv(dev)->steer[port - 1]; 301 302 /* if qp is not promisc, it cannot be duplicated */ 303 if (!get_promisc_qp(dev, port, steer, qpn)) 304 return false; 305 306 /* The qp is promisc qp so it is a duplicate on this index 307 * Find the index entry, and remove the duplicate */ 308 list_for_each_entry(tmp_entry, &s_steer->steer_entries[steer], list) { 309 if (tmp_entry->index == index) { 310 entry = tmp_entry; 311 break; 312 } 313 } 314 if (unlikely(!entry)) { 315 mlx4_warn(dev, "Steering entry for index %x is not registered\n", index); 316 return false; 317 } 318 list_for_each_entry_safe(dqp, tmp_dqp, &entry->duplicates, list) { 319 if (dqp->qpn == qpn) { 320 list_del(&dqp->list); 321 kfree(dqp); 322 } 323 } 324 return true; 325 } 326 327 /* Returns true if all the QPs != tqpn contained in this entry 328 * are Promisc QPs. Returns false otherwise. 329 */ 330 static bool promisc_steering_entry(struct mlx4_dev *dev, u8 port, 331 enum mlx4_steer_type steer, 332 unsigned int index, u32 tqpn, 333 u32 *members_count) 334 { 335 struct mlx4_cmd_mailbox *mailbox; 336 struct mlx4_mgm *mgm; 337 u32 m_count; 338 bool ret = false; 339 int i; 340 341 if (port < 1 || port > dev->caps.num_ports) 342 return false; 343 344 mailbox = mlx4_alloc_cmd_mailbox(dev); 345 if (IS_ERR(mailbox)) 346 return false; 347 mgm = mailbox->buf; 348 349 if (mlx4_READ_ENTRY(dev, index, mailbox)) 350 goto out; 351 m_count = be32_to_cpu(mgm->members_count) & 0xffffff; 352 if (members_count) 353 *members_count = m_count; 354 355 for (i = 0; i < m_count; i++) { 356 u32 qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK; 357 if (!get_promisc_qp(dev, port, steer, qpn) && qpn != tqpn) { 358 /* the qp is not promisc, the entry can't be removed */ 359 goto out; 360 } 361 } 362 ret = true; 363 out: 364 mlx4_free_cmd_mailbox(dev, mailbox); 365 return ret; 366 } 367 368 /* IF a steering entry contains only promisc QPs, it can be removed. */ 369 static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port, 370 enum mlx4_steer_type steer, 371 unsigned int index, u32 tqpn) 372 { 373 struct mlx4_steer *s_steer; 374 struct mlx4_steer_index *entry = NULL, *tmp_entry; 375 u32 members_count; 376 bool ret = false; 377 378 if (port < 1 || port > dev->caps.num_ports) 379 return NULL; 380 381 s_steer = &mlx4_priv(dev)->steer[port - 1]; 382 383 if (!promisc_steering_entry(dev, port, steer, index, 384 tqpn, &members_count)) 385 goto out; 386 387 /* All the qps currently registered for this entry are promiscuous, 388 * Checking for duplicates */ 389 ret = true; 390 list_for_each_entry_safe(entry, tmp_entry, &s_steer->steer_entries[steer], list) { 391 if (entry->index == index) { 392 if (list_empty(&entry->duplicates) || 393 members_count == 1) { 394 struct mlx4_promisc_qp *pqp, *tmp_pqp; 395 /* If there is only 1 entry in duplicates then 396 * this is the QP we want to delete, going over 397 * the list and deleting the entry. 398 */ 399 list_del(&entry->list); 400 list_for_each_entry_safe(pqp, tmp_pqp, 401 &entry->duplicates, 402 list) { 403 list_del(&pqp->list); 404 kfree(pqp); 405 } 406 kfree(entry); 407 } else { 408 /* This entry contains duplicates so it shouldn't be removed */ 409 ret = false; 410 goto out; 411 } 412 } 413 } 414 415 out: 416 return ret; 417 } 418 419 static int add_promisc_qp(struct mlx4_dev *dev, u8 port, 420 enum mlx4_steer_type steer, u32 qpn) 421 { 422 struct mlx4_steer *s_steer; 423 struct mlx4_cmd_mailbox *mailbox; 424 struct mlx4_mgm *mgm; 425 struct mlx4_steer_index *entry; 426 struct mlx4_promisc_qp *pqp; 427 struct mlx4_promisc_qp *dqp; 428 u32 members_count; 429 u32 prot; 430 int i; 431 bool found; 432 int err; 433 struct mlx4_priv *priv = mlx4_priv(dev); 434 435 if (port < 1 || port > dev->caps.num_ports) 436 return -EINVAL; 437 438 s_steer = &mlx4_priv(dev)->steer[port - 1]; 439 440 mutex_lock(&priv->mcg_table.mutex); 441 442 if (get_promisc_qp(dev, port, steer, qpn)) { 443 err = 0; /* Noting to do, already exists */ 444 goto out_mutex; 445 } 446 447 pqp = kmalloc(sizeof *pqp, GFP_KERNEL); 448 if (!pqp) { 449 err = -ENOMEM; 450 goto out_mutex; 451 } 452 pqp->qpn = qpn; 453 454 mailbox = mlx4_alloc_cmd_mailbox(dev); 455 if (IS_ERR(mailbox)) { 456 err = -ENOMEM; 457 goto out_alloc; 458 } 459 mgm = mailbox->buf; 460 461 if (!(mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)) { 462 /* The promisc QP needs to be added for each one of the steering 463 * entries. If it already exists, needs to be added as 464 * a duplicate for this entry. 465 */ 466 list_for_each_entry(entry, 467 &s_steer->steer_entries[steer], 468 list) { 469 err = mlx4_READ_ENTRY(dev, entry->index, mailbox); 470 if (err) 471 goto out_mailbox; 472 473 members_count = be32_to_cpu(mgm->members_count) & 474 0xffffff; 475 prot = be32_to_cpu(mgm->members_count) >> 30; 476 found = false; 477 for (i = 0; i < members_count; i++) { 478 if ((be32_to_cpu(mgm->qp[i]) & 479 MGM_QPN_MASK) == qpn) { 480 /* Entry already exists. 481 * Add to duplicates. 482 */ 483 dqp = kmalloc(sizeof(*dqp), GFP_KERNEL); 484 if (!dqp) { 485 err = -ENOMEM; 486 goto out_mailbox; 487 } 488 dqp->qpn = qpn; 489 list_add_tail(&dqp->list, 490 &entry->duplicates); 491 found = true; 492 } 493 } 494 if (!found) { 495 /* Need to add the qpn to mgm */ 496 if (members_count == 497 dev->caps.num_qp_per_mgm) { 498 /* entry is full */ 499 err = -ENOMEM; 500 goto out_mailbox; 501 } 502 mgm->qp[members_count++] = 503 cpu_to_be32(qpn & MGM_QPN_MASK); 504 mgm->members_count = 505 cpu_to_be32(members_count | 506 (prot << 30)); 507 err = mlx4_WRITE_ENTRY(dev, entry->index, 508 mailbox); 509 if (err) 510 goto out_mailbox; 511 } 512 } 513 } 514 515 /* add the new qpn to list of promisc qps */ 516 list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]); 517 /* now need to add all the promisc qps to default entry */ 518 memset(mgm, 0, sizeof *mgm); 519 members_count = 0; 520 list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list) { 521 if (members_count == dev->caps.num_qp_per_mgm) { 522 /* entry is full */ 523 err = -ENOMEM; 524 goto out_list; 525 } 526 mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK); 527 } 528 mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30); 529 530 err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox); 531 if (err) 532 goto out_list; 533 534 mlx4_free_cmd_mailbox(dev, mailbox); 535 mutex_unlock(&priv->mcg_table.mutex); 536 return 0; 537 538 out_list: 539 list_del(&pqp->list); 540 out_mailbox: 541 mlx4_free_cmd_mailbox(dev, mailbox); 542 out_alloc: 543 kfree(pqp); 544 out_mutex: 545 mutex_unlock(&priv->mcg_table.mutex); 546 return err; 547 } 548 549 static int remove_promisc_qp(struct mlx4_dev *dev, u8 port, 550 enum mlx4_steer_type steer, u32 qpn) 551 { 552 struct mlx4_priv *priv = mlx4_priv(dev); 553 struct mlx4_steer *s_steer; 554 struct mlx4_cmd_mailbox *mailbox; 555 struct mlx4_mgm *mgm; 556 struct mlx4_steer_index *entry, *tmp_entry; 557 struct mlx4_promisc_qp *pqp; 558 struct mlx4_promisc_qp *dqp; 559 u32 members_count; 560 bool found; 561 bool back_to_list = false; 562 int i; 563 int err; 564 565 if (port < 1 || port > dev->caps.num_ports) 566 return -EINVAL; 567 568 s_steer = &mlx4_priv(dev)->steer[port - 1]; 569 mutex_lock(&priv->mcg_table.mutex); 570 571 pqp = get_promisc_qp(dev, port, steer, qpn); 572 if (unlikely(!pqp)) { 573 mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn); 574 /* nothing to do */ 575 err = 0; 576 goto out_mutex; 577 } 578 579 /*remove from list of promisc qps */ 580 list_del(&pqp->list); 581 582 /* set the default entry not to include the removed one */ 583 mailbox = mlx4_alloc_cmd_mailbox(dev); 584 if (IS_ERR(mailbox)) { 585 err = -ENOMEM; 586 back_to_list = true; 587 goto out_list; 588 } 589 mgm = mailbox->buf; 590 members_count = 0; 591 list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list) 592 mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK); 593 mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30); 594 595 err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox); 596 if (err) 597 goto out_mailbox; 598 599 if (!(mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER)) { 600 /* Remove the QP from all the steering entries */ 601 list_for_each_entry_safe(entry, tmp_entry, 602 &s_steer->steer_entries[steer], 603 list) { 604 found = false; 605 list_for_each_entry(dqp, &entry->duplicates, list) { 606 if (dqp->qpn == qpn) { 607 found = true; 608 break; 609 } 610 } 611 if (found) { 612 /* A duplicate, no need to change the MGM, 613 * only update the duplicates list 614 */ 615 list_del(&dqp->list); 616 kfree(dqp); 617 } else { 618 int loc = -1; 619 620 err = mlx4_READ_ENTRY(dev, 621 entry->index, 622 mailbox); 623 if (err) 624 goto out_mailbox; 625 members_count = 626 be32_to_cpu(mgm->members_count) & 627 0xffffff; 628 if (!members_count) { 629 mlx4_warn(dev, "QP %06x wasn't found in entry %x mcount=0. deleting entry...\n", 630 qpn, entry->index); 631 list_del(&entry->list); 632 kfree(entry); 633 continue; 634 } 635 636 for (i = 0; i < members_count; ++i) 637 if ((be32_to_cpu(mgm->qp[i]) & 638 MGM_QPN_MASK) == qpn) { 639 loc = i; 640 break; 641 } 642 643 if (loc < 0) { 644 mlx4_err(dev, "QP %06x wasn't found in entry %d\n", 645 qpn, entry->index); 646 err = -EINVAL; 647 goto out_mailbox; 648 } 649 650 /* Copy the last QP in this MGM 651 * over removed QP 652 */ 653 mgm->qp[loc] = mgm->qp[members_count - 1]; 654 mgm->qp[members_count - 1] = 0; 655 mgm->members_count = 656 cpu_to_be32(--members_count | 657 (MLX4_PROT_ETH << 30)); 658 659 err = mlx4_WRITE_ENTRY(dev, 660 entry->index, 661 mailbox); 662 if (err) 663 goto out_mailbox; 664 } 665 } 666 } 667 668 out_mailbox: 669 mlx4_free_cmd_mailbox(dev, mailbox); 670 out_list: 671 if (back_to_list) 672 list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]); 673 else 674 kfree(pqp); 675 out_mutex: 676 mutex_unlock(&priv->mcg_table.mutex); 677 return err; 678 } 679 680 /* 681 * Caller must hold MCG table semaphore. gid and mgm parameters must 682 * be properly aligned for command interface. 683 * 684 * Returns 0 unless a firmware command error occurs. 685 * 686 * If GID is found in MGM or MGM is empty, *index = *hash, *prev = -1 687 * and *mgm holds MGM entry. 688 * 689 * if GID is found in AMGM, *index = index in AMGM, *prev = index of 690 * previous entry in hash chain and *mgm holds AMGM entry. 691 * 692 * If no AMGM exists for given gid, *index = -1, *prev = index of last 693 * entry in hash chain and *mgm holds end of hash chain. 694 */ 695 static int find_entry(struct mlx4_dev *dev, u8 port, 696 u8 *gid, enum mlx4_protocol prot, 697 struct mlx4_cmd_mailbox *mgm_mailbox, 698 int *prev, int *index) 699 { 700 struct mlx4_cmd_mailbox *mailbox; 701 struct mlx4_mgm *mgm = mgm_mailbox->buf; 702 u8 *mgid; 703 int err; 704 u16 hash; 705 u8 op_mod = (prot == MLX4_PROT_ETH) ? 706 !!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) : 0; 707 708 mailbox = mlx4_alloc_cmd_mailbox(dev); 709 if (IS_ERR(mailbox)) 710 return -ENOMEM; 711 mgid = mailbox->buf; 712 713 memcpy(mgid, gid, 16); 714 715 err = mlx4_GID_HASH(dev, mailbox, &hash, op_mod); 716 mlx4_free_cmd_mailbox(dev, mailbox); 717 if (err) 718 return err; 719 720 if (0) 721 mlx4_dbg(dev, "Hash for %pI6 is %04x\n", gid, hash); 722 723 *index = hash; 724 *prev = -1; 725 726 do { 727 err = mlx4_READ_ENTRY(dev, *index, mgm_mailbox); 728 if (err) 729 return err; 730 731 if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) { 732 if (*index != hash) { 733 mlx4_err(dev, "Found zero MGID in AMGM\n"); 734 err = -EINVAL; 735 } 736 return err; 737 } 738 739 if (!memcmp(mgm->gid, gid, 16) && 740 be32_to_cpu(mgm->members_count) >> 30 == prot) 741 return err; 742 743 *prev = *index; 744 *index = be32_to_cpu(mgm->next_gid_index) >> 6; 745 } while (*index); 746 747 *index = -1; 748 return err; 749 } 750 751 static const u8 __promisc_mode[] = { 752 [MLX4_FS_REGULAR] = 0x0, 753 [MLX4_FS_ALL_DEFAULT] = 0x1, 754 [MLX4_FS_MC_DEFAULT] = 0x3, 755 [MLX4_FS_UC_SNIFFER] = 0x4, 756 [MLX4_FS_MC_SNIFFER] = 0x5, 757 }; 758 759 int mlx4_map_sw_to_hw_steering_mode(struct mlx4_dev *dev, 760 enum mlx4_net_trans_promisc_mode flow_type) 761 { 762 if (flow_type >= MLX4_FS_MODE_NUM) { 763 mlx4_err(dev, "Invalid flow type. type = %d\n", flow_type); 764 return -EINVAL; 765 } 766 return __promisc_mode[flow_type]; 767 } 768 EXPORT_SYMBOL_GPL(mlx4_map_sw_to_hw_steering_mode); 769 770 static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, 771 struct mlx4_net_trans_rule_hw_ctrl *hw) 772 { 773 u8 flags = 0; 774 775 flags = ctrl->queue_mode == MLX4_NET_TRANS_Q_LIFO ? 1 : 0; 776 flags |= ctrl->exclusive ? (1 << 2) : 0; 777 flags |= ctrl->allow_loopback ? (1 << 3) : 0; 778 779 hw->flags = flags; 780 hw->type = __promisc_mode[ctrl->promisc_mode]; 781 hw->prio = cpu_to_be16(ctrl->priority); 782 hw->port = ctrl->port; 783 hw->qpn = cpu_to_be32(ctrl->qpn); 784 } 785 786 const u16 __sw_id_hw[] = { 787 [MLX4_NET_TRANS_RULE_ID_ETH] = 0xE001, 788 [MLX4_NET_TRANS_RULE_ID_IB] = 0xE005, 789 [MLX4_NET_TRANS_RULE_ID_IPV6] = 0xE003, 790 [MLX4_NET_TRANS_RULE_ID_IPV4] = 0xE002, 791 [MLX4_NET_TRANS_RULE_ID_TCP] = 0xE004, 792 [MLX4_NET_TRANS_RULE_ID_UDP] = 0xE006, 793 [MLX4_NET_TRANS_RULE_ID_VXLAN] = 0xE008 794 }; 795 796 int mlx4_map_sw_to_hw_steering_id(struct mlx4_dev *dev, 797 enum mlx4_net_trans_rule_id id) 798 { 799 if (id >= MLX4_NET_TRANS_RULE_NUM) { 800 mlx4_err(dev, "Invalid network rule id. id = %d\n", id); 801 return -EINVAL; 802 } 803 return __sw_id_hw[id]; 804 } 805 EXPORT_SYMBOL_GPL(mlx4_map_sw_to_hw_steering_id); 806 807 static const int __rule_hw_sz[] = { 808 [MLX4_NET_TRANS_RULE_ID_ETH] = 809 sizeof(struct mlx4_net_trans_rule_hw_eth), 810 [MLX4_NET_TRANS_RULE_ID_IB] = 811 sizeof(struct mlx4_net_trans_rule_hw_ib), 812 [MLX4_NET_TRANS_RULE_ID_IPV6] = 0, 813 [MLX4_NET_TRANS_RULE_ID_IPV4] = 814 sizeof(struct mlx4_net_trans_rule_hw_ipv4), 815 [MLX4_NET_TRANS_RULE_ID_TCP] = 816 sizeof(struct mlx4_net_trans_rule_hw_tcp_udp), 817 [MLX4_NET_TRANS_RULE_ID_UDP] = 818 sizeof(struct mlx4_net_trans_rule_hw_tcp_udp), 819 [MLX4_NET_TRANS_RULE_ID_VXLAN] = 820 sizeof(struct mlx4_net_trans_rule_hw_vxlan) 821 }; 822 823 int mlx4_hw_rule_sz(struct mlx4_dev *dev, 824 enum mlx4_net_trans_rule_id id) 825 { 826 if (id >= MLX4_NET_TRANS_RULE_NUM) { 827 mlx4_err(dev, "Invalid network rule id. id = %d\n", id); 828 return -EINVAL; 829 } 830 831 return __rule_hw_sz[id]; 832 } 833 EXPORT_SYMBOL_GPL(mlx4_hw_rule_sz); 834 835 static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec, 836 struct _rule_hw *rule_hw) 837 { 838 if (mlx4_hw_rule_sz(dev, spec->id) < 0) 839 return -EINVAL; 840 memset(rule_hw, 0, mlx4_hw_rule_sz(dev, spec->id)); 841 rule_hw->id = cpu_to_be16(__sw_id_hw[spec->id]); 842 rule_hw->size = mlx4_hw_rule_sz(dev, spec->id) >> 2; 843 844 switch (spec->id) { 845 case MLX4_NET_TRANS_RULE_ID_ETH: 846 memcpy(rule_hw->eth.dst_mac, spec->eth.dst_mac, ETH_ALEN); 847 memcpy(rule_hw->eth.dst_mac_msk, spec->eth.dst_mac_msk, 848 ETH_ALEN); 849 memcpy(rule_hw->eth.src_mac, spec->eth.src_mac, ETH_ALEN); 850 memcpy(rule_hw->eth.src_mac_msk, spec->eth.src_mac_msk, 851 ETH_ALEN); 852 if (spec->eth.ether_type_enable) { 853 rule_hw->eth.ether_type_enable = 1; 854 rule_hw->eth.ether_type = spec->eth.ether_type; 855 } 856 rule_hw->eth.vlan_tag = spec->eth.vlan_id; 857 rule_hw->eth.vlan_tag_msk = spec->eth.vlan_id_msk; 858 break; 859 860 case MLX4_NET_TRANS_RULE_ID_IB: 861 rule_hw->ib.l3_qpn = spec->ib.l3_qpn; 862 rule_hw->ib.qpn_mask = spec->ib.qpn_msk; 863 memcpy(&rule_hw->ib.dst_gid, &spec->ib.dst_gid, 16); 864 memcpy(&rule_hw->ib.dst_gid_msk, &spec->ib.dst_gid_msk, 16); 865 break; 866 867 case MLX4_NET_TRANS_RULE_ID_IPV6: 868 return -EOPNOTSUPP; 869 870 case MLX4_NET_TRANS_RULE_ID_IPV4: 871 rule_hw->ipv4.src_ip = spec->ipv4.src_ip; 872 rule_hw->ipv4.src_ip_msk = spec->ipv4.src_ip_msk; 873 rule_hw->ipv4.dst_ip = spec->ipv4.dst_ip; 874 rule_hw->ipv4.dst_ip_msk = spec->ipv4.dst_ip_msk; 875 break; 876 877 case MLX4_NET_TRANS_RULE_ID_TCP: 878 case MLX4_NET_TRANS_RULE_ID_UDP: 879 rule_hw->tcp_udp.dst_port = spec->tcp_udp.dst_port; 880 rule_hw->tcp_udp.dst_port_msk = spec->tcp_udp.dst_port_msk; 881 rule_hw->tcp_udp.src_port = spec->tcp_udp.src_port; 882 rule_hw->tcp_udp.src_port_msk = spec->tcp_udp.src_port_msk; 883 break; 884 885 case MLX4_NET_TRANS_RULE_ID_VXLAN: 886 rule_hw->vxlan.vni = 887 cpu_to_be32(be32_to_cpu(spec->vxlan.vni) << 8); 888 rule_hw->vxlan.vni_mask = 889 cpu_to_be32(be32_to_cpu(spec->vxlan.vni_mask) << 8); 890 break; 891 892 default: 893 return -EINVAL; 894 } 895 896 return __rule_hw_sz[spec->id]; 897 } 898 899 static void mlx4_err_rule(struct mlx4_dev *dev, char *str, 900 struct mlx4_net_trans_rule *rule) 901 { 902 #define BUF_SIZE 256 903 struct mlx4_spec_list *cur; 904 char buf[BUF_SIZE]; 905 int len = 0; 906 907 mlx4_err(dev, "%s", str); 908 len += snprintf(buf + len, BUF_SIZE - len, 909 "port = %d prio = 0x%x qp = 0x%x ", 910 rule->port, rule->priority, rule->qpn); 911 912 list_for_each_entry(cur, &rule->list, list) { 913 switch (cur->id) { 914 case MLX4_NET_TRANS_RULE_ID_ETH: 915 len += snprintf(buf + len, BUF_SIZE - len, 916 "dmac = %pM ", &cur->eth.dst_mac); 917 if (cur->eth.ether_type) 918 len += snprintf(buf + len, BUF_SIZE - len, 919 "ethertype = 0x%x ", 920 be16_to_cpu(cur->eth.ether_type)); 921 if (cur->eth.vlan_id) 922 len += snprintf(buf + len, BUF_SIZE - len, 923 "vlan-id = %d ", 924 be16_to_cpu(cur->eth.vlan_id)); 925 break; 926 927 case MLX4_NET_TRANS_RULE_ID_IPV4: 928 if (cur->ipv4.src_ip) 929 len += snprintf(buf + len, BUF_SIZE - len, 930 "src-ip = %pI4 ", 931 &cur->ipv4.src_ip); 932 if (cur->ipv4.dst_ip) 933 len += snprintf(buf + len, BUF_SIZE - len, 934 "dst-ip = %pI4 ", 935 &cur->ipv4.dst_ip); 936 break; 937 938 case MLX4_NET_TRANS_RULE_ID_TCP: 939 case MLX4_NET_TRANS_RULE_ID_UDP: 940 if (cur->tcp_udp.src_port) 941 len += snprintf(buf + len, BUF_SIZE - len, 942 "src-port = %d ", 943 be16_to_cpu(cur->tcp_udp.src_port)); 944 if (cur->tcp_udp.dst_port) 945 len += snprintf(buf + len, BUF_SIZE - len, 946 "dst-port = %d ", 947 be16_to_cpu(cur->tcp_udp.dst_port)); 948 break; 949 950 case MLX4_NET_TRANS_RULE_ID_IB: 951 len += snprintf(buf + len, BUF_SIZE - len, 952 "dst-gid = %pI6\n", cur->ib.dst_gid); 953 len += snprintf(buf + len, BUF_SIZE - len, 954 "dst-gid-mask = %pI6\n", 955 cur->ib.dst_gid_msk); 956 break; 957 958 case MLX4_NET_TRANS_RULE_ID_VXLAN: 959 len += snprintf(buf + len, BUF_SIZE - len, 960 "VNID = %d ", be32_to_cpu(cur->vxlan.vni)); 961 break; 962 case MLX4_NET_TRANS_RULE_ID_IPV6: 963 break; 964 965 default: 966 break; 967 } 968 } 969 len += snprintf(buf + len, BUF_SIZE - len, "\n"); 970 mlx4_err(dev, "%s", buf); 971 972 if (len >= BUF_SIZE) 973 mlx4_err(dev, "Network rule error message was truncated, print buffer is too small\n"); 974 } 975 976 int mlx4_flow_attach(struct mlx4_dev *dev, 977 struct mlx4_net_trans_rule *rule, u64 *reg_id) 978 { 979 struct mlx4_cmd_mailbox *mailbox; 980 struct mlx4_spec_list *cur; 981 u32 size = 0; 982 int ret; 983 984 mailbox = mlx4_alloc_cmd_mailbox(dev); 985 if (IS_ERR(mailbox)) 986 return PTR_ERR(mailbox); 987 988 trans_rule_ctrl_to_hw(rule, mailbox->buf); 989 990 size += sizeof(struct mlx4_net_trans_rule_hw_ctrl); 991 992 list_for_each_entry(cur, &rule->list, list) { 993 ret = parse_trans_rule(dev, cur, mailbox->buf + size); 994 if (ret < 0) { 995 mlx4_free_cmd_mailbox(dev, mailbox); 996 return ret; 997 } 998 size += ret; 999 } 1000 1001 ret = mlx4_QP_FLOW_STEERING_ATTACH(dev, mailbox, size >> 2, reg_id); 1002 if (ret == -ENOMEM) 1003 mlx4_err_rule(dev, 1004 "mcg table is full. Fail to register network rule\n", 1005 rule); 1006 else if (ret) 1007 mlx4_err_rule(dev, "Fail to register network rule\n", rule); 1008 1009 mlx4_free_cmd_mailbox(dev, mailbox); 1010 1011 return ret; 1012 } 1013 EXPORT_SYMBOL_GPL(mlx4_flow_attach); 1014 1015 int mlx4_flow_detach(struct mlx4_dev *dev, u64 reg_id) 1016 { 1017 int err; 1018 1019 err = mlx4_QP_FLOW_STEERING_DETACH(dev, reg_id); 1020 if (err) 1021 mlx4_err(dev, "Fail to detach network rule. registration id = 0x%llx\n", 1022 reg_id); 1023 return err; 1024 } 1025 EXPORT_SYMBOL_GPL(mlx4_flow_detach); 1026 1027 int mlx4_tunnel_steer_add(struct mlx4_dev *dev, unsigned char *addr, 1028 int port, int qpn, u16 prio, u64 *reg_id) 1029 { 1030 int err; 1031 struct mlx4_spec_list spec_eth_outer = { {NULL} }; 1032 struct mlx4_spec_list spec_vxlan = { {NULL} }; 1033 struct mlx4_spec_list spec_eth_inner = { {NULL} }; 1034 1035 struct mlx4_net_trans_rule rule = { 1036 .queue_mode = MLX4_NET_TRANS_Q_FIFO, 1037 .exclusive = 0, 1038 .allow_loopback = 1, 1039 .promisc_mode = MLX4_FS_REGULAR, 1040 }; 1041 1042 __be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16); 1043 1044 rule.port = port; 1045 rule.qpn = qpn; 1046 rule.priority = prio; 1047 INIT_LIST_HEAD(&rule.list); 1048 1049 spec_eth_outer.id = MLX4_NET_TRANS_RULE_ID_ETH; 1050 memcpy(spec_eth_outer.eth.dst_mac, addr, ETH_ALEN); 1051 memcpy(spec_eth_outer.eth.dst_mac_msk, &mac_mask, ETH_ALEN); 1052 1053 spec_vxlan.id = MLX4_NET_TRANS_RULE_ID_VXLAN; /* any vxlan header */ 1054 spec_eth_inner.id = MLX4_NET_TRANS_RULE_ID_ETH; /* any inner eth header */ 1055 1056 list_add_tail(&spec_eth_outer.list, &rule.list); 1057 list_add_tail(&spec_vxlan.list, &rule.list); 1058 list_add_tail(&spec_eth_inner.list, &rule.list); 1059 1060 err = mlx4_flow_attach(dev, &rule, reg_id); 1061 return err; 1062 } 1063 EXPORT_SYMBOL(mlx4_tunnel_steer_add); 1064 1065 int mlx4_FLOW_STEERING_IB_UC_QP_RANGE(struct mlx4_dev *dev, u32 min_range_qpn, 1066 u32 max_range_qpn) 1067 { 1068 int err; 1069 u64 in_param; 1070 1071 in_param = ((u64) min_range_qpn) << 32; 1072 in_param |= ((u64) max_range_qpn) & 0xFFFFFFFF; 1073 1074 err = mlx4_cmd(dev, in_param, 0, 0, 1075 MLX4_FLOW_STEERING_IB_UC_QP_RANGE, 1076 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 1077 1078 return err; 1079 } 1080 EXPORT_SYMBOL_GPL(mlx4_FLOW_STEERING_IB_UC_QP_RANGE); 1081 1082 int mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 1083 int block_mcast_loopback, enum mlx4_protocol prot, 1084 enum mlx4_steer_type steer) 1085 { 1086 struct mlx4_priv *priv = mlx4_priv(dev); 1087 struct mlx4_cmd_mailbox *mailbox; 1088 struct mlx4_mgm *mgm; 1089 u32 members_count; 1090 int index, prev; 1091 int link = 0; 1092 int i; 1093 int err; 1094 u8 port = gid[5]; 1095 u8 new_entry = 0; 1096 1097 mailbox = mlx4_alloc_cmd_mailbox(dev); 1098 if (IS_ERR(mailbox)) 1099 return PTR_ERR(mailbox); 1100 mgm = mailbox->buf; 1101 1102 mutex_lock(&priv->mcg_table.mutex); 1103 err = find_entry(dev, port, gid, prot, 1104 mailbox, &prev, &index); 1105 if (err) 1106 goto out; 1107 1108 if (index != -1) { 1109 if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) { 1110 new_entry = 1; 1111 memcpy(mgm->gid, gid, 16); 1112 } 1113 } else { 1114 link = 1; 1115 1116 index = mlx4_bitmap_alloc(&priv->mcg_table.bitmap); 1117 if (index == -1) { 1118 mlx4_err(dev, "No AMGM entries left\n"); 1119 err = -ENOMEM; 1120 goto out; 1121 } 1122 index += dev->caps.num_mgms; 1123 1124 new_entry = 1; 1125 memset(mgm, 0, sizeof *mgm); 1126 memcpy(mgm->gid, gid, 16); 1127 } 1128 1129 members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 1130 if (members_count == dev->caps.num_qp_per_mgm) { 1131 mlx4_err(dev, "MGM at index %x is full\n", index); 1132 err = -ENOMEM; 1133 goto out; 1134 } 1135 1136 for (i = 0; i < members_count; ++i) 1137 if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) { 1138 mlx4_dbg(dev, "QP %06x already a member of MGM\n", qp->qpn); 1139 err = 0; 1140 goto out; 1141 } 1142 1143 if (block_mcast_loopback) 1144 mgm->qp[members_count++] = cpu_to_be32((qp->qpn & MGM_QPN_MASK) | 1145 (1U << MGM_BLCK_LB_BIT)); 1146 else 1147 mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK); 1148 1149 mgm->members_count = cpu_to_be32(members_count | (u32) prot << 30); 1150 1151 err = mlx4_WRITE_ENTRY(dev, index, mailbox); 1152 if (err) 1153 goto out; 1154 1155 if (!link) 1156 goto out; 1157 1158 err = mlx4_READ_ENTRY(dev, prev, mailbox); 1159 if (err) 1160 goto out; 1161 1162 mgm->next_gid_index = cpu_to_be32(index << 6); 1163 1164 err = mlx4_WRITE_ENTRY(dev, prev, mailbox); 1165 if (err) 1166 goto out; 1167 1168 out: 1169 if (prot == MLX4_PROT_ETH) { 1170 /* manage the steering entry for promisc mode */ 1171 if (new_entry) 1172 new_steering_entry(dev, port, steer, index, qp->qpn); 1173 else 1174 existing_steering_entry(dev, port, steer, 1175 index, qp->qpn); 1176 } 1177 if (err && link && index != -1) { 1178 if (index < dev->caps.num_mgms) 1179 mlx4_warn(dev, "Got AMGM index %d < %d\n", 1180 index, dev->caps.num_mgms); 1181 else 1182 mlx4_bitmap_free(&priv->mcg_table.bitmap, 1183 index - dev->caps.num_mgms, MLX4_USE_RR); 1184 } 1185 mutex_unlock(&priv->mcg_table.mutex); 1186 1187 mlx4_free_cmd_mailbox(dev, mailbox); 1188 return err; 1189 } 1190 1191 int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 1192 enum mlx4_protocol prot, enum mlx4_steer_type steer) 1193 { 1194 struct mlx4_priv *priv = mlx4_priv(dev); 1195 struct mlx4_cmd_mailbox *mailbox; 1196 struct mlx4_mgm *mgm; 1197 u32 members_count; 1198 int prev, index; 1199 int i, loc = -1; 1200 int err; 1201 u8 port = gid[5]; 1202 bool removed_entry = false; 1203 1204 mailbox = mlx4_alloc_cmd_mailbox(dev); 1205 if (IS_ERR(mailbox)) 1206 return PTR_ERR(mailbox); 1207 mgm = mailbox->buf; 1208 1209 mutex_lock(&priv->mcg_table.mutex); 1210 1211 err = find_entry(dev, port, gid, prot, 1212 mailbox, &prev, &index); 1213 if (err) 1214 goto out; 1215 1216 if (index == -1) { 1217 mlx4_err(dev, "MGID %pI6 not found\n", gid); 1218 err = -EINVAL; 1219 goto out; 1220 } 1221 1222 /* If this QP is also a promisc QP, it shouldn't be removed only if 1223 * at least one none promisc QP is also attached to this MCG 1224 */ 1225 if (prot == MLX4_PROT_ETH && 1226 check_duplicate_entry(dev, port, steer, index, qp->qpn) && 1227 !promisc_steering_entry(dev, port, steer, index, qp->qpn, NULL)) 1228 goto out; 1229 1230 members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 1231 for (i = 0; i < members_count; ++i) 1232 if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) { 1233 loc = i; 1234 break; 1235 } 1236 1237 if (loc == -1) { 1238 mlx4_err(dev, "QP %06x not found in MGM\n", qp->qpn); 1239 err = -EINVAL; 1240 goto out; 1241 } 1242 1243 /* copy the last QP in this MGM over removed QP */ 1244 mgm->qp[loc] = mgm->qp[members_count - 1]; 1245 mgm->qp[members_count - 1] = 0; 1246 mgm->members_count = cpu_to_be32(--members_count | (u32) prot << 30); 1247 1248 if (prot == MLX4_PROT_ETH) 1249 removed_entry = can_remove_steering_entry(dev, port, steer, 1250 index, qp->qpn); 1251 if (members_count && (prot != MLX4_PROT_ETH || !removed_entry)) { 1252 err = mlx4_WRITE_ENTRY(dev, index, mailbox); 1253 goto out; 1254 } 1255 1256 /* We are going to delete the entry, members count should be 0 */ 1257 mgm->members_count = cpu_to_be32((u32) prot << 30); 1258 1259 if (prev == -1) { 1260 /* Remove entry from MGM */ 1261 int amgm_index = be32_to_cpu(mgm->next_gid_index) >> 6; 1262 if (amgm_index) { 1263 err = mlx4_READ_ENTRY(dev, amgm_index, mailbox); 1264 if (err) 1265 goto out; 1266 } else 1267 memset(mgm->gid, 0, 16); 1268 1269 err = mlx4_WRITE_ENTRY(dev, index, mailbox); 1270 if (err) 1271 goto out; 1272 1273 if (amgm_index) { 1274 if (amgm_index < dev->caps.num_mgms) 1275 mlx4_warn(dev, "MGM entry %d had AMGM index %d < %d\n", 1276 index, amgm_index, dev->caps.num_mgms); 1277 else 1278 mlx4_bitmap_free(&priv->mcg_table.bitmap, 1279 amgm_index - dev->caps.num_mgms, MLX4_USE_RR); 1280 } 1281 } else { 1282 /* Remove entry from AMGM */ 1283 int cur_next_index = be32_to_cpu(mgm->next_gid_index) >> 6; 1284 err = mlx4_READ_ENTRY(dev, prev, mailbox); 1285 if (err) 1286 goto out; 1287 1288 mgm->next_gid_index = cpu_to_be32(cur_next_index << 6); 1289 1290 err = mlx4_WRITE_ENTRY(dev, prev, mailbox); 1291 if (err) 1292 goto out; 1293 1294 if (index < dev->caps.num_mgms) 1295 mlx4_warn(dev, "entry %d had next AMGM index %d < %d\n", 1296 prev, index, dev->caps.num_mgms); 1297 else 1298 mlx4_bitmap_free(&priv->mcg_table.bitmap, 1299 index - dev->caps.num_mgms, MLX4_USE_RR); 1300 } 1301 1302 out: 1303 mutex_unlock(&priv->mcg_table.mutex); 1304 1305 mlx4_free_cmd_mailbox(dev, mailbox); 1306 return err; 1307 } 1308 1309 static int mlx4_QP_ATTACH(struct mlx4_dev *dev, struct mlx4_qp *qp, 1310 u8 gid[16], u8 attach, u8 block_loopback, 1311 enum mlx4_protocol prot) 1312 { 1313 struct mlx4_cmd_mailbox *mailbox; 1314 int err = 0; 1315 int qpn; 1316 1317 if (!mlx4_is_mfunc(dev)) 1318 return -EBADF; 1319 1320 mailbox = mlx4_alloc_cmd_mailbox(dev); 1321 if (IS_ERR(mailbox)) 1322 return PTR_ERR(mailbox); 1323 1324 memcpy(mailbox->buf, gid, 16); 1325 qpn = qp->qpn; 1326 qpn |= (prot << 28); 1327 if (attach && block_loopback) 1328 qpn |= (1 << 31); 1329 1330 err = mlx4_cmd(dev, mailbox->dma, qpn, attach, 1331 MLX4_CMD_QP_ATTACH, MLX4_CMD_TIME_CLASS_A, 1332 MLX4_CMD_WRAPPED); 1333 1334 mlx4_free_cmd_mailbox(dev, mailbox); 1335 return err; 1336 } 1337 1338 int mlx4_trans_to_dmfs_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, 1339 u8 gid[16], u8 port, 1340 int block_mcast_loopback, 1341 enum mlx4_protocol prot, u64 *reg_id) 1342 { 1343 struct mlx4_spec_list spec = { {NULL} }; 1344 __be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16); 1345 1346 struct mlx4_net_trans_rule rule = { 1347 .queue_mode = MLX4_NET_TRANS_Q_FIFO, 1348 .exclusive = 0, 1349 .promisc_mode = MLX4_FS_REGULAR, 1350 .priority = MLX4_DOMAIN_NIC, 1351 }; 1352 1353 rule.allow_loopback = !block_mcast_loopback; 1354 rule.port = port; 1355 rule.qpn = qp->qpn; 1356 INIT_LIST_HEAD(&rule.list); 1357 1358 switch (prot) { 1359 case MLX4_PROT_ETH: 1360 spec.id = MLX4_NET_TRANS_RULE_ID_ETH; 1361 memcpy(spec.eth.dst_mac, &gid[10], ETH_ALEN); 1362 memcpy(spec.eth.dst_mac_msk, &mac_mask, ETH_ALEN); 1363 break; 1364 1365 case MLX4_PROT_IB_IPV6: 1366 spec.id = MLX4_NET_TRANS_RULE_ID_IB; 1367 memcpy(spec.ib.dst_gid, gid, 16); 1368 memset(&spec.ib.dst_gid_msk, 0xff, 16); 1369 break; 1370 default: 1371 return -EINVAL; 1372 } 1373 list_add_tail(&spec.list, &rule.list); 1374 1375 return mlx4_flow_attach(dev, &rule, reg_id); 1376 } 1377 1378 int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 1379 u8 port, int block_mcast_loopback, 1380 enum mlx4_protocol prot, u64 *reg_id) 1381 { 1382 switch (dev->caps.steering_mode) { 1383 case MLX4_STEERING_MODE_A0: 1384 if (prot == MLX4_PROT_ETH) 1385 return 0; 1386 1387 case MLX4_STEERING_MODE_B0: 1388 if (prot == MLX4_PROT_ETH) 1389 gid[7] |= (MLX4_MC_STEER << 1); 1390 1391 if (mlx4_is_mfunc(dev)) 1392 return mlx4_QP_ATTACH(dev, qp, gid, 1, 1393 block_mcast_loopback, prot); 1394 return mlx4_qp_attach_common(dev, qp, gid, 1395 block_mcast_loopback, prot, 1396 MLX4_MC_STEER); 1397 1398 case MLX4_STEERING_MODE_DEVICE_MANAGED: 1399 return mlx4_trans_to_dmfs_attach(dev, qp, gid, port, 1400 block_mcast_loopback, 1401 prot, reg_id); 1402 default: 1403 return -EINVAL; 1404 } 1405 } 1406 EXPORT_SYMBOL_GPL(mlx4_multicast_attach); 1407 1408 int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 1409 enum mlx4_protocol prot, u64 reg_id) 1410 { 1411 switch (dev->caps.steering_mode) { 1412 case MLX4_STEERING_MODE_A0: 1413 if (prot == MLX4_PROT_ETH) 1414 return 0; 1415 1416 case MLX4_STEERING_MODE_B0: 1417 if (prot == MLX4_PROT_ETH) 1418 gid[7] |= (MLX4_MC_STEER << 1); 1419 1420 if (mlx4_is_mfunc(dev)) 1421 return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot); 1422 1423 return mlx4_qp_detach_common(dev, qp, gid, prot, 1424 MLX4_MC_STEER); 1425 1426 case MLX4_STEERING_MODE_DEVICE_MANAGED: 1427 return mlx4_flow_detach(dev, reg_id); 1428 1429 default: 1430 return -EINVAL; 1431 } 1432 } 1433 EXPORT_SYMBOL_GPL(mlx4_multicast_detach); 1434 1435 int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port, 1436 u32 qpn, enum mlx4_net_trans_promisc_mode mode) 1437 { 1438 struct mlx4_net_trans_rule rule; 1439 u64 *regid_p; 1440 1441 switch (mode) { 1442 case MLX4_FS_ALL_DEFAULT: 1443 regid_p = &dev->regid_promisc_array[port]; 1444 break; 1445 case MLX4_FS_MC_DEFAULT: 1446 regid_p = &dev->regid_allmulti_array[port]; 1447 break; 1448 default: 1449 return -1; 1450 } 1451 1452 if (*regid_p != 0) 1453 return -1; 1454 1455 rule.promisc_mode = mode; 1456 rule.port = port; 1457 rule.qpn = qpn; 1458 INIT_LIST_HEAD(&rule.list); 1459 mlx4_err(dev, "going promisc on %x\n", port); 1460 1461 return mlx4_flow_attach(dev, &rule, regid_p); 1462 } 1463 EXPORT_SYMBOL_GPL(mlx4_flow_steer_promisc_add); 1464 1465 int mlx4_flow_steer_promisc_remove(struct mlx4_dev *dev, u8 port, 1466 enum mlx4_net_trans_promisc_mode mode) 1467 { 1468 int ret; 1469 u64 *regid_p; 1470 1471 switch (mode) { 1472 case MLX4_FS_ALL_DEFAULT: 1473 regid_p = &dev->regid_promisc_array[port]; 1474 break; 1475 case MLX4_FS_MC_DEFAULT: 1476 regid_p = &dev->regid_allmulti_array[port]; 1477 break; 1478 default: 1479 return -1; 1480 } 1481 1482 if (*regid_p == 0) 1483 return -1; 1484 1485 ret = mlx4_flow_detach(dev, *regid_p); 1486 if (ret == 0) 1487 *regid_p = 0; 1488 1489 return ret; 1490 } 1491 EXPORT_SYMBOL_GPL(mlx4_flow_steer_promisc_remove); 1492 1493 int mlx4_unicast_attach(struct mlx4_dev *dev, 1494 struct mlx4_qp *qp, u8 gid[16], 1495 int block_mcast_loopback, enum mlx4_protocol prot) 1496 { 1497 if (prot == MLX4_PROT_ETH) 1498 gid[7] |= (MLX4_UC_STEER << 1); 1499 1500 if (mlx4_is_mfunc(dev)) 1501 return mlx4_QP_ATTACH(dev, qp, gid, 1, 1502 block_mcast_loopback, prot); 1503 1504 return mlx4_qp_attach_common(dev, qp, gid, block_mcast_loopback, 1505 prot, MLX4_UC_STEER); 1506 } 1507 EXPORT_SYMBOL_GPL(mlx4_unicast_attach); 1508 1509 int mlx4_unicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, 1510 u8 gid[16], enum mlx4_protocol prot) 1511 { 1512 if (prot == MLX4_PROT_ETH) 1513 gid[7] |= (MLX4_UC_STEER << 1); 1514 1515 if (mlx4_is_mfunc(dev)) 1516 return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot); 1517 1518 return mlx4_qp_detach_common(dev, qp, gid, prot, MLX4_UC_STEER); 1519 } 1520 EXPORT_SYMBOL_GPL(mlx4_unicast_detach); 1521 1522 int mlx4_PROMISC_wrapper(struct mlx4_dev *dev, int slave, 1523 struct mlx4_vhcr *vhcr, 1524 struct mlx4_cmd_mailbox *inbox, 1525 struct mlx4_cmd_mailbox *outbox, 1526 struct mlx4_cmd_info *cmd) 1527 { 1528 u32 qpn = (u32) vhcr->in_param & 0xffffffff; 1529 int port = mlx4_slave_convert_port(dev, slave, vhcr->in_param >> 62); 1530 enum mlx4_steer_type steer = vhcr->in_modifier; 1531 1532 if (port < 0) 1533 return -EINVAL; 1534 1535 /* Promiscuous unicast is not allowed in mfunc */ 1536 if (mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER) 1537 return 0; 1538 1539 if (vhcr->op_modifier) 1540 return add_promisc_qp(dev, port, steer, qpn); 1541 else 1542 return remove_promisc_qp(dev, port, steer, qpn); 1543 } 1544 1545 static int mlx4_PROMISC(struct mlx4_dev *dev, u32 qpn, 1546 enum mlx4_steer_type steer, u8 add, u8 port) 1547 { 1548 return mlx4_cmd(dev, (u64) qpn | (u64) port << 62, (u32) steer, add, 1549 MLX4_CMD_PROMISC, MLX4_CMD_TIME_CLASS_A, 1550 MLX4_CMD_WRAPPED); 1551 } 1552 1553 int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) 1554 { 1555 if (mlx4_is_mfunc(dev)) 1556 return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 1, port); 1557 1558 return add_promisc_qp(dev, port, MLX4_MC_STEER, qpn); 1559 } 1560 EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_add); 1561 1562 int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) 1563 { 1564 if (mlx4_is_mfunc(dev)) 1565 return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 0, port); 1566 1567 return remove_promisc_qp(dev, port, MLX4_MC_STEER, qpn); 1568 } 1569 EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_remove); 1570 1571 int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) 1572 { 1573 if (mlx4_is_mfunc(dev)) 1574 return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 1, port); 1575 1576 return add_promisc_qp(dev, port, MLX4_UC_STEER, qpn); 1577 } 1578 EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_add); 1579 1580 int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) 1581 { 1582 if (mlx4_is_mfunc(dev)) 1583 return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 0, port); 1584 1585 return remove_promisc_qp(dev, port, MLX4_UC_STEER, qpn); 1586 } 1587 EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_remove); 1588 1589 int mlx4_init_mcg_table(struct mlx4_dev *dev) 1590 { 1591 struct mlx4_priv *priv = mlx4_priv(dev); 1592 int err; 1593 1594 /* No need for mcg_table when fw managed the mcg table*/ 1595 if (dev->caps.steering_mode == 1596 MLX4_STEERING_MODE_DEVICE_MANAGED) 1597 return 0; 1598 err = mlx4_bitmap_init(&priv->mcg_table.bitmap, dev->caps.num_amgms, 1599 dev->caps.num_amgms - 1, 0, 0); 1600 if (err) 1601 return err; 1602 1603 mutex_init(&priv->mcg_table.mutex); 1604 1605 return 0; 1606 } 1607 1608 void mlx4_cleanup_mcg_table(struct mlx4_dev *dev) 1609 { 1610 if (dev->caps.steering_mode != 1611 MLX4_STEERING_MODE_DEVICE_MANAGED) 1612 mlx4_bitmap_cleanup(&mlx4_priv(dev)->mcg_table.bitmap); 1613 } 1614