linux/drivers/net/ethernet/mellanox/mlx4/qp.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2004 Topspin Communications.  All rights reserved.
   3 * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved.
   4 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved.
   5 * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
   6 *
   7 * This software is available to you under a choice of one of two
   8 * licenses.  You may choose to be licensed under the terms of the GNU
   9 * General Public License (GPL) Version 2, available from the file
  10 * COPYING in the main directory of this source tree, or the
  11 * OpenIB.org BSD license below:
  12 *
  13 *     Redistribution and use in source and binary forms, with or
  14 *     without modification, are permitted provided that the following
  15 *     conditions are met:
  16 *
  17 *      - Redistributions of source code must retain the above
  18 *        copyright notice, this list of conditions and the following
  19 *        disclaimer.
  20 *
  21 *      - Redistributions in binary form must reproduce the above
  22 *        copyright notice, this list of conditions and the following
  23 *        disclaimer in the documentation and/or other materials
  24 *        provided with the distribution.
  25 *
  26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  33 * SOFTWARE.
  34 */
  35
  36#include <linux/gfp.h>
  37#include <linux/export.h>
  38
  39#include <linux/mlx4/cmd.h>
  40#include <linux/mlx4/qp.h>
  41
  42#include "mlx4.h"
  43#include "icm.h"
  44
  45void mlx4_qp_event(struct mlx4_dev *dev, u32 qpn, int event_type)
  46{
  47        struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
  48        struct mlx4_qp *qp;
  49
  50        spin_lock(&qp_table->lock);
  51
  52        qp = __mlx4_qp_lookup(dev, qpn);
  53        if (qp)
  54                atomic_inc(&qp->refcount);
  55
  56        spin_unlock(&qp_table->lock);
  57
  58        if (!qp) {
  59                mlx4_dbg(dev, "Async event for none existent QP %08x\n", qpn);
  60                return;
  61        }
  62
  63        qp->event(qp, event_type);
  64
  65        if (atomic_dec_and_test(&qp->refcount))
  66                complete(&qp->free);
  67}
  68
  69/* used for INIT/CLOSE port logic */
  70static int is_master_qp0(struct mlx4_dev *dev, struct mlx4_qp *qp, int *real_qp0, int *proxy_qp0)
  71{
  72        /* this procedure is called after we already know we are on the master */
  73        /* qp0 is either the proxy qp0, or the real qp0 */
  74        u32 pf_proxy_offset = dev->phys_caps.base_proxy_sqpn + 8 * mlx4_master_func_num(dev);
  75        *proxy_qp0 = qp->qpn >= pf_proxy_offset && qp->qpn <= pf_proxy_offset + 1;
  76
  77        *real_qp0 = qp->qpn >= dev->phys_caps.base_sqpn &&
  78                qp->qpn <= dev->phys_caps.base_sqpn + 1;
  79
  80        return *real_qp0 || *proxy_qp0;
  81}
  82
  83static int __mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
  84                     enum mlx4_qp_state cur_state, enum mlx4_qp_state new_state,
  85                     struct mlx4_qp_context *context,
  86                     enum mlx4_qp_optpar optpar,
  87                     int sqd_event, struct mlx4_qp *qp, int native)
  88{
  89        static const u16 op[MLX4_QP_NUM_STATE][MLX4_QP_NUM_STATE] = {
  90                [MLX4_QP_STATE_RST] = {
  91                        [MLX4_QP_STATE_RST]     = MLX4_CMD_2RST_QP,
  92                        [MLX4_QP_STATE_ERR]     = MLX4_CMD_2ERR_QP,
  93                        [MLX4_QP_STATE_INIT]    = MLX4_CMD_RST2INIT_QP,
  94                },
  95                [MLX4_QP_STATE_INIT]  = {
  96                        [MLX4_QP_STATE_RST]     = MLX4_CMD_2RST_QP,
  97                        [MLX4_QP_STATE_ERR]     = MLX4_CMD_2ERR_QP,
  98                        [MLX4_QP_STATE_INIT]    = MLX4_CMD_INIT2INIT_QP,
  99                        [MLX4_QP_STATE_RTR]     = MLX4_CMD_INIT2RTR_QP,
 100                },
 101                [MLX4_QP_STATE_RTR]   = {
 102                        [MLX4_QP_STATE_RST]     = MLX4_CMD_2RST_QP,
 103                        [MLX4_QP_STATE_ERR]     = MLX4_CMD_2ERR_QP,
 104                        [MLX4_QP_STATE_RTS]     = MLX4_CMD_RTR2RTS_QP,
 105                },
 106                [MLX4_QP_STATE_RTS]   = {
 107                        [MLX4_QP_STATE_RST]     = MLX4_CMD_2RST_QP,
 108                        [MLX4_QP_STATE_ERR]     = MLX4_CMD_2ERR_QP,
 109                        [MLX4_QP_STATE_RTS]     = MLX4_CMD_RTS2RTS_QP,
 110                        [MLX4_QP_STATE_SQD]     = MLX4_CMD_RTS2SQD_QP,
 111                },
 112                [MLX4_QP_STATE_SQD] = {
 113                        [MLX4_QP_STATE_RST]     = MLX4_CMD_2RST_QP,
 114                        [MLX4_QP_STATE_ERR]     = MLX4_CMD_2ERR_QP,
 115                        [MLX4_QP_STATE_RTS]     = MLX4_CMD_SQD2RTS_QP,
 116                        [MLX4_QP_STATE_SQD]     = MLX4_CMD_SQD2SQD_QP,
 117                },
 118                [MLX4_QP_STATE_SQER] = {
 119                        [MLX4_QP_STATE_RST]     = MLX4_CMD_2RST_QP,
 120                        [MLX4_QP_STATE_ERR]     = MLX4_CMD_2ERR_QP,
 121                        [MLX4_QP_STATE_RTS]     = MLX4_CMD_SQERR2RTS_QP,
 122                },
 123                [MLX4_QP_STATE_ERR] = {
 124                        [MLX4_QP_STATE_RST]     = MLX4_CMD_2RST_QP,
 125                        [MLX4_QP_STATE_ERR]     = MLX4_CMD_2ERR_QP,
 126                }
 127        };
 128
 129        struct mlx4_priv *priv = mlx4_priv(dev);
 130        struct mlx4_cmd_mailbox *mailbox;
 131        int ret = 0;
 132        int real_qp0 = 0;
 133        int proxy_qp0 = 0;
 134        u8 port;
 135
 136        if (cur_state >= MLX4_QP_NUM_STATE || new_state >= MLX4_QP_NUM_STATE ||
 137            !op[cur_state][new_state])
 138                return -EINVAL;
 139
 140        if (op[cur_state][new_state] == MLX4_CMD_2RST_QP) {
 141                ret = mlx4_cmd(dev, 0, qp->qpn, 2,
 142                        MLX4_CMD_2RST_QP, MLX4_CMD_TIME_CLASS_A, native);
 143                if (mlx4_is_master(dev) && cur_state != MLX4_QP_STATE_ERR &&
 144                    cur_state != MLX4_QP_STATE_RST &&
 145                    is_master_qp0(dev, qp, &real_qp0, &proxy_qp0)) {
 146                        port = (qp->qpn & 1) + 1;
 147                        if (proxy_qp0)
 148                                priv->mfunc.master.qp0_state[port].proxy_qp0_active = 0;
 149                        else
 150                                priv->mfunc.master.qp0_state[port].qp0_active = 0;
 151                }
 152                return ret;
 153        }
 154
 155        mailbox = mlx4_alloc_cmd_mailbox(dev);
 156        if (IS_ERR(mailbox))
 157                return PTR_ERR(mailbox);
 158
 159        if (cur_state == MLX4_QP_STATE_RST && new_state == MLX4_QP_STATE_INIT) {
 160                u64 mtt_addr = mlx4_mtt_addr(dev, mtt);
 161                context->mtt_base_addr_h = mtt_addr >> 32;
 162                context->mtt_base_addr_l = cpu_to_be32(mtt_addr & 0xffffffff);
 163                context->log_page_size   = mtt->page_shift - MLX4_ICM_PAGE_SHIFT;
 164        }
 165
 166        *(__be32 *) mailbox->buf = cpu_to_be32(optpar);
 167        memcpy(mailbox->buf + 8, context, sizeof *context);
 168
 169        ((struct mlx4_qp_context *) (mailbox->buf + 8))->local_qpn =
 170                cpu_to_be32(qp->qpn);
 171
 172        ret = mlx4_cmd(dev, mailbox->dma,
 173                       qp->qpn | (!!sqd_event << 31),
 174                       new_state == MLX4_QP_STATE_RST ? 2 : 0,
 175                       op[cur_state][new_state], MLX4_CMD_TIME_CLASS_C, native);
 176
 177        if (mlx4_is_master(dev) && is_master_qp0(dev, qp, &real_qp0, &proxy_qp0)) {
 178                port = (qp->qpn & 1) + 1;
 179                if (cur_state != MLX4_QP_STATE_ERR &&
 180                    cur_state != MLX4_QP_STATE_RST &&
 181                    new_state == MLX4_QP_STATE_ERR) {
 182                        if (proxy_qp0)
 183                                priv->mfunc.master.qp0_state[port].proxy_qp0_active = 0;
 184                        else
 185                                priv->mfunc.master.qp0_state[port].qp0_active = 0;
 186                } else if (new_state == MLX4_QP_STATE_RTR) {
 187                        if (proxy_qp0)
 188                                priv->mfunc.master.qp0_state[port].proxy_qp0_active = 1;
 189                        else
 190                                priv->mfunc.master.qp0_state[port].qp0_active = 1;
 191                }
 192        }
 193
 194        mlx4_free_cmd_mailbox(dev, mailbox);
 195        return ret;
 196}
 197
 198int mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
 199                   enum mlx4_qp_state cur_state, enum mlx4_qp_state new_state,
 200                   struct mlx4_qp_context *context,
 201                   enum mlx4_qp_optpar optpar,
 202                   int sqd_event, struct mlx4_qp *qp)
 203{
 204        return __mlx4_qp_modify(dev, mtt, cur_state, new_state, context,
 205                                optpar, sqd_event, qp, 0);
 206}
 207EXPORT_SYMBOL_GPL(mlx4_qp_modify);
 208
 209int __mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align,
 210                                   int *base)
 211{
 212        struct mlx4_priv *priv = mlx4_priv(dev);
 213        struct mlx4_qp_table *qp_table = &priv->qp_table;
 214
 215        *base = mlx4_bitmap_alloc_range(&qp_table->bitmap, cnt, align);
 216        if (*base == -1)
 217                return -ENOMEM;
 218
 219        return 0;
 220}
 221
 222int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int *base)
 223{
 224        u64 in_param = 0;
 225        u64 out_param;
 226        int err;
 227
 228        if (mlx4_is_mfunc(dev)) {
 229                set_param_l(&in_param, cnt);
 230                set_param_h(&in_param, align);
 231                err = mlx4_cmd_imm(dev, in_param, &out_param,
 232                                   RES_QP, RES_OP_RESERVE,
 233                                   MLX4_CMD_ALLOC_RES,
 234                                   MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
 235                if (err)
 236                        return err;
 237
 238                *base = get_param_l(&out_param);
 239                return 0;
 240        }
 241        return __mlx4_qp_reserve_range(dev, cnt, align, base);
 242}
 243EXPORT_SYMBOL_GPL(mlx4_qp_reserve_range);
 244
 245void __mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt)
 246{
 247        struct mlx4_priv *priv = mlx4_priv(dev);
 248        struct mlx4_qp_table *qp_table = &priv->qp_table;
 249
 250        if (mlx4_is_qp_reserved(dev, (u32) base_qpn))
 251                return;
 252        mlx4_bitmap_free_range(&qp_table->bitmap, base_qpn, cnt, MLX4_USE_RR);
 253}
 254
 255void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt)
 256{
 257        u64 in_param = 0;
 258        int err;
 259
 260        if (mlx4_is_mfunc(dev)) {
 261                set_param_l(&in_param, base_qpn);
 262                set_param_h(&in_param, cnt);
 263                err = mlx4_cmd(dev, in_param, RES_QP, RES_OP_RESERVE,
 264                               MLX4_CMD_FREE_RES,
 265                               MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
 266                if (err) {
 267                        mlx4_warn(dev, "Failed to release qp range base:%d cnt:%d\n",
 268                                  base_qpn, cnt);
 269                }
 270        } else
 271                 __mlx4_qp_release_range(dev, base_qpn, cnt);
 272}
 273EXPORT_SYMBOL_GPL(mlx4_qp_release_range);
 274
 275int __mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn, gfp_t gfp)
 276{
 277        struct mlx4_priv *priv = mlx4_priv(dev);
 278        struct mlx4_qp_table *qp_table = &priv->qp_table;
 279        int err;
 280
 281        err = mlx4_table_get(dev, &qp_table->qp_table, qpn, gfp);
 282        if (err)
 283                goto err_out;
 284
 285        err = mlx4_table_get(dev, &qp_table->auxc_table, qpn, gfp);
 286        if (err)
 287                goto err_put_qp;
 288
 289        err = mlx4_table_get(dev, &qp_table->altc_table, qpn, gfp);
 290        if (err)
 291                goto err_put_auxc;
 292
 293        err = mlx4_table_get(dev, &qp_table->rdmarc_table, qpn, gfp);
 294        if (err)
 295                goto err_put_altc;
 296
 297        err = mlx4_table_get(dev, &qp_table->cmpt_table, qpn, gfp);
 298        if (err)
 299                goto err_put_rdmarc;
 300
 301        return 0;
 302
 303err_put_rdmarc:
 304        mlx4_table_put(dev, &qp_table->rdmarc_table, qpn);
 305
 306err_put_altc:
 307        mlx4_table_put(dev, &qp_table->altc_table, qpn);
 308
 309err_put_auxc:
 310        mlx4_table_put(dev, &qp_table->auxc_table, qpn);
 311
 312err_put_qp:
 313        mlx4_table_put(dev, &qp_table->qp_table, qpn);
 314
 315err_out:
 316        return err;
 317}
 318
 319static int mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn, gfp_t gfp)
 320{
 321        u64 param = 0;
 322
 323        if (mlx4_is_mfunc(dev)) {
 324                set_param_l(&param, qpn);
 325                return mlx4_cmd_imm(dev, param, &param, RES_QP, RES_OP_MAP_ICM,
 326                                    MLX4_CMD_ALLOC_RES, MLX4_CMD_TIME_CLASS_A,
 327                                    MLX4_CMD_WRAPPED);
 328        }
 329        return __mlx4_qp_alloc_icm(dev, qpn, gfp);
 330}
 331
 332void __mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn)
 333{
 334        struct mlx4_priv *priv = mlx4_priv(dev);
 335        struct mlx4_qp_table *qp_table = &priv->qp_table;
 336
 337        mlx4_table_put(dev, &qp_table->cmpt_table, qpn);
 338        mlx4_table_put(dev, &qp_table->rdmarc_table, qpn);
 339        mlx4_table_put(dev, &qp_table->altc_table, qpn);
 340        mlx4_table_put(dev, &qp_table->auxc_table, qpn);
 341        mlx4_table_put(dev, &qp_table->qp_table, qpn);
 342}
 343
 344static void mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn)
 345{
 346        u64 in_param = 0;
 347
 348        if (mlx4_is_mfunc(dev)) {
 349                set_param_l(&in_param, qpn);
 350                if (mlx4_cmd(dev, in_param, RES_QP, RES_OP_MAP_ICM,
 351                             MLX4_CMD_FREE_RES, MLX4_CMD_TIME_CLASS_A,
 352                             MLX4_CMD_WRAPPED))
 353                        mlx4_warn(dev, "Failed to free icm of qp:%d\n", qpn);
 354        } else
 355                __mlx4_qp_free_icm(dev, qpn);
 356}
 357
 358int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp, gfp_t gfp)
 359{
 360        struct mlx4_priv *priv = mlx4_priv(dev);
 361        struct mlx4_qp_table *qp_table = &priv->qp_table;
 362        int err;
 363
 364        if (!qpn)
 365                return -EINVAL;
 366
 367        qp->qpn = qpn;
 368
 369        err = mlx4_qp_alloc_icm(dev, qpn, gfp);
 370        if (err)
 371                return err;
 372
 373        spin_lock_irq(&qp_table->lock);
 374        err = radix_tree_insert(&dev->qp_table_tree, qp->qpn &
 375                                (dev->caps.num_qps - 1), qp);
 376        spin_unlock_irq(&qp_table->lock);
 377        if (err)
 378                goto err_icm;
 379
 380        atomic_set(&qp->refcount, 1);
 381        init_completion(&qp->free);
 382
 383        return 0;
 384
 385err_icm:
 386        mlx4_qp_free_icm(dev, qpn);
 387        return err;
 388}
 389
 390EXPORT_SYMBOL_GPL(mlx4_qp_alloc);
 391
 392#define MLX4_UPDATE_QP_SUPPORTED_ATTRS MLX4_UPDATE_QP_SMAC
 393int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn,
 394                   enum mlx4_update_qp_attr attr,
 395                   struct mlx4_update_qp_params *params)
 396{
 397        struct mlx4_cmd_mailbox *mailbox;
 398        struct mlx4_update_qp_context *cmd;
 399        u64 pri_addr_path_mask = 0;
 400        u64 qp_mask = 0;
 401        int err = 0;
 402
 403        mailbox = mlx4_alloc_cmd_mailbox(dev);
 404        if (IS_ERR(mailbox))
 405                return PTR_ERR(mailbox);
 406
 407        cmd = (struct mlx4_update_qp_context *)mailbox->buf;
 408
 409        if (!attr || (attr & ~MLX4_UPDATE_QP_SUPPORTED_ATTRS))
 410                return -EINVAL;
 411
 412        if (attr & MLX4_UPDATE_QP_SMAC) {
 413                pri_addr_path_mask |= 1ULL << MLX4_UPD_QP_PATH_MASK_MAC_INDEX;
 414                cmd->qp_context.pri_path.grh_mylmc = params->smac_index;
 415        }
 416
 417        if (attr & MLX4_UPDATE_QP_VSD) {
 418                qp_mask |= 1ULL << MLX4_UPD_QP_MASK_VSD;
 419                if (params->flags & MLX4_UPDATE_QP_PARAMS_FLAGS_VSD_ENABLE)
 420                        cmd->qp_context.param3 |= cpu_to_be32(MLX4_STRIP_VLAN);
 421        }
 422
 423        cmd->primary_addr_path_mask = cpu_to_be64(pri_addr_path_mask);
 424        cmd->qp_mask = cpu_to_be64(qp_mask);
 425
 426        err = mlx4_cmd(dev, mailbox->dma, qpn & 0xffffff, 0,
 427                       MLX4_CMD_UPDATE_QP, MLX4_CMD_TIME_CLASS_A,
 428                       MLX4_CMD_NATIVE);
 429
 430        mlx4_free_cmd_mailbox(dev, mailbox);
 431        return err;
 432}
 433EXPORT_SYMBOL_GPL(mlx4_update_qp);
 434
 435void mlx4_qp_remove(struct mlx4_dev *dev, struct mlx4_qp *qp)
 436{
 437        struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
 438        unsigned long flags;
 439
 440        spin_lock_irqsave(&qp_table->lock, flags);
 441        radix_tree_delete(&dev->qp_table_tree, qp->qpn & (dev->caps.num_qps - 1));
 442        spin_unlock_irqrestore(&qp_table->lock, flags);
 443}
 444EXPORT_SYMBOL_GPL(mlx4_qp_remove);
 445
 446void mlx4_qp_free(struct mlx4_dev *dev, struct mlx4_qp *qp)
 447{
 448        if (atomic_dec_and_test(&qp->refcount))
 449                complete(&qp->free);
 450        wait_for_completion(&qp->free);
 451
 452        mlx4_qp_free_icm(dev, qp->qpn);
 453}
 454EXPORT_SYMBOL_GPL(mlx4_qp_free);
 455
 456static int mlx4_CONF_SPECIAL_QP(struct mlx4_dev *dev, u32 base_qpn)
 457{
 458        return mlx4_cmd(dev, 0, base_qpn, 0, MLX4_CMD_CONF_SPECIAL_QP,
 459                        MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
 460}
 461
 462int mlx4_init_qp_table(struct mlx4_dev *dev)
 463{
 464        struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
 465        int err;
 466        int reserved_from_top = 0;
 467        int k;
 468
 469        spin_lock_init(&qp_table->lock);
 470        INIT_RADIX_TREE(&dev->qp_table_tree, GFP_ATOMIC);
 471        if (mlx4_is_slave(dev))
 472                return 0;
 473
 474        /*
 475         * We reserve 2 extra QPs per port for the special QPs.  The
 476         * block of special QPs must be aligned to a multiple of 8, so
 477         * round up.
 478         *
 479         * We also reserve the MSB of the 24-bit QP number to indicate
 480         * that a QP is an XRC QP.
 481         */
 482        dev->phys_caps.base_sqpn =
 483                ALIGN(dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW], 8);
 484
 485        {
 486                int sort[MLX4_NUM_QP_REGION];
 487                int i, j, tmp;
 488                int last_base = dev->caps.num_qps;
 489
 490                for (i = 1; i < MLX4_NUM_QP_REGION; ++i)
 491                        sort[i] = i;
 492
 493                for (i = MLX4_NUM_QP_REGION; i > 0; --i) {
 494                        for (j = 2; j < i; ++j) {
 495                                if (dev->caps.reserved_qps_cnt[sort[j]] >
 496                                    dev->caps.reserved_qps_cnt[sort[j - 1]]) {
 497                                        tmp             = sort[j];
 498                                        sort[j]         = sort[j - 1];
 499                                        sort[j - 1]     = tmp;
 500                                }
 501                        }
 502                }
 503
 504                for (i = 1; i < MLX4_NUM_QP_REGION; ++i) {
 505                        last_base -= dev->caps.reserved_qps_cnt[sort[i]];
 506                        dev->caps.reserved_qps_base[sort[i]] = last_base;
 507                        reserved_from_top +=
 508                                dev->caps.reserved_qps_cnt[sort[i]];
 509                }
 510
 511        }
 512
 513       /* Reserve 8 real SQPs in both native and SRIOV modes.
 514        * In addition, in SRIOV mode, reserve 8 proxy SQPs per function
 515        * (for all PFs and VFs), and 8 corresponding tunnel QPs.
 516        * Each proxy SQP works opposite its own tunnel QP.
 517        *
 518        * The QPs are arranged as follows:
 519        * a. 8 real SQPs
 520        * b. All the proxy SQPs (8 per function)
 521        * c. All the tunnel QPs (8 per function)
 522        */
 523
 524        err = mlx4_bitmap_init(&qp_table->bitmap, dev->caps.num_qps,
 525                               (1 << 23) - 1, mlx4_num_reserved_sqps(dev),
 526                               reserved_from_top);
 527        if (err)
 528                return err;
 529
 530        if (mlx4_is_mfunc(dev)) {
 531                /* for PPF use */
 532                dev->phys_caps.base_proxy_sqpn = dev->phys_caps.base_sqpn + 8;
 533                dev->phys_caps.base_tunnel_sqpn = dev->phys_caps.base_sqpn + 8 + 8 * MLX4_MFUNC_MAX;
 534
 535                /* In mfunc, calculate proxy and tunnel qp offsets for the PF here,
 536                 * since the PF does not call mlx4_slave_caps */
 537                dev->caps.qp0_tunnel = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL);
 538                dev->caps.qp0_proxy = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL);
 539                dev->caps.qp1_tunnel = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL);
 540                dev->caps.qp1_proxy = kcalloc(dev->caps.num_ports, sizeof (u32), GFP_KERNEL);
 541
 542                if (!dev->caps.qp0_tunnel || !dev->caps.qp0_proxy ||
 543                    !dev->caps.qp1_tunnel || !dev->caps.qp1_proxy) {
 544                        err = -ENOMEM;
 545                        goto err_mem;
 546                }
 547
 548                for (k = 0; k < dev->caps.num_ports; k++) {
 549                        dev->caps.qp0_proxy[k] = dev->phys_caps.base_proxy_sqpn +
 550                                8 * mlx4_master_func_num(dev) + k;
 551                        dev->caps.qp0_tunnel[k] = dev->caps.qp0_proxy[k] + 8 * MLX4_MFUNC_MAX;
 552                        dev->caps.qp1_proxy[k] = dev->phys_caps.base_proxy_sqpn +
 553                                8 * mlx4_master_func_num(dev) + MLX4_MAX_PORTS + k;
 554                        dev->caps.qp1_tunnel[k] = dev->caps.qp1_proxy[k] + 8 * MLX4_MFUNC_MAX;
 555                }
 556        }
 557
 558
 559        err = mlx4_CONF_SPECIAL_QP(dev, dev->phys_caps.base_sqpn);
 560        if (err)
 561                goto err_mem;
 562        return 0;
 563
 564err_mem:
 565        kfree(dev->caps.qp0_tunnel);
 566        kfree(dev->caps.qp0_proxy);
 567        kfree(dev->caps.qp1_tunnel);
 568        kfree(dev->caps.qp1_proxy);
 569        dev->caps.qp0_tunnel = dev->caps.qp0_proxy =
 570                dev->caps.qp1_tunnel = dev->caps.qp1_proxy = NULL;
 571        return err;
 572}
 573
 574void mlx4_cleanup_qp_table(struct mlx4_dev *dev)
 575{
 576        if (mlx4_is_slave(dev))
 577                return;
 578
 579        mlx4_CONF_SPECIAL_QP(dev, 0);
 580        mlx4_bitmap_cleanup(&mlx4_priv(dev)->qp_table.bitmap);
 581}
 582
 583int mlx4_qp_query(struct mlx4_dev *dev, struct mlx4_qp *qp,
 584                  struct mlx4_qp_context *context)
 585{
 586        struct mlx4_cmd_mailbox *mailbox;
 587        int err;
 588
 589        mailbox = mlx4_alloc_cmd_mailbox(dev);
 590        if (IS_ERR(mailbox))
 591                return PTR_ERR(mailbox);
 592
 593        err = mlx4_cmd_box(dev, 0, mailbox->dma, qp->qpn, 0,
 594                           MLX4_CMD_QUERY_QP, MLX4_CMD_TIME_CLASS_A,
 595                           MLX4_CMD_WRAPPED);
 596        if (!err)
 597                memcpy(context, mailbox->buf + 8, sizeof *context);
 598
 599        mlx4_free_cmd_mailbox(dev, mailbox);
 600        return err;
 601}
 602EXPORT_SYMBOL_GPL(mlx4_qp_query);
 603
 604int mlx4_qp_to_ready(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
 605                     struct mlx4_qp_context *context,
 606                     struct mlx4_qp *qp, enum mlx4_qp_state *qp_state)
 607{
 608        int err;
 609        int i;
 610        enum mlx4_qp_state states[] = {
 611                MLX4_QP_STATE_RST,
 612                MLX4_QP_STATE_INIT,
 613                MLX4_QP_STATE_RTR,
 614                MLX4_QP_STATE_RTS
 615        };
 616
 617        for (i = 0; i < ARRAY_SIZE(states) - 1; i++) {
 618                context->flags &= cpu_to_be32(~(0xf << 28));
 619                context->flags |= cpu_to_be32(states[i + 1] << 28);
 620                err = mlx4_qp_modify(dev, mtt, states[i], states[i + 1],
 621                                     context, 0, 0, qp);
 622                if (err) {
 623                        mlx4_err(dev, "Failed to bring QP to state: %d with error: %d\n",
 624                                 states[i + 1], err);
 625                        return err;
 626                }
 627
 628                *qp_state = states[i + 1];
 629        }
 630
 631        return 0;
 632}
 633EXPORT_SYMBOL_GPL(mlx4_qp_to_ready);
 634