1225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier/* 2225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. 351a379d0c8f7a6db7c9e3c9c770d90a6d2d1ef9bJack Morgenstein * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. 4225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * 5225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * This software is available to you under a choice of one of two 6225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * licenses. You may choose to be licensed under the terms of the GNU 7225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * General Public License (GPL) Version 2, available from the file 8225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * COPYING in the main directory of this source tree, or the 9225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * OpenIB.org BSD license below: 10225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * 11225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * Redistribution and use in source and binary forms, with or 12225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * without modification, are permitted provided that the following 13225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * conditions are met: 14225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * 15225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * - Redistributions of source code must retain the above 16225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * copyright notice, this list of conditions and the following 17225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * disclaimer. 18225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * 19225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * - Redistributions in binary form must reproduce the above 20225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * copyright notice, this list of conditions and the following 21225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * disclaimer in the documentation and/or other materials 22225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * provided with the distribution. 23225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * 24225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * SOFTWARE. 32225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier */ 33225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 34225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier#include <linux/string.h> 350345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin#include <linux/etherdevice.h> 36225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 37225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier#include <linux/mlx4/cmd.h> 38ee40fa0656a730491765545ff7550f3c1ceb0fbcPaul Gortmaker#include <linux/export.h> 39225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 40225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier#include "mlx4.h" 41225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 42521e575b9a7324a0bca762622139f69582a042bfRon Livne#define MGM_QPN_MASK 0x00FFFFFF 43521e575b9a7324a0bca762622139f69582a042bfRon Livne#define MGM_BLCK_LB_BIT 30 44521e575b9a7324a0bca762622139f69582a042bfRon Livne 45225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreierstatic const u8 zero_gid[16]; /* automatically initialized to 0 */ 46225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 470ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayevstruct mlx4_mgm { 480ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev __be32 next_gid_index; 490ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev __be32 members_count; 500ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev u32 reserved[2]; 510ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev u8 gid[16]; 520ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev __be32 qp[MLX4_MAX_QP_PER_MGM]; 530ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev}; 540ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 550ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayevint mlx4_get_mgm_entry_size(struct mlx4_dev *dev) 560ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev{ 570ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return min((1 << mlx4_log_num_mgm_entry_size), MLX4_MAX_MGM_ENTRY_SIZE); 580ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev} 590ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 600ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayevint mlx4_get_qp_per_mgm(struct mlx4_dev *dev) 610ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev{ 620ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return 4 * (mlx4_get_mgm_entry_size(dev) / 16 - 2); 630ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev} 640ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 650345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilinstatic int mlx4_READ_ENTRY(struct mlx4_dev *dev, int index, 660345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin struct mlx4_cmd_mailbox *mailbox) 67225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{ 68225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier return mlx4_cmd_box(dev, 0, mailbox->dma, index, 0, MLX4_CMD_READ_MCG, 69f9baff509f8a05a79626defdbdf4f4aa4efd373bJack Morgenstein MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 70225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier} 71225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 720345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilinstatic int mlx4_WRITE_ENTRY(struct mlx4_dev *dev, int index, 730345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin struct mlx4_cmd_mailbox *mailbox) 74225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{ 75225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier return mlx4_cmd(dev, mailbox->dma, index, 0, MLX4_CMD_WRITE_MCG, 76f9baff509f8a05a79626defdbdf4f4aa4efd373bJack Morgenstein MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 77225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier} 78225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 790ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayevstatic int mlx4_WRITE_PROMISC(struct mlx4_dev *dev, u8 port, u8 steer, 80b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_cmd_mailbox *mailbox) 81b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin{ 82b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin u32 in_mod; 83b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 840ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev in_mod = (u32) port << 16 | steer << 1; 85b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return mlx4_cmd(dev, mailbox->dma, in_mod, 0x1, 86f9baff509f8a05a79626defdbdf4f4aa4efd373bJack Morgenstein MLX4_CMD_WRITE_MCG, MLX4_CMD_TIME_CLASS_A, 87f9baff509f8a05a79626defdbdf4f4aa4efd373bJack Morgenstein MLX4_CMD_NATIVE); 88b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin} 89b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 900345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilinstatic int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, 910345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin u16 *hash, u8 op_mod) 92225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{ 93225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier u64 imm; 94225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier int err; 95225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 960345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin err = mlx4_cmd_imm(dev, mailbox->dma, &imm, 0, op_mod, 97f9baff509f8a05a79626defdbdf4f4aa4efd373bJack Morgenstein MLX4_CMD_MGID_HASH, MLX4_CMD_TIME_CLASS_A, 98f9baff509f8a05a79626defdbdf4f4aa4efd373bJack Morgenstein MLX4_CMD_NATIVE); 99225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 100225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (!err) 101225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *hash = imm; 102225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 103225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier return err; 104225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier} 105225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 106b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilinstatic struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 pf_num, 107b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin enum mlx4_steer_type steer, 108b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin u32 qpn) 109b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin{ 110b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[pf_num]; 111b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_promisc_qp *pqp; 112b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 113b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { 114b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (pqp->qpn == qpn) 115b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return pqp; 116b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 117b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* not found */ 118b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return NULL; 119b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin} 120b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 121b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin/* 122b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin * Add new entry to steering data structure. 123b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin * All promisc QPs should be added as well 124b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin */ 1250ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayevstatic int new_steering_entry(struct mlx4_dev *dev, u8 port, 126b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin enum mlx4_steer_type steer, 127b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin unsigned int index, u32 qpn) 128b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin{ 129b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_steer *s_steer; 130b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_cmd_mailbox *mailbox; 131b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_mgm *mgm; 132b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin u32 members_count; 133b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_steer_index *new_entry; 134b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_promisc_qp *pqp; 135a14b289d4614bb3b25d0455d68f72f3c7b4cc8e8Mariusz Kozlowski struct mlx4_promisc_qp *dqp = NULL; 136b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin u32 prot; 137b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin int err; 138b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 1394c41b3673759d096106e68bce586f103c51d4119Eugenia Emantayev s_steer = &mlx4_priv(dev)->steer[port - 1]; 140b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin new_entry = kzalloc(sizeof *new_entry, GFP_KERNEL); 141b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (!new_entry) 142b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return -ENOMEM; 143b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 144b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin INIT_LIST_HEAD(&new_entry->duplicates); 145b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin new_entry->index = index; 146b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_add_tail(&new_entry->list, &s_steer->steer_entries[steer]); 147b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 148b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* If the given qpn is also a promisc qp, 149b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin * it should be inserted to duplicates list 150b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin */ 1510ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev pqp = get_promisc_qp(dev, 0, steer, qpn); 152b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (pqp) { 153b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin dqp = kmalloc(sizeof *dqp, GFP_KERNEL); 154b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (!dqp) { 155b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin err = -ENOMEM; 156b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_alloc; 157b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 158b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin dqp->qpn = qpn; 159b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_add_tail(&dqp->list, &new_entry->duplicates); 160b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 161b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 162b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* if no promisc qps for this vep, we are done */ 163b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (list_empty(&s_steer->promisc_qps[steer])) 164b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return 0; 165b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 166b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* now need to add all the promisc qps to the new 167b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin * steering entry, as they should also receive the packets 168b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin * destined to this address */ 169b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mailbox = mlx4_alloc_cmd_mailbox(dev); 170b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (IS_ERR(mailbox)) { 171b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin err = -ENOMEM; 172b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_alloc; 173b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 174b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm = mailbox->buf; 175b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 176b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin err = mlx4_READ_ENTRY(dev, index, mailbox); 177b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (err) 178b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_mailbox; 179b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 180b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 181b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin prot = be32_to_cpu(mgm->members_count) >> 30; 182b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { 183b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* don't add already existing qpn */ 184b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (pqp->qpn == qpn) 185b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin continue; 1860ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (members_count == dev->caps.num_qp_per_mgm) { 187b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* out of space */ 188b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin err = -ENOMEM; 189b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_mailbox; 190b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 191b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 192b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* add the qpn */ 193b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm->qp[members_count++] = cpu_to_be32(pqp->qpn & MGM_QPN_MASK); 194b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 195b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* update the qps count and update the entry with all the promisc qps*/ 196b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm->members_count = cpu_to_be32(members_count | (prot << 30)); 197b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin err = mlx4_WRITE_ENTRY(dev, index, mailbox); 198b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 199b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilinout_mailbox: 200b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mlx4_free_cmd_mailbox(dev, mailbox); 201b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (!err) 202b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return 0; 203b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilinout_alloc: 204b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (dqp) { 205b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_del(&dqp->list); 206a14b289d4614bb3b25d0455d68f72f3c7b4cc8e8Mariusz Kozlowski kfree(dqp); 207b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 208b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_del(&new_entry->list); 209b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin kfree(new_entry); 210b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return err; 211b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin} 212b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 213b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin/* update the data structures with existing steering entry */ 2140ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayevstatic int existing_steering_entry(struct mlx4_dev *dev, u8 port, 215b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin enum mlx4_steer_type steer, 216b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin unsigned int index, u32 qpn) 217b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin{ 218b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_steer *s_steer; 219b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_steer_index *tmp_entry, *entry = NULL; 220b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_promisc_qp *pqp; 221b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_promisc_qp *dqp; 222b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 2234c41b3673759d096106e68bce586f103c51d4119Eugenia Emantayev s_steer = &mlx4_priv(dev)->steer[port - 1]; 224b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 2250ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev pqp = get_promisc_qp(dev, 0, steer, qpn); 226b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (!pqp) 227b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return 0; /* nothing to do */ 228b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 229b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_for_each_entry(tmp_entry, &s_steer->steer_entries[steer], list) { 230b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (tmp_entry->index == index) { 231b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin entry = tmp_entry; 232b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin break; 233b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 234b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 235b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (unlikely(!entry)) { 236b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mlx4_warn(dev, "Steering entry at index %x is not registered\n", index); 237b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return -EINVAL; 238b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 239b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 240b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* the given qpn is listed as a promisc qpn 241b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin * we need to add it as a duplicate to this entry 24225985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * for future references */ 243b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_for_each_entry(dqp, &entry->duplicates, list) { 2440ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (qpn == pqp->qpn) 245b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return 0; /* qp is already duplicated */ 246b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 247b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 248b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* add the qp as a duplicate on this index */ 249b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin dqp = kmalloc(sizeof *dqp, GFP_KERNEL); 250b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (!dqp) 251b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return -ENOMEM; 252b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin dqp->qpn = qpn; 253b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_add_tail(&dqp->list, &entry->duplicates); 254b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 255b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return 0; 256b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin} 257b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 258b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin/* Check whether a qpn is a duplicate on steering entry 259b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin * If so, it should not be removed from mgm */ 2600ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayevstatic bool check_duplicate_entry(struct mlx4_dev *dev, u8 port, 261b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin enum mlx4_steer_type steer, 262b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin unsigned int index, u32 qpn) 263b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin{ 264b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_steer *s_steer; 265b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_steer_index *tmp_entry, *entry = NULL; 266b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_promisc_qp *dqp, *tmp_dqp; 267b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 2684c41b3673759d096106e68bce586f103c51d4119Eugenia Emantayev s_steer = &mlx4_priv(dev)->steer[port - 1]; 269b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 270b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* if qp is not promisc, it cannot be duplicated */ 2710ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (!get_promisc_qp(dev, 0, steer, qpn)) 272b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return false; 273b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 274b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* The qp is promisc qp so it is a duplicate on this index 275b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin * Find the index entry, and remove the duplicate */ 276b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_for_each_entry(tmp_entry, &s_steer->steer_entries[steer], list) { 277b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (tmp_entry->index == index) { 278b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin entry = tmp_entry; 279b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin break; 280b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 281b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 282b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (unlikely(!entry)) { 283b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mlx4_warn(dev, "Steering entry for index %x is not registered\n", index); 284b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return false; 285b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 286b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_for_each_entry_safe(dqp, tmp_dqp, &entry->duplicates, list) { 287b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (dqp->qpn == qpn) { 288b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_del(&dqp->list); 289b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin kfree(dqp); 290b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 291b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 292b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return true; 293b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin} 294b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 295b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin/* I a steering entry contains only promisc QPs, it can be removed. */ 2960ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayevstatic bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port, 297b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin enum mlx4_steer_type steer, 298b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin unsigned int index, u32 tqpn) 299b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin{ 300b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_steer *s_steer; 301b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_cmd_mailbox *mailbox; 302b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_mgm *mgm; 303b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_steer_index *entry = NULL, *tmp_entry; 304b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin u32 qpn; 305b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin u32 members_count; 306b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin bool ret = false; 307b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin int i; 308b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 3094c41b3673759d096106e68bce586f103c51d4119Eugenia Emantayev s_steer = &mlx4_priv(dev)->steer[port - 1]; 310b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 311b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mailbox = mlx4_alloc_cmd_mailbox(dev); 312b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (IS_ERR(mailbox)) 313b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return false; 314b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm = mailbox->buf; 315b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 316b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (mlx4_READ_ENTRY(dev, index, mailbox)) 317b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out; 318b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 319b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin for (i = 0; i < members_count; i++) { 320b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK; 3210ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (!get_promisc_qp(dev, 0, steer, qpn) && qpn != tqpn) { 322b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* the qp is not promisc, the entry can't be removed */ 323b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out; 324b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 325b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 326b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* All the qps currently registered for this entry are promiscuous, 327b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin * Checking for duplicates */ 328b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin ret = true; 329b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_for_each_entry_safe(entry, tmp_entry, &s_steer->steer_entries[steer], list) { 330b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (entry->index == index) { 331b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (list_empty(&entry->duplicates)) { 332b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_del(&entry->list); 333b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin kfree(entry); 334b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } else { 335b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* This entry contains duplicates so it shouldn't be removed */ 336b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin ret = false; 337b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out; 338b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 339b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 340b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 341b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 342b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilinout: 343b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mlx4_free_cmd_mailbox(dev, mailbox); 344b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return ret; 345b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin} 346b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 3470ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayevstatic int add_promisc_qp(struct mlx4_dev *dev, u8 port, 348b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin enum mlx4_steer_type steer, u32 qpn) 349b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin{ 350b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_steer *s_steer; 351b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_cmd_mailbox *mailbox; 352b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_mgm *mgm; 353b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_steer_index *entry; 354b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_promisc_qp *pqp; 355b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_promisc_qp *dqp; 356b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin u32 members_count; 357b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin u32 prot; 358b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin int i; 359b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin bool found; 360b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin int last_index; 361b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin int err; 362b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_priv *priv = mlx4_priv(dev); 3630ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 3644c41b3673759d096106e68bce586f103c51d4119Eugenia Emantayev s_steer = &mlx4_priv(dev)->steer[port - 1]; 365b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 366b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mutex_lock(&priv->mcg_table.mutex); 367b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 3680ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (get_promisc_qp(dev, 0, steer, qpn)) { 369b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin err = 0; /* Noting to do, already exists */ 370b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_mutex; 371b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 372b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 373b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin pqp = kmalloc(sizeof *pqp, GFP_KERNEL); 374b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (!pqp) { 375b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin err = -ENOMEM; 376b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_mutex; 377b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 378b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin pqp->qpn = qpn; 379b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 380b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mailbox = mlx4_alloc_cmd_mailbox(dev); 381b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (IS_ERR(mailbox)) { 382b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin err = -ENOMEM; 383b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_alloc; 384b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 385b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm = mailbox->buf; 386b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 387b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* the promisc qp needs to be added for each one of the steering 388b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin * entries, if it already exists, needs to be added as a duplicate 389b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin * for this entry */ 390b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_for_each_entry(entry, &s_steer->steer_entries[steer], list) { 391b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin err = mlx4_READ_ENTRY(dev, entry->index, mailbox); 392b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (err) 393b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_mailbox; 394b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 395b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 396b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin prot = be32_to_cpu(mgm->members_count) >> 30; 397b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin found = false; 398b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin for (i = 0; i < members_count; i++) { 399b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) { 400b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* Entry already exists, add to duplicates */ 401b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin dqp = kmalloc(sizeof *dqp, GFP_KERNEL); 402b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (!dqp) 403b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_mailbox; 404b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin dqp->qpn = qpn; 405b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_add_tail(&dqp->list, &entry->duplicates); 406b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin found = true; 407b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 408b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 409b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (!found) { 410b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* Need to add the qpn to mgm */ 4110ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (members_count == dev->caps.num_qp_per_mgm) { 412b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* entry is full */ 413b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin err = -ENOMEM; 414b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_mailbox; 415b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 416b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm->qp[members_count++] = cpu_to_be32(qpn & MGM_QPN_MASK); 417b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm->members_count = cpu_to_be32(members_count | (prot << 30)); 418b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox); 419b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (err) 420b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_mailbox; 421b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 422b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin last_index = entry->index; 423b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 424b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 425b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* add the new qpn to list of promisc qps */ 426b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]); 427b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* now need to add all the promisc qps to default entry */ 428b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin memset(mgm, 0, sizeof *mgm); 429b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin members_count = 0; 430b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list) 431b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK); 432b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30); 433b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 4340ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox); 435b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (err) 436b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_list; 437b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 438b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mlx4_free_cmd_mailbox(dev, mailbox); 439b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mutex_unlock(&priv->mcg_table.mutex); 440b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return 0; 441b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 442b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilinout_list: 443b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_del(&pqp->list); 444b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilinout_mailbox: 445b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mlx4_free_cmd_mailbox(dev, mailbox); 446b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilinout_alloc: 447b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin kfree(pqp); 448b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilinout_mutex: 449b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mutex_unlock(&priv->mcg_table.mutex); 450b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return err; 451b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin} 452b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 4530ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayevstatic int remove_promisc_qp(struct mlx4_dev *dev, u8 port, 454b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin enum mlx4_steer_type steer, u32 qpn) 455b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin{ 456b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_priv *priv = mlx4_priv(dev); 457b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_steer *s_steer; 458b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_cmd_mailbox *mailbox; 459b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_mgm *mgm; 460b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_steer_index *entry; 461b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_promisc_qp *pqp; 462b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin struct mlx4_promisc_qp *dqp; 463b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin u32 members_count; 464b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin bool found; 465b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin bool back_to_list = false; 466b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin int loc, i; 467b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin int err; 468b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 4694c41b3673759d096106e68bce586f103c51d4119Eugenia Emantayev s_steer = &mlx4_priv(dev)->steer[port - 1]; 470b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mutex_lock(&priv->mcg_table.mutex); 471b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 4720ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev pqp = get_promisc_qp(dev, 0, steer, qpn); 473b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (unlikely(!pqp)) { 474b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn); 475b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* nothing to do */ 476b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin err = 0; 477b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_mutex; 478b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 479b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 480b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /*remove from list of promisc qps */ 481b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_del(&pqp->list); 482b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 483b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* set the default entry not to include the removed one */ 484b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mailbox = mlx4_alloc_cmd_mailbox(dev); 485b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (IS_ERR(mailbox)) { 486b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin err = -ENOMEM; 487b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin back_to_list = true; 488b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_list; 489b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 490b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm = mailbox->buf; 4910ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev memset(mgm, 0, sizeof *mgm); 492b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin members_count = 0; 493b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_for_each_entry(dqp, &s_steer->promisc_qps[steer], list) 494b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm->qp[members_count++] = cpu_to_be32(dqp->qpn & MGM_QPN_MASK); 495b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm->members_count = cpu_to_be32(members_count | MLX4_PROT_ETH << 30); 496b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 4970ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev err = mlx4_WRITE_PROMISC(dev, port, steer, mailbox); 498b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (err) 499b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_mailbox; 500b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 501b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* remove the qp from all the steering entries*/ 502b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_for_each_entry(entry, &s_steer->steer_entries[steer], list) { 503b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin found = false; 504b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_for_each_entry(dqp, &entry->duplicates, list) { 505b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (dqp->qpn == qpn) { 506b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin found = true; 507b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin break; 508b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 509b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 510b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (found) { 511b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* a duplicate, no need to change the mgm, 512b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin * only update the duplicates list */ 513b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_del(&dqp->list); 514b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin kfree(dqp); 515b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } else { 516b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin err = mlx4_READ_ENTRY(dev, entry->index, mailbox); 517b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (err) 518b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_mailbox; 519b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 520b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin for (loc = -1, i = 0; i < members_count; ++i) 521b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) 522b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin loc = i; 523b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 524b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm->members_count = cpu_to_be32(--members_count | 525b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin (MLX4_PROT_ETH << 30)); 526b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm->qp[loc] = mgm->qp[i - 1]; 527b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm->qp[i - 1] = 0; 528b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 529b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox); 530b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (err) 531b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out_mailbox; 532b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 533b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 534b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 535b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 536b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilinout_mailbox: 537b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mlx4_free_cmd_mailbox(dev, mailbox); 538b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilinout_list: 539b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (back_to_list) 540b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]); 54153020092bd89b0d4ccc5368a3956f43cb43e5665Yevgeny Petrilin else 54253020092bd89b0d4ccc5368a3956f43cb43e5665Yevgeny Petrilin kfree(pqp); 543b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilinout_mutex: 544b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mutex_unlock(&priv->mcg_table.mutex); 545b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return err; 546b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin} 547b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 548225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier/* 549225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * Caller must hold MCG table semaphore. gid and mgm parameters must 550225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * be properly aligned for command interface. 551225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * 552225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * Returns 0 unless a firmware command error occurs. 553225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * 554225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * If GID is found in MGM or MGM is empty, *index = *hash, *prev = -1 555225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * and *mgm holds MGM entry. 556225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * 557225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * if GID is found in AMGM, *index = index in AMGM, *prev = index of 558225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * previous entry in hash chain and *mgm holds AMGM entry. 559225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * 560225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * If no AMGM exists for given gid, *index = -1, *prev = index of last 561225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * entry in hash chain and *mgm holds end of hash chain. 562225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier */ 5630345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilinstatic int find_entry(struct mlx4_dev *dev, u8 port, 5640345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin u8 *gid, enum mlx4_protocol prot, 5650345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin struct mlx4_cmd_mailbox *mgm_mailbox, 566deb8b3e8494f63b05ce144a52e8c0b3f80789fedEugenia Emantayev int *prev, int *index) 567225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{ 568225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier struct mlx4_cmd_mailbox *mailbox; 569225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier struct mlx4_mgm *mgm = mgm_mailbox->buf; 570225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier u8 *mgid; 571225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier int err; 572deb8b3e8494f63b05ce144a52e8c0b3f80789fedEugenia Emantayev u16 hash; 573ccf863219675aa86bebdd6a2806acb8176478e37Or Gerlitz u8 op_mod = (prot == MLX4_PROT_ETH) ? 574ccf863219675aa86bebdd6a2806acb8176478e37Or Gerlitz !!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) : 0; 575225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 576225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mailbox = mlx4_alloc_cmd_mailbox(dev); 577225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (IS_ERR(mailbox)) 578225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier return -ENOMEM; 579225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mgid = mailbox->buf; 580225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 581225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier memcpy(mgid, gid, 16); 582225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 583deb8b3e8494f63b05ce144a52e8c0b3f80789fedEugenia Emantayev err = mlx4_GID_HASH(dev, mailbox, &hash, op_mod); 584225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mlx4_free_cmd_mailbox(dev, mailbox); 585225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (err) 586225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier return err; 587225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 588225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (0) 589deb8b3e8494f63b05ce144a52e8c0b3f80789fedEugenia Emantayev mlx4_dbg(dev, "Hash for %pI6 is %04x\n", gid, hash); 590225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 591deb8b3e8494f63b05ce144a52e8c0b3f80789fedEugenia Emantayev *index = hash; 592225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *prev = -1; 593225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 594225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier do { 5950345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin err = mlx4_READ_ENTRY(dev, *index, mgm_mailbox); 596225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (err) 597225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier return err; 598225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 5990345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) { 600deb8b3e8494f63b05ce144a52e8c0b3f80789fedEugenia Emantayev if (*index != hash) { 601225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mlx4_err(dev, "Found zero MGID in AMGM.\n"); 602225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier err = -EINVAL; 603225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier } 604225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier return err; 605225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier } 606225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 607da995a8aee044bc5d0847e19e351cd48a2cb8bccAleksey Senin if (!memcmp(mgm->gid, gid, 16) && 6080345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin be32_to_cpu(mgm->members_count) >> 30 == prot) 609225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier return err; 610225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 611225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *prev = *index; 612225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *index = be32_to_cpu(mgm->next_gid_index) >> 6; 613225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier } while (*index); 614225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 615225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *index = -1; 616225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier return err; 617225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier} 618225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 6190345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilinint mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 6200345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin int block_mcast_loopback, enum mlx4_protocol prot, 6210345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin enum mlx4_steer_type steer) 622225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{ 623225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier struct mlx4_priv *priv = mlx4_priv(dev); 624225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier struct mlx4_cmd_mailbox *mailbox; 625225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier struct mlx4_mgm *mgm; 626225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier u32 members_count; 627225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier int index, prev; 628225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier int link = 0; 629225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier int i; 630225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier int err; 6310345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin u8 port = gid[5]; 632b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin u8 new_entry = 0; 633225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 634225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mailbox = mlx4_alloc_cmd_mailbox(dev); 635225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (IS_ERR(mailbox)) 636225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier return PTR_ERR(mailbox); 637225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mgm = mailbox->buf; 638225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 639225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mutex_lock(&priv->mcg_table.mutex); 640deb8b3e8494f63b05ce144a52e8c0b3f80789fedEugenia Emantayev err = find_entry(dev, port, gid, prot, 641deb8b3e8494f63b05ce144a52e8c0b3f80789fedEugenia Emantayev mailbox, &prev, &index); 642225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (err) 643225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 644225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 645225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (index != -1) { 646b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) { 647b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin new_entry = 1; 648225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier memcpy(mgm->gid, gid, 16); 649b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 650225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier } else { 651225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier link = 1; 652225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 653225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier index = mlx4_bitmap_alloc(&priv->mcg_table.bitmap); 654225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (index == -1) { 655225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mlx4_err(dev, "No AMGM entries left\n"); 656225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier err = -ENOMEM; 657225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 658225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier } 659225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier index += dev->caps.num_mgms; 660225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 6610ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev new_entry = 1; 662225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier memset(mgm, 0, sizeof *mgm); 663225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier memcpy(mgm->gid, gid, 16); 664225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier } 665225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 666da995a8aee044bc5d0847e19e351cd48a2cb8bccAleksey Senin members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 6670ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (members_count == dev->caps.num_qp_per_mgm) { 668225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mlx4_err(dev, "MGM at index %x is full.\n", index); 669225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier err = -ENOMEM; 670225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 671225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier } 672225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 673225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier for (i = 0; i < members_count; ++i) 674521e575b9a7324a0bca762622139f69582a042bfRon Livne if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) { 675225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mlx4_dbg(dev, "QP %06x already a member of MGM\n", qp->qpn); 676225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier err = 0; 677225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 678225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier } 679225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 680521e575b9a7324a0bca762622139f69582a042bfRon Livne if (block_mcast_loopback) 681521e575b9a7324a0bca762622139f69582a042bfRon Livne mgm->qp[members_count++] = cpu_to_be32((qp->qpn & MGM_QPN_MASK) | 682e6a176228a38d74c0360ca586146bd45a2ac2d60Ingo Molnar (1U << MGM_BLCK_LB_BIT)); 683521e575b9a7324a0bca762622139f69582a042bfRon Livne else 684521e575b9a7324a0bca762622139f69582a042bfRon Livne mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK); 685521e575b9a7324a0bca762622139f69582a042bfRon Livne 6860345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin mgm->members_count = cpu_to_be32(members_count | (u32) prot << 30); 687225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 6880345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin err = mlx4_WRITE_ENTRY(dev, index, mailbox); 689225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (err) 690225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 691225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 692225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (!link) 693225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 694225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 6950345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin err = mlx4_READ_ENTRY(dev, prev, mailbox); 696225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (err) 697225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 698225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 699225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mgm->next_gid_index = cpu_to_be32(index << 6); 700225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 7010345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin err = mlx4_WRITE_ENTRY(dev, prev, mailbox); 702225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (err) 703225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 704225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 705225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreierout: 706b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (prot == MLX4_PROT_ETH) { 707b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* manage the steering entry for promisc mode */ 708b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (new_entry) 7090ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev new_steering_entry(dev, port, steer, index, qp->qpn); 710b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin else 7110ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev existing_steering_entry(dev, port, steer, 712b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin index, qp->qpn); 713b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin } 714225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (err && link && index != -1) { 715225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (index < dev->caps.num_mgms) 716225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mlx4_warn(dev, "Got AMGM index %d < %d", 717225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier index, dev->caps.num_mgms); 718225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier else 719225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mlx4_bitmap_free(&priv->mcg_table.bitmap, 720225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier index - dev->caps.num_mgms); 721225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier } 722225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mutex_unlock(&priv->mcg_table.mutex); 723225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 724225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mlx4_free_cmd_mailbox(dev, mailbox); 725225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier return err; 726225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier} 727225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 7280345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilinint mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 7290345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin enum mlx4_protocol prot, enum mlx4_steer_type steer) 730225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{ 731225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier struct mlx4_priv *priv = mlx4_priv(dev); 732225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier struct mlx4_cmd_mailbox *mailbox; 733225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier struct mlx4_mgm *mgm; 734225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier u32 members_count; 735225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier int prev, index; 736225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier int i, loc; 737225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier int err; 7380345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin u8 port = gid[5]; 739b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin bool removed_entry = false; 740225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 741225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mailbox = mlx4_alloc_cmd_mailbox(dev); 742225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (IS_ERR(mailbox)) 743225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier return PTR_ERR(mailbox); 744225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mgm = mailbox->buf; 745225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 746225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mutex_lock(&priv->mcg_table.mutex); 747225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 748deb8b3e8494f63b05ce144a52e8c0b3f80789fedEugenia Emantayev err = find_entry(dev, port, gid, prot, 749deb8b3e8494f63b05ce144a52e8c0b3f80789fedEugenia Emantayev mailbox, &prev, &index); 750225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (err) 751225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 752225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 753225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (index == -1) { 7545b095d98928fdb9e3b75be20a54b7a6cbf6ca9adHarvey Harrison mlx4_err(dev, "MGID %pI6 not found\n", gid); 755225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier err = -EINVAL; 756225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 757225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier } 758225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 759b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* if this pq is also a promisc qp, it shouldn't be removed */ 760b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (prot == MLX4_PROT_ETH && 7610ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev check_duplicate_entry(dev, port, steer, index, qp->qpn)) 762b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin goto out; 763b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 764da995a8aee044bc5d0847e19e351cd48a2cb8bccAleksey Senin members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 765225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier for (loc = -1, i = 0; i < members_count; ++i) 766521e575b9a7324a0bca762622139f69582a042bfRon Livne if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) 767225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier loc = i; 768225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 769225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (loc == -1) { 770225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mlx4_err(dev, "QP %06x not found in MGM\n", qp->qpn); 771225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier err = -EINVAL; 772225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 773225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier } 774225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 775225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 7760345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin mgm->members_count = cpu_to_be32(--members_count | (u32) prot << 30); 777225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mgm->qp[loc] = mgm->qp[i - 1]; 778225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mgm->qp[i - 1] = 0; 779225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 780b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (prot == MLX4_PROT_ETH) 7810ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev removed_entry = can_remove_steering_entry(dev, port, steer, 7820ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev index, qp->qpn); 783b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin if (i != 1 && (prot != MLX4_PROT_ETH || !removed_entry)) { 7840345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin err = mlx4_WRITE_ENTRY(dev, index, mailbox); 785225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 7864dc51b32582d45cb7e8322d750ffe0e6d82b506dEli Cohen } 787225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 788b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin /* We are going to delete the entry, members count should be 0 */ 789b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin mgm->members_count = cpu_to_be32((u32) prot << 30); 790b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 791225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (prev == -1) { 792225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier /* Remove entry from MGM */ 793225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier int amgm_index = be32_to_cpu(mgm->next_gid_index) >> 6; 794225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (amgm_index) { 7950345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin err = mlx4_READ_ENTRY(dev, amgm_index, mailbox); 796225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (err) 797225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 798225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier } else 799225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier memset(mgm->gid, 0, 16); 800225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 8010345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin err = mlx4_WRITE_ENTRY(dev, index, mailbox); 802225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (err) 803225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 804225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 805225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (amgm_index) { 806225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (amgm_index < dev->caps.num_mgms) 807225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mlx4_warn(dev, "MGM entry %d had AMGM index %d < %d", 808225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier index, amgm_index, dev->caps.num_mgms); 809225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier else 810225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mlx4_bitmap_free(&priv->mcg_table.bitmap, 811225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier amgm_index - dev->caps.num_mgms); 812225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier } 813225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier } else { 814225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier /* Remove entry from AMGM */ 815225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier int cur_next_index = be32_to_cpu(mgm->next_gid_index) >> 6; 8160345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin err = mlx4_READ_ENTRY(dev, prev, mailbox); 817225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (err) 818225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 819225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 820225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mgm->next_gid_index = cpu_to_be32(cur_next_index << 6); 821225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 8220345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin err = mlx4_WRITE_ENTRY(dev, prev, mailbox); 823225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (err) 824225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier goto out; 825225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 826225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (index < dev->caps.num_mgms) 827225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mlx4_warn(dev, "entry %d had next AMGM index %d < %d", 828225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier prev, index, dev->caps.num_mgms); 829225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier else 830225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mlx4_bitmap_free(&priv->mcg_table.bitmap, 831225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier index - dev->caps.num_mgms); 832225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier } 833225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 834225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreierout: 835225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mutex_unlock(&priv->mcg_table.mutex); 836225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 837225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mlx4_free_cmd_mailbox(dev, mailbox); 838225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier return err; 839225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier} 8400345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin 8410ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayevstatic int mlx4_QP_ATTACH(struct mlx4_dev *dev, struct mlx4_qp *qp, 8420ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev u8 gid[16], u8 attach, u8 block_loopback, 8430ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev enum mlx4_protocol prot) 8440ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev{ 8450ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev struct mlx4_cmd_mailbox *mailbox; 8460ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev int err = 0; 8470ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev int qpn; 8480ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 8490ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (!mlx4_is_mfunc(dev)) 8500ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return -EBADF; 8510ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 8520ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev mailbox = mlx4_alloc_cmd_mailbox(dev); 8530ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (IS_ERR(mailbox)) 8540ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return PTR_ERR(mailbox); 8550ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 8560ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev memcpy(mailbox->buf, gid, 16); 8570ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev qpn = qp->qpn; 8580ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev qpn |= (prot << 28); 8590ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (attach && block_loopback) 8600ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev qpn |= (1 << 31); 8610ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 8620ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev err = mlx4_cmd(dev, mailbox->dma, qpn, attach, 8630ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev MLX4_CMD_QP_ATTACH, MLX4_CMD_TIME_CLASS_A, 8640ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev MLX4_CMD_WRAPPED); 8650ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 8660ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev mlx4_free_cmd_mailbox(dev, mailbox); 8670ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return err; 8680ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev} 8690345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin 8700345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilinint mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 8710345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin int block_mcast_loopback, enum mlx4_protocol prot) 8720345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin{ 873ccf863219675aa86bebdd6a2806acb8176478e37Or Gerlitz if (prot == MLX4_PROT_ETH && 874ccf863219675aa86bebdd6a2806acb8176478e37Or Gerlitz !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) 8750345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin return 0; 8760345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin 8770345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin if (prot == MLX4_PROT_ETH) 878f1f75f0e2bb94674da540be9c488fe596dd55881Eugenia Emantayev gid[7] |= (MLX4_MC_STEER << 1); 8790345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin 8800ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (mlx4_is_mfunc(dev)) 8810ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return mlx4_QP_ATTACH(dev, qp, gid, 1, 8820ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev block_mcast_loopback, prot); 8830ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 8840ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return mlx4_qp_attach_common(dev, qp, gid, block_mcast_loopback, 885f1f75f0e2bb94674da540be9c488fe596dd55881Eugenia Emantayev prot, MLX4_MC_STEER); 8860345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin} 8870345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny PetrilinEXPORT_SYMBOL_GPL(mlx4_multicast_attach); 8880345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin 8890345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilinint mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 8900345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin enum mlx4_protocol prot) 8910345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin{ 892ccf863219675aa86bebdd6a2806acb8176478e37Or Gerlitz if (prot == MLX4_PROT_ETH && 893ccf863219675aa86bebdd6a2806acb8176478e37Or Gerlitz !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) 8940345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin return 0; 8950345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin 8960ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (prot == MLX4_PROT_ETH) 897f1f75f0e2bb94674da540be9c488fe596dd55881Eugenia Emantayev gid[7] |= (MLX4_MC_STEER << 1); 8980ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 8990ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (mlx4_is_mfunc(dev)) 9000ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot); 9010345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin 902f1f75f0e2bb94674da540be9c488fe596dd55881Eugenia Emantayev return mlx4_qp_detach_common(dev, qp, gid, prot, MLX4_MC_STEER); 9030345584e0b8be3735a950d17c7e463db20c6ce27Yevgeny Petrilin} 904225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland DreierEXPORT_SYMBOL_GPL(mlx4_multicast_detach); 905225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 906ffe455ad04681f3fc48eef595fe526a795f809a3Eugenia Emantayevint mlx4_unicast_attach(struct mlx4_dev *dev, 9070ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev struct mlx4_qp *qp, u8 gid[16], 9080ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev int block_mcast_loopback, enum mlx4_protocol prot) 9090ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev{ 9100ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (prot == MLX4_PROT_ETH && 9110ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) 9120ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return 0; 9130ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 9140ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (prot == MLX4_PROT_ETH) 9150ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev gid[7] |= (MLX4_UC_STEER << 1); 9160ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 9170ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (mlx4_is_mfunc(dev)) 9180ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return mlx4_QP_ATTACH(dev, qp, gid, 1, 9190ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev block_mcast_loopback, prot); 9200ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 9210ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return mlx4_qp_attach_common(dev, qp, gid, block_mcast_loopback, 9220ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev prot, MLX4_UC_STEER); 9230ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev} 9240ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia EmantayevEXPORT_SYMBOL_GPL(mlx4_unicast_attach); 9250ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 926ffe455ad04681f3fc48eef595fe526a795f809a3Eugenia Emantayevint mlx4_unicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, 9270ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev u8 gid[16], enum mlx4_protocol prot) 9280ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev{ 9290ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (prot == MLX4_PROT_ETH && 9300ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev !(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) 9310ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return 0; 9320ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 9330ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (prot == MLX4_PROT_ETH) 9340ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev gid[7] |= (MLX4_UC_STEER << 1); 9350ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 9360ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (mlx4_is_mfunc(dev)) 9370ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot); 9380ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 9390ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return mlx4_qp_detach_common(dev, qp, gid, prot, MLX4_UC_STEER); 9400ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev} 9410ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia EmantayevEXPORT_SYMBOL_GPL(mlx4_unicast_detach); 9420ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 9430ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayevint mlx4_PROMISC_wrapper(struct mlx4_dev *dev, int slave, 9440ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev struct mlx4_vhcr *vhcr, 9450ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev struct mlx4_cmd_mailbox *inbox, 9460ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev struct mlx4_cmd_mailbox *outbox, 9470ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev struct mlx4_cmd_info *cmd) 9480ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev{ 9490ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev u32 qpn = (u32) vhcr->in_param & 0xffffffff; 9500ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev u8 port = vhcr->in_param >> 62; 9510ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev enum mlx4_steer_type steer = vhcr->in_modifier; 9520ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 9530ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev /* Promiscuous unicast is not allowed in mfunc */ 9540ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (mlx4_is_mfunc(dev) && steer == MLX4_UC_STEER) 9550ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return 0; 9560ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 9570ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (vhcr->op_modifier) 9580ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return add_promisc_qp(dev, port, steer, qpn); 9590ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev else 9600ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return remove_promisc_qp(dev, port, steer, qpn); 9610ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev} 9620ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 9630ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayevstatic int mlx4_PROMISC(struct mlx4_dev *dev, u32 qpn, 9640ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev enum mlx4_steer_type steer, u8 add, u8 port) 9650ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev{ 9660ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return mlx4_cmd(dev, (u64) qpn | (u64) port << 62, (u32) steer, add, 9670ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev MLX4_CMD_PROMISC, MLX4_CMD_TIME_CLASS_A, 9680ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev MLX4_CMD_WRAPPED); 9690ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev} 970b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 971b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilinint mlx4_multicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) 972b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin{ 973ccf863219675aa86bebdd6a2806acb8176478e37Or Gerlitz if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) 974b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return 0; 975b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 9760ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (mlx4_is_mfunc(dev)) 9770ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 1, port); 978b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 9790ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return add_promisc_qp(dev, port, MLX4_MC_STEER, qpn); 980b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin} 981b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny PetrilinEXPORT_SYMBOL_GPL(mlx4_multicast_promisc_add); 982b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 983b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilinint mlx4_multicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) 984b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin{ 985ccf863219675aa86bebdd6a2806acb8176478e37Or Gerlitz if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER)) 986b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return 0; 987b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 9880ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (mlx4_is_mfunc(dev)) 9890ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return mlx4_PROMISC(dev, qpn, MLX4_MC_STEER, 0, port); 990b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 9910ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return remove_promisc_qp(dev, port, MLX4_MC_STEER, qpn); 992b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin} 993b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny PetrilinEXPORT_SYMBOL_GPL(mlx4_multicast_promisc_remove); 994b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 995b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilinint mlx4_unicast_promisc_add(struct mlx4_dev *dev, u32 qpn, u8 port) 996b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin{ 9974df99504065fcc75c70cde0aa4a342fb32c829b8Eugenia Emantayev if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) 998b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return 0; 999b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 10000ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (mlx4_is_mfunc(dev)) 10010ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 1, port); 1002b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 10030ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return add_promisc_qp(dev, port, MLX4_UC_STEER, qpn); 1004b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin} 1005b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny PetrilinEXPORT_SYMBOL_GPL(mlx4_unicast_promisc_add); 1006b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 1007b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilinint mlx4_unicast_promisc_remove(struct mlx4_dev *dev, u32 qpn, u8 port) 1008b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin{ 10094df99504065fcc75c70cde0aa4a342fb32c829b8Eugenia Emantayev if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER)) 1010b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin return 0; 1011b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 10120ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev if (mlx4_is_mfunc(dev)) 10130ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return mlx4_PROMISC(dev, qpn, MLX4_UC_STEER, 0, port); 10140ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev 10150ec2c0f86d31ab36547307f133b0016006bdc6b5Eugenia Emantayev return remove_promisc_qp(dev, port, MLX4_UC_STEER, qpn); 1016b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin} 1017b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny PetrilinEXPORT_SYMBOL_GPL(mlx4_unicast_promisc_remove); 1018b12d93d63c3217f0ec923ff938b12a744e242ffaYevgeny Petrilin 10193d73c2884f45f9a297cbc956cea101405a9703f2Roland Dreierint mlx4_init_mcg_table(struct mlx4_dev *dev) 1020225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{ 1021225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier struct mlx4_priv *priv = mlx4_priv(dev); 1022225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier int err; 1023225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 102493fc9e1bb6507dde945c2eab68c93e1066ac3691Yevgeny Petrilin err = mlx4_bitmap_init(&priv->mcg_table.bitmap, dev->caps.num_amgms, 102593fc9e1bb6507dde945c2eab68c93e1066ac3691Yevgeny Petrilin dev->caps.num_amgms - 1, 0, 0); 1026225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier if (err) 1027225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier return err; 1028225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 1029225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mutex_init(&priv->mcg_table.mutex); 1030225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 1031225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier return 0; 1032225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier} 1033225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier 1034225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiervoid mlx4_cleanup_mcg_table(struct mlx4_dev *dev) 1035225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{ 1036225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier mlx4_bitmap_cleanup(&mlx4_priv(dev)->mcg_table.bitmap); 1037225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier} 1038