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 #define MGM_QPN_MASK 0x00FFFFFF 43 #define MGM_BLCK_LB_BIT 30 44 45 static const u8 zero_gid[16]; /* automatically initialized to 0 */ 46 47 struct mlx4_mgm { 48 __be32 next_gid_index; 49 __be32 members_count; 50 u32 reserved[2]; 51 u8 gid[16]; 52 __be32 qp[MLX4_MAX_QP_PER_MGM]; 53 }; 54 55 int mlx4_get_mgm_entry_size(struct mlx4_dev *dev) 56 { 57 return min((1 << mlx4_log_num_mgm_entry_size), MLX4_MAX_MGM_ENTRY_SIZE); 58 } 59 60 int mlx4_get_qp_per_mgm(struct mlx4_dev *dev) 61 { 62 return 4 * (mlx4_get_mgm_entry_size(dev) / 16 - 2); 63 } 64 65 static int mlx4_READ_ENTRY(struct mlx4_dev *dev, int index, 66 struct mlx4_cmd_mailbox *mailbox) 67 { 68 return mlx4_cmd_box(dev, 0, mailbox->dma, index, 0, MLX4_CMD_READ_MCG, 69 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 70 } 71 72 static int mlx4_WRITE_ENTRY(struct mlx4_dev *dev, int index, 73 struct mlx4_cmd_mailbox *mailbox) 74 { 75 return mlx4_cmd(dev, mailbox->dma, index, 0, MLX4_CMD_WRITE_MCG, 76 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 77 } 78 79 static int mlx4_WRITE_PROMISC(struct mlx4_dev *dev, u8 port, u8 steer, 80 struct mlx4_cmd_mailbox *mailbox) 81 { 82 u32 in_mod; 83 84 in_mod = (u32) port << 16 | steer << 1; 85 return mlx4_cmd(dev, mailbox->dma, in_mod, 0x1, 86 MLX4_CMD_WRITE_MCG, MLX4_CMD_TIME_CLASS_A, 87 MLX4_CMD_NATIVE); 88 } 89 90 static int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, 91 u16 *hash, u8 op_mod) 92 { 93 u64 imm; 94 int err; 95 96 err = mlx4_cmd_imm(dev, mailbox->dma, &imm, 0, op_mod, 97 MLX4_CMD_MGID_HASH, MLX4_CMD_TIME_CLASS_A, 98 MLX4_CMD_NATIVE); 99 100 if (!err) 101 *hash = imm; 102 103 return err; 104 } 105 106 static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 pf_num, 107 enum mlx4_steer_type steer, 108 u32 qpn) 109 { 110 struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[pf_num]; 111 struct mlx4_promisc_qp *pqp; 112 113 list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { 114 if (pqp->qpn == qpn) 115 return pqp; 116 } 117 /* not found */ 118 return NULL; 119 } 120 121 /* 122 * Add new entry to steering data structure. 123 * All promisc QPs should be added as well 124 */ 125 static int new_steering_entry(struct mlx4_dev *dev, u8 port, 126 enum mlx4_steer_type steer, 127 unsigned int index, u32 qpn) 128 { 129 struct mlx4_steer *s_steer; 130 struct mlx4_cmd_mailbox *mailbox; 131 struct mlx4_mgm *mgm; 132 u32 members_count; 133 struct mlx4_steer_index *new_entry; 134 struct mlx4_promisc_qp *pqp; 135 struct mlx4_promisc_qp *dqp = NULL; 136 u32 prot; 137 int err; 138 139 s_steer = &mlx4_priv(dev)->steer[port - 1]; 140 new_entry = kzalloc(sizeof *new_entry, GFP_KERNEL); 141 if (!new_entry) 142 return -ENOMEM; 143 144 INIT_LIST_HEAD(&new_entry->duplicates); 145 new_entry->index = index; 146 list_add_tail(&new_entry->list, &s_steer->steer_entries[steer]); 147 148 /* If the given qpn is also a promisc qp, 149 * it should be inserted to duplicates list 150 */ 151 pqp = get_promisc_qp(dev, 0, steer, qpn); 152 if (pqp) { 153 dqp = kmalloc(sizeof *dqp, GFP_KERNEL); 154 if (!dqp) { 155 err = -ENOMEM; 156 goto out_alloc; 157 } 158 dqp->qpn = qpn; 159 list_add_tail(&dqp->list, &new_entry->duplicates); 160 } 161 162 /* if no promisc qps for this vep, we are done */ 163 if (list_empty(&s_steer->promisc_qps[steer])) 164 return 0; 165 166 /* now need to add all the promisc qps to the new 167 * steering entry, as they should also receive the packets 168 * destined to this address */ 169 mailbox = mlx4_alloc_cmd_mailbox(dev); 170 if (IS_ERR(mailbox)) { 171 err = -ENOMEM; 172 goto out_alloc; 173 } 174 mgm = mailbox->buf; 175 176 err = mlx4_READ_ENTRY(dev, index, mailbox); 177 if (err) 178 goto out_mailbox; 179 180 members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 181 prot = be32_to_cpu(mgm->members_count) >> 30; 182 list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { 183 /* don't add already existing qpn */ 184 if (pqp->qpn == qpn) 185 continue; 186 if (members_count == dev->caps.num_qp_per_mgm) { 187 /* out of space */ 188 err = -ENOMEM; 189 goto out_mailbox; 190 } 191 192 /* add the qpn */ 193 mgm->qp[members_count++] = cpu_to_be32(pqp->qpn & MGM_QPN_MASK); 194 } 195 /* update the qps count and update the entry with all the promisc qps*/ 196 mgm->members_count = cpu_to_be32(members_count | (prot << 30)); 197 err = mlx4_WRITE_ENTRY(dev, index, mailbox); 198 199 out_mailbox: 200 mlx4_free_cmd_mailbox(dev, mailbox); 201 if (!err) 202 return 0; 203 out_alloc: 204 if (dqp) { 205 list_del(&dqp->list); 206 kfree(dqp); 207 } 208 list_del(&new_entry->list); 209 kfree(new_entry); 210 return err; 211 } 212 213 /* update the data structures with existing steering entry */ 214 static int existing_steering_entry(struct mlx4_dev *dev, u8 port, 215 enum mlx4_steer_type steer, 216 unsigned int index, u32 qpn) 217 { 218 struct mlx4_steer *s_steer; 219 struct mlx4_steer_index *tmp_entry, *entry = NULL; 220 struct mlx4_promisc_qp *pqp; 221 struct mlx4_promisc_qp *dqp; 222 223 s_steer = &mlx4_priv(dev)->steer[port - 1]; 224 225 pqp = get_promisc_qp(dev, 0, steer, qpn); 226 if (!pqp) 227 return 0; /* nothing to do */ 228 229 list_for_each_entry(tmp_entry, &s_steer->steer_entries[steer], list) { 230 if (tmp_entry->index == index) { 231 entry = tmp_entry; 232 break; 233 } 234 } 235 if (unlikely(!entry)) { 236 mlx4_warn(dev, "Steering entry at index %x is not registered\n", index); 237 return -EINVAL; 238 } 239 240 /* the given qpn is listed as a promisc qpn 241 * we need to add it as a duplicate to this entry 242 * for future references */ 243 list_for_each_entry(dqp, &entry->duplicates, list) { 244 if (qpn == pqp->qpn) 245 return 0; /* qp is already duplicated */ 246 } 247 248 /* add the qp as a duplicate on this index */ 249 dqp = kmalloc(sizeof *dqp, GFP_KERNEL); 250 if (!dqp) 251 return -ENOMEM; 252 dqp->qpn = qpn; 253 list_add_tail(&dqp->list, &entry->duplicates); 254 255 return 0; 256 } 257 258 /* Check whether a qpn is a duplicate on steering entry 259 * If so, it should not be removed from mgm */ 260 static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port, 261 enum mlx4_steer_type steer, 262 unsigned int index, u32 qpn) 263 { 264 struct mlx4_steer *s_steer; 265 struct mlx4_steer_index *tmp_entry, *entry = NULL; 266 struct mlx4_promisc_qp *dqp, *tmp_dqp; 267 268 s_steer = &mlx4_priv(dev)->steer[port - 1]; 269 270 /* if qp is not promisc, it cannot be duplicated */ 271 if (!get_promisc_qp(dev, 0, steer, qpn)) 272 return false; 273 274 /* The qp is promisc qp so it is a duplicate on this index 275 * Find the index entry, and remove the duplicate */ 276 list_for_each_entry(tmp_entry, &s_steer->steer_entries[steer], list) { 277 if (tmp_entry->index == index) { 278 entry = tmp_entry; 279 break; 280 } 281 } 282 if (unlikely(!entry)) { 283 mlx4_warn(dev, "Steering entry for index %x is not registered\n", index); 284 return false; 285 } 286 list_for_each_entry_safe(dqp, tmp_dqp, &entry->duplicates, list) { 287 if (dqp->qpn == qpn) { 288 list_del(&dqp->list); 289 kfree(dqp); 290 } 291 } 292 return true; 293 } 294 295 /* I a steering entry contains only promisc QPs, it can be removed. */ 296 static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port, 297 enum mlx4_steer_type steer, 298 unsigned int index, u32 tqpn) 299 { 300 struct mlx4_steer *s_steer; 301 struct mlx4_cmd_mailbox *mailbox; 302 struct mlx4_mgm *mgm; 303 struct mlx4_steer_index *entry = NULL, *tmp_entry; 304 u32 qpn; 305 u32 members_count; 306 bool ret = false; 307 int i; 308 309 s_steer = &mlx4_priv(dev)->steer[port - 1]; 310 311 mailbox = mlx4_alloc_cmd_mailbox(dev); 312 if (IS_ERR(mailbox)) 313 return false; 314 mgm = mailbox->buf; 315 316 if (mlx4_READ_ENTRY(dev, index, mailbox)) 317 goto out; 318 members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 319 for (i = 0; i < members_count; i++) { 320 qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK; 321 if (!get_promisc_qp(dev, 0, steer, qpn) && qpn != tqpn) { 322 /* the qp is not promisc, the entry can't be removed */ 323 goto out; 324 } 325 } 326 /* All the qps currently registered for this entry are promiscuous, 327 * Checking for duplicates */ 328 ret = true; 329 list_for_each_entry_safe(entry, tmp_entry, &s_steer->steer_entries[steer], list) { 330 if (entry->index == index) { 331 if (list_empty(&entry->duplicates)) { 332 list_del(&entry->list); 333 kfree(entry); 334 } else { 335 /* This entry contains duplicates so it shouldn't be removed */ 336 ret = false; 337 goto out; 338 } 339 } 340 } 341 342 out: 343 mlx4_free_cmd_mailbox(dev, mailbox); 344 return ret; 345 } 346 347 static int add_promisc_qp(struct mlx4_dev *dev, u8 port, 348 enum mlx4_steer_type steer, u32 qpn) 349 { 350 struct mlx4_steer *s_steer; 351 struct mlx4_cmd_mailbox *mailbox; 352 struct mlx4_mgm *mgm; 353 struct mlx4_steer_index *entry; 354 struct mlx4_promisc_qp *pqp; 355 struct mlx4_promisc_qp *dqp; 356 u32 members_count; 357 u32 prot; 358 int i; 359 bool found; 360 int err; 361 struct mlx4_priv *priv = mlx4_priv(dev); 362 363 s_steer = &mlx4_priv(dev)->steer[port - 1]; 364 365 mutex_lock(&priv->mcg_table.mutex); 366 367 if (get_promisc_qp(dev, 0, steer, qpn)) { 368 err = 0; /* Noting to do, already exists */ 369 goto out_mutex; 370 } 371 372 pqp = kmalloc(sizeof *pqp, GFP_KERNEL); 373 if (!pqp) { 374 err = -ENOMEM; 375 goto out_mutex; 376 } 377 pqp->qpn = qpn; 378 379 mailbox = mlx4_alloc_cmd_mailbox(dev); 380 if (IS_ERR(mailbox)) { 381 err = -ENOMEM; 382 goto out_alloc; 383 } 384 mgm = mailbox->buf; 385 386 /* the promisc qp needs to be added for each one of the steering 387 * entries, if it already exists, needs to be added as a duplicate 388 * for this entry */ 389 list_for_each_entry(entry, &s_steer->steer_entries[steer], list) { 390 err = mlx4_READ_ENTRY(dev, entry->index, mailbox); 391 if (err) 392 goto out_mailbox; 393 394 members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 395 prot = be32_to_cpu(mgm->members_count) >> 30; 396 found = false; 397 for (i = 0; i < members_count; i++) { 398 if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) { 399 /* Entry already exists, add to duplicates */ 400 dqp = kmalloc(sizeof *dqp, GFP_KERNEL); 401 if (!dqp) 402 goto out_mailbox; 403 dqp->qpn = qpn; 404 list_add_tail(&dqp->list, &entry->duplicates); 405 found = true; 406 } 407 } 408 if (!found) { 409 /* Need to add the qpn to mgm */ 410 if (members_count == dev->caps.num_qp_per_mgm) { 411 /* entry is full */ 412 err = -ENOMEM; 413 goto out_mailbox; 414 } 415 mgm->qp[members_count++] = cpu_to_be32(qpn & MGM_QPN_MASK); 416 mgm->members_count = cpu_to_be32(members_count | (prot << 30)); 417 err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox); 418 if (err) 419 goto out_mailbox; 420 } 421 } 422 423 /* add the new qpn to list of promisc qps */ 424 list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]); 425 /* now need to add all the promisc qps to default entry */ 426 memset(mgm, 0, sizeof *mgm); 427 members_count = 0; 428 list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list) 429 mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK); 430 mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30); 431 432 err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox); 433 if (err) 434 goto out_list; 435 436 mlx4_free_cmd_mailbox(dev, mailbox); 437 mutex_unlock(&priv->mcg_table.mutex); 438 return 0; 439 440 out_list: 441 list_del(&pqp->list); 442 out_mailbox: 443 mlx4_free_cmd_mailbox(dev, mailbox); 444 out_alloc: 445 kfree(pqp); 446 out_mutex: 447 mutex_unlock(&priv->mcg_table.mutex); 448 return err; 449 } 450 451 static int remove_promisc_qp(struct mlx4_dev *dev, u8 port, 452 enum mlx4_steer_type steer, u32 qpn) 453 { 454 struct mlx4_priv *priv = mlx4_priv(dev); 455 struct mlx4_steer *s_steer; 456 struct mlx4_cmd_mailbox *mailbox; 457 struct mlx4_mgm *mgm; 458 struct mlx4_steer_index *entry; 459 struct mlx4_promisc_qp *pqp; 460 struct mlx4_promisc_qp *dqp; 461 u32 members_count; 462 bool found; 463 bool back_to_list = false; 464 int loc, i; 465 int err; 466 467 s_steer = &mlx4_priv(dev)->steer[port - 1]; 468 mutex_lock(&priv->mcg_table.mutex); 469 470 pqp = get_promisc_qp(dev, 0, steer, qpn); 471 if (unlikely(!pqp)) { 472 mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn); 473 /* nothing to do */ 474 err = 0; 475 goto out_mutex; 476 } 477 478 /*remove from list of promisc qps */ 479 list_del(&pqp->list); 480 481 /* set the default entry not to include the removed one */ 482 mailbox = mlx4_alloc_cmd_mailbox(dev); 483 if (IS_ERR(mailbox)) { 484 err = -ENOMEM; 485 back_to_list = true; 486 goto out_list; 487 } 488 mgm = mailbox->buf; 489 memset(mgm, 0, sizeof *mgm); 490 members_count = 0; 491 list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list) 492 mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK); 493 mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30); 494 495 err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox); 496 if (err) 497 goto out_mailbox; 498 499 /* remove the qp from all the steering entries*/ 500 list_for_each_entry(entry, &s_steer->steer_entries[steer], list) { 501 found = false; 502 list_for_each_entry(dqp, &entry->duplicates, list) { 503 if (dqp->qpn == qpn) { 504 found = true; 505 break; 506 } 507 } 508 if (found) { 509 /* a duplicate, no need to change the mgm, 510 * only update the duplicates list */ 511 list_del(&dqp->list); 512 kfree(dqp); 513 } else { 514 err = mlx4_READ_ENTRY(dev, entry->index, mailbox); 515 if (err) 516 goto out_mailbox; 517 members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 518 for (loc = -1, i = 0; i < members_count; ++i) 519 if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) 520 loc = i; 521 522 mgm->members_count = cpu_to_be32(--members_count | 523 (MLX4_PROT_ETH << 30)); 524 mgm->qp[loc] = mgm->qp[i - 1]; 525 mgm->qp[i - 1] = 0; 526 527 err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox); 528 if (err) 529 goto out_mailbox; 530 } 531 532 } 533 534 out_mailbox: 535 mlx4_free_cmd_mailbox(dev, mailbox); 536 out_list: 537 if (back_to_list) 538 list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]); 539 else 540 kfree(pqp); 541 out_mutex: 542 mutex_unlock(&priv->mcg_table.mutex); 543 return err; 544 } 545 546 /* 547 * Caller must hold MCG table semaphore. gid and mgm parameters must 548 * be properly aligned for command interface. 549 * 550 * Returns 0 unless a firmware command error occurs. 551 * 552 * If GID is found in MGM or MGM is empty, *index = *hash, *prev = -1 553 * and *mgm holds MGM entry. 554 * 555 * if GID is found in AMGM, *index = index in AMGM, *prev = index of 556 * previous entry in hash chain and *mgm holds AMGM entry. 557 * 558 * If no AMGM exists for given gid, *index = -1, *prev = index of last 559 * entry in hash chain and *mgm holds end of hash chain. 560 */ 561 static int find_entry(struct mlx4_dev *dev, u8 port, 562 u8 *gid, enum mlx4_protocol prot, 563 struct mlx4_cmd_mailbox *mgm_mailbox, 564 int *prev, int *index) 565 { 566 struct mlx4_cmd_mailbox *mailbox; 567 struct mlx4_mgm *mgm = mgm_mailbox->buf; 568 u8 *mgid; 569 int err; 570 u16 hash; 571 u8 op_mod = (prot == MLX4_PROT_ETH) ? 572 !!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) : 0; 573 574 mailbox = mlx4_alloc_cmd_mailbox(dev); 575 if (IS_ERR(mailbox)) 576 return -ENOMEM; 577 mgid = mailbox->buf; 578 579 memcpy(mgid, gid, 16); 580 581 err = mlx4_GID_HASH(dev, mailbox, &hash, op_mod); 582 mlx4_free_cmd_mailbox(dev, mailbox); 583 if (err) 584 return err; 585 586 if (0) 587 mlx4_dbg(dev, "Hash for %pI6 is %04x\n", gid, hash); 588 589 *index = hash; 590 *prev = -1; 591 592 do { 593 err = mlx4_READ_ENTRY(dev, *index, mgm_mailbox); 594 if (err) 595 return err; 596 597 if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) { 598 if (*index != hash) { 599 mlx4_err(dev, "Found zero MGID in AMGM.\n"); 600 err = -EINVAL; 601 } 602 return err; 603 } 604 605 if (!memcmp(mgm->gid, gid, 16) && 606 be32_to_cpu(mgm->members_count) >> 30 == prot) 607 return err; 608 609 *prev = *index; 610 *index = be32_to_cpu(mgm->next_gid_index) >> 6; 611 } while (*index); 612 613 *index = -1; 614 return err; 615 } 616 617 int mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 618 int block_mcast_loopback, enum mlx4_protocol prot, 619 enum mlx4_steer_type steer) 620 { 621 struct mlx4_priv *priv = mlx4_priv(dev); 622 struct mlx4_cmd_mailbox *mailbox; 623 struct mlx4_mgm *mgm; 624 u32 members_count; 625 int index, prev; 626 int link = 0; 627 int i; 628 int err; 629 u8 port = gid[5]; 630 u8 new_entry = 0; 631 632 mailbox = mlx4_alloc_cmd_mailbox(dev); 633 if (IS_ERR(mailbox)) 634 return PTR_ERR(mailbox); 635 mgm = mailbox->buf; 636 637 mutex_lock(&priv->mcg_table.mutex); 638 err = find_entry(dev, port, gid, prot, 639 mailbox, &prev, &index); 640 if (err) 641 goto out; 642 643 if (index != -1) { 644 if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) { 645 new_entry = 1; 646 memcpy(mgm->gid, gid, 16); 647 } 648 } else { 649 link = 1; 650 651 index = mlx4_bitmap_alloc(&priv->mcg_table.bitmap); 652 if (index == -1) { 653 mlx4_err(dev, "No AMGM entries left\n"); 654 err = -ENOMEM; 655 goto out; 656 } 657 index += dev->caps.num_mgms; 658 659 new_entry = 1; 660 memset(mgm, 0, sizeof *mgm); 661 memcpy(mgm->gid, gid, 16); 662 } 663 664 members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 665 if (members_count == dev->caps.num_qp_per_mgm) { 666 mlx4_err(dev, "MGM at index %x is full.\n", index); 667 err = -ENOMEM; 668 goto out; 669 } 670 671 for (i = 0; i < members_count; ++i) 672 if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) { 673 mlx4_dbg(dev, "QP %06x already a member of MGM\n", qp->qpn); 674 err = 0; 675 goto out; 676 } 677 678 if (block_mcast_loopback) 679 mgm->qp[members_count++] = cpu_to_be32((qp->qpn & MGM_QPN_MASK) | 680 (1U << MGM_BLCK_LB_BIT)); 681 else 682 mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK); 683 684 mgm->members_count = cpu_to_be32(members_count | (u32) prot << 30); 685 686 err = mlx4_WRITE_ENTRY(dev, index, mailbox); 687 if (err) 688 goto out; 689 690 if (!link) 691 goto out; 692 693 err = mlx4_READ_ENTRY(dev, prev, mailbox); 694 if (err) 695 goto out; 696 697 mgm->next_gid_index = cpu_to_be32(index << 6); 698 699 err = mlx4_WRITE_ENTRY(dev, prev, mailbox); 700 if (err) 701 goto out; 702 703 out: 704 if (prot == MLX4_PROT_ETH) { 705 /* manage the steering entry for promisc mode */ 706 if (new_entry) 707 new_steering_entry(dev, port, steer, index, qp->qpn); 708 else 709 existing_steering_entry(dev, port, steer, 710 index, qp->qpn); 711 } 712 if (err && link && index != -1) { 713 if (index < dev->caps.num_mgms) 714 mlx4_warn(dev, "Got AMGM index %d < %d", 715 index, dev->caps.num_mgms); 716 else 717 mlx4_bitmap_free(&priv->mcg_table.bitmap, 718 index - dev->caps.num_mgms); 719 } 720 mutex_unlock(&priv->mcg_table.mutex); 721 722 mlx4_free_cmd_mailbox(dev, mailbox); 723 return err; 724 } 725 726 int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 727 enum mlx4_protocol prot, enum mlx4_steer_type steer) 728 { 729 struct mlx4_priv *priv = mlx4_priv(dev); 730 struct mlx4_cmd_mailbox *mailbox; 731 struct mlx4_mgm *mgm; 732 u32 members_count; 733 int prev, index; 734 int i, loc; 735 int err; 736 u8 port = gid[5]; 737 bool removed_entry = false; 738 739 mailbox = mlx4_alloc_cmd_mailbox(dev); 740 if (IS_ERR(mailbox)) 741 return PTR_ERR(mailbox); 742 mgm = mailbox->buf; 743 744 mutex_lock(&priv->mcg_table.mutex); 745 746 err = find_entry(dev, port, gid, prot, 747 mailbox, &prev, &index); 748 if (err) 749 goto out; 750 751 if (index == -1) { 752 mlx4_err(dev, "MGID %pI6 not found\n", gid); 753 err = -EINVAL; 754 goto out; 755 } 756 757 /* if this pq is also a promisc qp, it shouldn't be removed */ 758 if (prot == MLX4_PROT_ETH && 759 check_duplicate_entry(dev, port, steer, index, qp->qpn)) 760 goto out; 761 762 members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 763 for (loc = -1, i = 0; i < members_count; ++i) 764 if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) 765 loc = i; 766 767 if (loc == -1) { 768 mlx4_err(dev, "QP %06x not found in MGM\n", qp->qpn); 769 err = -EINVAL; 770 goto out; 771 } 772 773 774 mgm->members_count = cpu_to_be32(--members_count | (u32) prot << 30); 775 mgm->qp[loc] = mgm->qp[i - 1]; 776 mgm->qp[i - 1] = 0; 777 778 if (prot == MLX4_PROT_ETH) 779 removed_entry = can_remove_steering_entry(dev, port, steer, 780 index, qp->qpn); 781 if (i != 1 && (prot != MLX4_PROT_ETH || !removed_entry)) { 782 err = mlx4_WRITE_ENTRY(dev, index, mailbox); 783 goto out; 784 } 785 786 /* We are going to delete the entry, members count should be 0 */ 787 mgm->members_count = cpu_to_be32((u32) prot << 30); 788 789 if (prev == -1) { 790 /* Remove entry from MGM */ 791 int amgm_index = be32_to_cpu(mgm->next_gid_index) >> 6; 792 if (amgm_index) { 793 err = mlx4_READ_ENTRY(dev, amgm_index, mailbox); 794 if (err) 795 goto out; 796 } else 797 memset(mgm->gid, 0, 16); 798 799 err = mlx4_WRITE_ENTRY(dev, index, mailbox); 800 if (err) 801 goto out; 802 803 if (amgm_index) { 804 if (amgm_index < dev->caps.num_mgms) 805 mlx4_warn(dev, "MGM entry %d had AMGM index %d < %d", 806 index, amgm_index, dev->caps.num_mgms); 807 else 808 mlx4_bitmap_free(&priv->mcg_table.bitmap, 809 amgm_index - dev->caps.num_mgms); 810 } 811 } else { 812 /* Remove entry from AMGM */ 813 int cur_next_index = be32_to_cpu(mgm->next_gid_index) >> 6; 814 err = mlx4_READ_ENTRY(dev, prev, mailbox); 815 if (err) 816 goto out; 817 818 mgm->next_gid_index = cpu_to_be32(cur_next_index << 6); 819 820 err = mlx4_WRITE_ENTRY(dev, prev, mailbox); 821 if (err) 822 goto out; 823 824 if (index < dev->caps.num_mgms) 825 mlx4_warn(dev, "entry %d had next AMGM index %d < %d", 826 prev, index, dev->caps.num_mgms); 827 else 828 mlx4_bitmap_free(&priv->mcg_table.bitmap, 829 index - dev->caps.num_mgms); 830 } 831 832 out: 833 mutex_unlock(&priv->mcg_table.mutex); 834 835 mlx4_free_cmd_mailbox(dev, mailbox); 836 return err; 837 } 838 839 static int mlx4_QP_ATTACH(struct mlx4_dev *dev, struct mlx4_qp *qp, 840 u8 gid[16], u8 attach, u8 block_loopback, 841 enum mlx4_protocol prot) 842 { 843 struct mlx4_cmd_mailbox *mailbox; 844 int err = 0; 845 int qpn; 846 847 if (!mlx4_is_mfunc(dev)) 848 return -EBADF; 849 850 mailbox = mlx4_alloc_cmd_mailbox(dev); 851 if (IS_ERR(mailbox)) 852 return PTR_ERR(mailbox); 853 854 memcpy(mailbox->buf, gid, 16); 855 qpn = qp->qpn; 856 qpn |= (prot << 28); 857 if (attach && block_loopback) 858 qpn |= (1 << 31); 859 860 err = mlx4_cmd(dev, mailbox->dma, qpn, attach, 861 MLX4_CMD_QP_ATTACH, MLX4_CMD_TIME_CLASS_A, 862 MLX4_CMD_WRAPPED); 863 864 mlx4_free_cmd_mailbox(dev, mailbox); 865 return err; 866 } 867 868 int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 869 int block_mcast_loopback, enum mlx4_protocol prot) 870 { 871 if (prot == MLX4_PROT_ETH && 872 !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) 873 return 0; 874 875 if (prot == MLX4_PROT_ETH) 876 gid[7] |= (MLX4_MC_STEER << 1); 877 878 if (mlx4_is_mfunc(dev)) 879 return mlx4_QP_ATTACH(dev, qp, gid, 1, 880 block_mcast_loopback, prot); 881 882 return mlx4_qp_attach_common(dev, qp, gid, block_mcast_loopback, 883 prot, MLX4_MC_STEER); 884 } 885 EXPORT_SYMBOL_GPL(mlx4_multicast_attach); 886 887 int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 888 enum mlx4_protocol prot) 889 { 890 if (prot == MLX4_PROT_ETH && 891 !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) 892 return 0; 893 894 if (prot == MLX4_PROT_ETH) 895 gid[7] |= (MLX4_MC_STEER << 1); 896 897 if (mlx4_is_mfunc(dev)) 898 return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot); 899 900 return mlx4_qp_detach_common(dev, qp, gid, prot, MLX4_MC_STEER); 901 } 902 EXPORT_SYMBOL_GPL(mlx4_multicast_detach); 903 904 int mlx4_unicast_attach(struct mlx4_dev *dev, 905 struct mlx4_qp *qp, u8 gid[16], 906 int block_mcast_loopback, enum mlx4_protocol prot) 907 { 908 if (prot == MLX4_PROT_ETH && 909 !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) 910 return 0; 911 912 if (prot == MLX4_PROT_ETH) 913 gid[7] |= (MLX4_UC_STEER << 1); 914 915 if (mlx4_is_mfunc(dev)) 916 return mlx4_QP_ATTACH(dev, qp, gid, 1, 917 block_mcast_loopback, prot); 918 919 return mlx4_qp_attach_common(dev, qp, gid, block_mcast_loopback, 920 prot, MLX4_UC_STEER); 921 } 922 EXPORT_SYMBOL_GPL(mlx4_unicast_attach); 923 924 int mlx4_unicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, 925 u8 gid[16], enum mlx4_protocol prot) 926 { 927 if (prot == MLX4_PROT_ETH && 928 !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) 929 return 0; 930 931 if (prot == MLX4_PROT_ETH) 932 gid[7] |= (MLX4_UC_STEER << 1); 933 934 if (mlx4_is_mfunc(dev)) 935 return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot); 936 937 return mlx4_qp_detach_common(dev, qp, gid, prot, MLX4_UC_STEER); 938 } 939 EXPORT_SYMBOL_GPL(mlx4_unicast_detach); 940 941 int mlx4_PROMISC_wrapper(struct mlx4_dev *dev, int slave, 942 struct mlx4_vhcr *vhcr, 943 struct mlx4_cmd_mailbox *inbox, 944 struct mlx4_cmd_mailbox *outbox, 945 struct mlx4_cmd_info *cmd) 946 { 947 u32 qpn = (u32) vhcr->in_param & 0xffffffff; 948 u8 port = vhcr->in_param >> 62; 949 enum mlx4_steer_type steer = vhcr->in_modifier; 950 951 /* Promiscuous unicast is not allowed in mfunc */ 952 if (mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER) 953 return 0; 954 955 if (vhcr->op_modifier) 956 return add_promisc_qp(dev, port, steer, qpn); 957 else 958 return remove_promisc_qp(dev, port, steer, qpn); 959 } 960 961 static int mlx4_PROMISC(struct mlx4_dev *dev, u32 qpn, 962 enum mlx4_steer_type steer, u8 add, u8 port) 963 { 964 return mlx4_cmd(dev, (u64) qpn | (u64) port << 62, (u32) steer, add, 965 MLX4_CMD_PROMISC, MLX4_CMD_TIME_CLASS_A, 966 MLX4_CMD_WRAPPED); 967 } 968 969 int mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) 970 { 971 if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) 972 return 0; 973 974 if (mlx4_is_mfunc(dev)) 975 return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 1, port); 976 977 return add_promisc_qp(dev, port, MLX4_MC_STEER, qpn); 978 } 979 EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_add); 980 981 int mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) 982 { 983 if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) 984 return 0; 985 986 if (mlx4_is_mfunc(dev)) 987 return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 0, port); 988 989 return remove_promisc_qp(dev, port, MLX4_MC_STEER, qpn); 990 } 991 EXPORT_SYMBOL_GPL(mlx4_multicast_promisc_remove); 992 993 int mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) 994 { 995 if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) 996 return 0; 997 998 if (mlx4_is_mfunc(dev)) 999 return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 1, port); 1000 1001 return add_promisc_qp(dev, port, MLX4_UC_STEER, qpn); 1002 } 1003 EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_add); 1004 1005 int mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) 1006 { 1007 if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) 1008 return 0; 1009 1010 if (mlx4_is_mfunc(dev)) 1011 return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 0, port); 1012 1013 return remove_promisc_qp(dev, port, MLX4_UC_STEER, qpn); 1014 } 1015 EXPORT_SYMBOL_GPL(mlx4_unicast_promisc_remove); 1016 1017 int mlx4_init_mcg_table(struct mlx4_dev *dev) 1018 { 1019 struct mlx4_priv *priv = mlx4_priv(dev); 1020 int err; 1021 1022 err = mlx4_bitmap_init(&priv->mcg_table.bitmap, dev->caps.num_amgms, 1023 dev->caps.num_amgms - 1, 0, 0); 1024 if (err) 1025 return err; 1026 1027 mutex_init(&priv->mcg_table.mutex); 1028 1029 return 0; 1030 } 1031 1032 void mlx4_cleanup_mcg_table(struct mlx4_dev *dev) 1033 { 1034 mlx4_bitmap_cleanup(&mlx4_priv(dev)->mcg_table.bitmap); 1035 } 1036