linux/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
   3 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies.
   4 * All rights reserved.
   5 * Copyright (c) 2005, 2006, 2007 Cisco Systems, 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/sched.h>
  37#include <linux/pci.h>
  38#include <linux/errno.h>
  39#include <linux/kernel.h>
  40#include <linux/io.h>
  41#include <linux/slab.h>
  42#include <linux/mlx4/cmd.h>
  43#include <linux/mlx4/qp.h>
  44#include <linux/if_ether.h>
  45#include <linux/etherdevice.h>
  46
  47#include "mlx4.h"
  48#include "fw.h"
  49#include "mlx4_stats.h"
  50
  51#define MLX4_MAC_VALID          (1ull << 63)
  52#define MLX4_PF_COUNTERS_PER_PORT       2
  53#define MLX4_VF_COUNTERS_PER_PORT       1
  54
  55struct mac_res {
  56        struct list_head list;
  57        u64 mac;
  58        int ref_count;
  59        u8 smac_index;
  60        u8 port;
  61};
  62
  63struct vlan_res {
  64        struct list_head list;
  65        u16 vlan;
  66        int ref_count;
  67        int vlan_index;
  68        u8 port;
  69};
  70
  71struct res_common {
  72        struct list_head        list;
  73        struct rb_node          node;
  74        u64                     res_id;
  75        int                     owner;
  76        int                     state;
  77        int                     from_state;
  78        int                     to_state;
  79        int                     removing;
  80        const char              *func_name;
  81};
  82
  83enum {
  84        RES_ANY_BUSY = 1
  85};
  86
  87struct res_gid {
  88        struct list_head        list;
  89        u8                      gid[16];
  90        enum mlx4_protocol      prot;
  91        enum mlx4_steer_type    steer;
  92        u64                     reg_id;
  93};
  94
  95enum res_qp_states {
  96        RES_QP_BUSY = RES_ANY_BUSY,
  97
  98        /* QP number was allocated */
  99        RES_QP_RESERVED,
 100
 101        /* ICM memory for QP context was mapped */
 102        RES_QP_MAPPED,
 103
 104        /* QP is in hw ownership */
 105        RES_QP_HW
 106};
 107
 108struct res_qp {
 109        struct res_common       com;
 110        struct res_mtt         *mtt;
 111        struct res_cq          *rcq;
 112        struct res_cq          *scq;
 113        struct res_srq         *srq;
 114        struct list_head        mcg_list;
 115        spinlock_t              mcg_spl;
 116        int                     local_qpn;
 117        atomic_t                ref_count;
 118        u32                     qpc_flags;
 119        /* saved qp params before VST enforcement in order to restore on VGT */
 120        u8                      sched_queue;
 121        __be32                  param3;
 122        u8                      vlan_control;
 123        u8                      fvl_rx;
 124        u8                      pri_path_fl;
 125        u8                      vlan_index;
 126        u8                      feup;
 127};
 128
 129enum res_mtt_states {
 130        RES_MTT_BUSY = RES_ANY_BUSY,
 131        RES_MTT_ALLOCATED,
 132};
 133
 134static inline const char *mtt_states_str(enum res_mtt_states state)
 135{
 136        switch (state) {
 137        case RES_MTT_BUSY: return "RES_MTT_BUSY";
 138        case RES_MTT_ALLOCATED: return "RES_MTT_ALLOCATED";
 139        default: return "Unknown";
 140        }
 141}
 142
 143struct res_mtt {
 144        struct res_common       com;
 145        int                     order;
 146        atomic_t                ref_count;
 147};
 148
 149enum res_mpt_states {
 150        RES_MPT_BUSY = RES_ANY_BUSY,
 151        RES_MPT_RESERVED,
 152        RES_MPT_MAPPED,
 153        RES_MPT_HW,
 154};
 155
 156struct res_mpt {
 157        struct res_common       com;
 158        struct res_mtt         *mtt;
 159        int                     key;
 160};
 161
 162enum res_eq_states {
 163        RES_EQ_BUSY = RES_ANY_BUSY,
 164        RES_EQ_RESERVED,
 165        RES_EQ_HW,
 166};
 167
 168struct res_eq {
 169        struct res_common       com;
 170        struct res_mtt         *mtt;
 171};
 172
 173enum res_cq_states {
 174        RES_CQ_BUSY = RES_ANY_BUSY,
 175        RES_CQ_ALLOCATED,
 176        RES_CQ_HW,
 177};
 178
 179struct res_cq {
 180        struct res_common       com;
 181        struct res_mtt         *mtt;
 182        atomic_t                ref_count;
 183};
 184
 185enum res_srq_states {
 186        RES_SRQ_BUSY = RES_ANY_BUSY,
 187        RES_SRQ_ALLOCATED,
 188        RES_SRQ_HW,
 189};
 190
 191struct res_srq {
 192        struct res_common       com;
 193        struct res_mtt         *mtt;
 194        struct res_cq          *cq;
 195        atomic_t                ref_count;
 196};
 197
 198enum res_counter_states {
 199        RES_COUNTER_BUSY = RES_ANY_BUSY,
 200        RES_COUNTER_ALLOCATED,
 201};
 202
 203struct res_counter {
 204        struct res_common       com;
 205        int                     port;
 206};
 207
 208enum res_xrcdn_states {
 209        RES_XRCD_BUSY = RES_ANY_BUSY,
 210        RES_XRCD_ALLOCATED,
 211};
 212
 213struct res_xrcdn {
 214        struct res_common       com;
 215        int                     port;
 216};
 217
 218enum res_fs_rule_states {
 219        RES_FS_RULE_BUSY = RES_ANY_BUSY,
 220        RES_FS_RULE_ALLOCATED,
 221};
 222
 223struct res_fs_rule {
 224        struct res_common       com;
 225        int                     qpn;
 226        /* VF DMFS mbox with port flipped */
 227        void                    *mirr_mbox;
 228        /* > 0 --> apply mirror when getting into HA mode      */
 229        /* = 0 --> un-apply mirror when getting out of HA mode */
 230        u32                     mirr_mbox_size;
 231        struct list_head        mirr_list;
 232        u64                     mirr_rule_id;
 233};
 234
 235static void *res_tracker_lookup(struct rb_root *root, u64 res_id)
 236{
 237        struct rb_node *node = root->rb_node;
 238
 239        while (node) {
 240                struct res_common *res = rb_entry(node, struct res_common,
 241                                                  node);
 242
 243                if (res_id < res->res_id)
 244                        node = node->rb_left;
 245                else if (res_id > res->res_id)
 246                        node = node->rb_right;
 247                else
 248                        return res;
 249        }
 250        return NULL;
 251}
 252
 253static int res_tracker_insert(struct rb_root *root, struct res_common *res)
 254{
 255        struct rb_node **new = &(root->rb_node), *parent = NULL;
 256
 257        /* Figure out where to put new node */
 258        while (*new) {
 259                struct res_common *this = rb_entry(*new, struct res_common,
 260                                                   node);
 261
 262                parent = *new;
 263                if (res->res_id < this->res_id)
 264                        new = &((*new)->rb_left);
 265                else if (res->res_id > this->res_id)
 266                        new = &((*new)->rb_right);
 267                else
 268                        return -EEXIST;
 269        }
 270
 271        /* Add new node and rebalance tree. */
 272        rb_link_node(&res->node, parent, new);
 273        rb_insert_color(&res->node, root);
 274
 275        return 0;
 276}
 277
 278enum qp_transition {
 279        QP_TRANS_INIT2RTR,
 280        QP_TRANS_RTR2RTS,
 281        QP_TRANS_RTS2RTS,
 282        QP_TRANS_SQERR2RTS,
 283        QP_TRANS_SQD2SQD,
 284        QP_TRANS_SQD2RTS
 285};
 286
 287/* For Debug uses */
 288static const char *resource_str(enum mlx4_resource rt)
 289{
 290        switch (rt) {
 291        case RES_QP: return "RES_QP";
 292        case RES_CQ: return "RES_CQ";
 293        case RES_SRQ: return "RES_SRQ";
 294        case RES_MPT: return "RES_MPT";
 295        case RES_MTT: return "RES_MTT";
 296        case RES_MAC: return  "RES_MAC";
 297        case RES_VLAN: return  "RES_VLAN";
 298        case RES_EQ: return "RES_EQ";
 299        case RES_COUNTER: return "RES_COUNTER";
 300        case RES_FS_RULE: return "RES_FS_RULE";
 301        case RES_XRCD: return "RES_XRCD";
 302        default: return "Unknown resource type !!!";
 303        }
 304}
 305
 306static void rem_slave_vlans(struct mlx4_dev *dev, int slave);
 307static inline int mlx4_grant_resource(struct mlx4_dev *dev, int slave,
 308                                      enum mlx4_resource res_type, int count,
 309                                      int port)
 310{
 311        struct mlx4_priv *priv = mlx4_priv(dev);
 312        struct resource_allocator *res_alloc =
 313                &priv->mfunc.master.res_tracker.res_alloc[res_type];
 314        int err = -EDQUOT;
 315        int allocated, free, reserved, guaranteed, from_free;
 316        int from_rsvd;
 317
 318        if (slave > dev->persist->num_vfs)
 319                return -EINVAL;
 320
 321        spin_lock(&res_alloc->alloc_lock);
 322        allocated = (port > 0) ?
 323                res_alloc->allocated[(port - 1) *
 324                (dev->persist->num_vfs + 1) + slave] :
 325                res_alloc->allocated[slave];
 326        free = (port > 0) ? res_alloc->res_port_free[port - 1] :
 327                res_alloc->res_free;
 328        reserved = (port > 0) ? res_alloc->res_port_rsvd[port - 1] :
 329                res_alloc->res_reserved;
 330        guaranteed = res_alloc->guaranteed[slave];
 331
 332        if (allocated + count > res_alloc->quota[slave]) {
 333                mlx4_warn(dev, "VF %d port %d res %s: quota exceeded, count %d alloc %d quota %d\n",
 334                          slave, port, resource_str(res_type), count,
 335                          allocated, res_alloc->quota[slave]);
 336                goto out;
 337        }
 338
 339        if (allocated + count <= guaranteed) {
 340                err = 0;
 341                from_rsvd = count;
 342        } else {
 343                /* portion may need to be obtained from free area */
 344                if (guaranteed - allocated > 0)
 345                        from_free = count - (guaranteed - allocated);
 346                else
 347                        from_free = count;
 348
 349                from_rsvd = count - from_free;
 350
 351                if (free - from_free >= reserved)
 352                        err = 0;
 353                else
 354                        mlx4_warn(dev, "VF %d port %d res %s: free pool empty, free %d from_free %d rsvd %d\n",
 355                                  slave, port, resource_str(res_type), free,
 356                                  from_free, reserved);
 357        }
 358
 359        if (!err) {
 360                /* grant the request */
 361                if (port > 0) {
 362                        res_alloc->allocated[(port - 1) *
 363                        (dev->persist->num_vfs + 1) + slave] += count;
 364                        res_alloc->res_port_free[port - 1] -= count;
 365                        res_alloc->res_port_rsvd[port - 1] -= from_rsvd;
 366                } else {
 367                        res_alloc->allocated[slave] += count;
 368                        res_alloc->res_free -= count;
 369                        res_alloc->res_reserved -= from_rsvd;
 370                }
 371        }
 372
 373out:
 374        spin_unlock(&res_alloc->alloc_lock);
 375        return err;
 376}
 377
 378static inline void mlx4_release_resource(struct mlx4_dev *dev, int slave,
 379                                    enum mlx4_resource res_type, int count,
 380                                    int port)
 381{
 382        struct mlx4_priv *priv = mlx4_priv(dev);
 383        struct resource_allocator *res_alloc =
 384                &priv->mfunc.master.res_tracker.res_alloc[res_type];
 385        int allocated, guaranteed, from_rsvd;
 386
 387        if (slave > dev->persist->num_vfs)
 388                return;
 389
 390        spin_lock(&res_alloc->alloc_lock);
 391
 392        allocated = (port > 0) ?
 393                res_alloc->allocated[(port - 1) *
 394                (dev->persist->num_vfs + 1) + slave] :
 395                res_alloc->allocated[slave];
 396        guaranteed = res_alloc->guaranteed[slave];
 397
 398        if (allocated - count >= guaranteed) {
 399                from_rsvd = 0;
 400        } else {
 401                /* portion may need to be returned to reserved area */
 402                if (allocated - guaranteed > 0)
 403                        from_rsvd = count - (allocated - guaranteed);
 404                else
 405                        from_rsvd = count;
 406        }
 407
 408        if (port > 0) {
 409                res_alloc->allocated[(port - 1) *
 410                (dev->persist->num_vfs + 1) + slave] -= count;
 411                res_alloc->res_port_free[port - 1] += count;
 412                res_alloc->res_port_rsvd[port - 1] += from_rsvd;
 413        } else {
 414                res_alloc->allocated[slave] -= count;
 415                res_alloc->res_free += count;
 416                res_alloc->res_reserved += from_rsvd;
 417        }
 418
 419        spin_unlock(&res_alloc->alloc_lock);
 420        return;
 421}
 422
 423static inline void initialize_res_quotas(struct mlx4_dev *dev,
 424                                         struct resource_allocator *res_alloc,
 425                                         enum mlx4_resource res_type,
 426                                         int vf, int num_instances)
 427{
 428        res_alloc->guaranteed[vf] = num_instances /
 429                                    (2 * (dev->persist->num_vfs + 1));
 430        res_alloc->quota[vf] = (num_instances / 2) + res_alloc->guaranteed[vf];
 431        if (vf == mlx4_master_func_num(dev)) {
 432                res_alloc->res_free = num_instances;
 433                if (res_type == RES_MTT) {
 434                        /* reserved mtts will be taken out of the PF allocation */
 435                        res_alloc->res_free += dev->caps.reserved_mtts;
 436                        res_alloc->guaranteed[vf] += dev->caps.reserved_mtts;
 437                        res_alloc->quota[vf] += dev->caps.reserved_mtts;
 438                }
 439        }
 440}
 441
 442void mlx4_init_quotas(struct mlx4_dev *dev)
 443{
 444        struct mlx4_priv *priv = mlx4_priv(dev);
 445        int pf;
 446
 447        /* quotas for VFs are initialized in mlx4_slave_cap */
 448        if (mlx4_is_slave(dev))
 449                return;
 450
 451        if (!mlx4_is_mfunc(dev)) {
 452                dev->quotas.qp = dev->caps.num_qps - dev->caps.reserved_qps -
 453                        mlx4_num_reserved_sqps(dev);
 454                dev->quotas.cq = dev->caps.num_cqs - dev->caps.reserved_cqs;
 455                dev->quotas.srq = dev->caps.num_srqs - dev->caps.reserved_srqs;
 456                dev->quotas.mtt = dev->caps.num_mtts - dev->caps.reserved_mtts;
 457                dev->quotas.mpt = dev->caps.num_mpts - dev->caps.reserved_mrws;
 458                return;
 459        }
 460
 461        pf = mlx4_master_func_num(dev);
 462        dev->quotas.qp =
 463                priv->mfunc.master.res_tracker.res_alloc[RES_QP].quota[pf];
 464        dev->quotas.cq =
 465                priv->mfunc.master.res_tracker.res_alloc[RES_CQ].quota[pf];
 466        dev->quotas.srq =
 467                priv->mfunc.master.res_tracker.res_alloc[RES_SRQ].quota[pf];
 468        dev->quotas.mtt =
 469                priv->mfunc.master.res_tracker.res_alloc[RES_MTT].quota[pf];
 470        dev->quotas.mpt =
 471                priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[pf];
 472}
 473
 474static int
 475mlx4_calc_res_counter_guaranteed(struct mlx4_dev *dev,
 476                                 struct resource_allocator *res_alloc,
 477                                 int vf)
 478{
 479        struct mlx4_active_ports actv_ports;
 480        int ports, counters_guaranteed;
 481
 482        /* For master, only allocate according to the number of phys ports */
 483        if (vf == mlx4_master_func_num(dev))
 484                return MLX4_PF_COUNTERS_PER_PORT * dev->caps.num_ports;
 485
 486        /* calculate real number of ports for the VF */
 487        actv_ports = mlx4_get_active_ports(dev, vf);
 488        ports = bitmap_weight(actv_ports.ports, dev->caps.num_ports);
 489        counters_guaranteed = ports * MLX4_VF_COUNTERS_PER_PORT;
 490
 491        /* If we do not have enough counters for this VF, do not
 492         * allocate any for it. '-1' to reduce the sink counter.
 493         */
 494        if ((res_alloc->res_reserved + counters_guaranteed) >
 495            (dev->caps.max_counters - 1))
 496                return 0;
 497
 498        return counters_guaranteed;
 499}
 500
 501int mlx4_init_resource_tracker(struct mlx4_dev *dev)
 502{
 503        struct mlx4_priv *priv = mlx4_priv(dev);
 504        int i, j;
 505        int t;
 506
 507        priv->mfunc.master.res_tracker.slave_list =
 508                kcalloc(dev->num_slaves, sizeof(struct slave_list),
 509                        GFP_KERNEL);
 510        if (!priv->mfunc.master.res_tracker.slave_list)
 511                return -ENOMEM;
 512
 513        for (i = 0 ; i < dev->num_slaves; i++) {
 514                for (t = 0; t < MLX4_NUM_OF_RESOURCE_TYPE; ++t)
 515                        INIT_LIST_HEAD(&priv->mfunc.master.res_tracker.
 516                                       slave_list[i].res_list[t]);
 517                mutex_init(&priv->mfunc.master.res_tracker.slave_list[i].mutex);
 518        }
 519
 520        mlx4_dbg(dev, "Started init_resource_tracker: %ld slaves\n",
 521                 dev->num_slaves);
 522        for (i = 0 ; i < MLX4_NUM_OF_RESOURCE_TYPE; i++)
 523                priv->mfunc.master.res_tracker.res_tree[i] = RB_ROOT;
 524
 525        for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) {
 526                struct resource_allocator *res_alloc =
 527                        &priv->mfunc.master.res_tracker.res_alloc[i];
 528                res_alloc->quota = kmalloc_array(dev->persist->num_vfs + 1,
 529                                                 sizeof(int),
 530                                                 GFP_KERNEL);
 531                res_alloc->guaranteed = kmalloc_array(dev->persist->num_vfs + 1,
 532                                                      sizeof(int),
 533                                                      GFP_KERNEL);
 534                if (i == RES_MAC || i == RES_VLAN)
 535                        res_alloc->allocated =
 536                                kcalloc(MLX4_MAX_PORTS *
 537                                                (dev->persist->num_vfs + 1),
 538                                        sizeof(int), GFP_KERNEL);
 539                else
 540                        res_alloc->allocated =
 541                                kcalloc(dev->persist->num_vfs + 1,
 542                                        sizeof(int), GFP_KERNEL);
 543                /* Reduce the sink counter */
 544                if (i == RES_COUNTER)
 545                        res_alloc->res_free = dev->caps.max_counters - 1;
 546
 547                if (!res_alloc->quota || !res_alloc->guaranteed ||
 548                    !res_alloc->allocated)
 549                        goto no_mem_err;
 550
 551                spin_lock_init(&res_alloc->alloc_lock);
 552                for (t = 0; t < dev->persist->num_vfs + 1; t++) {
 553                        struct mlx4_active_ports actv_ports =
 554                                mlx4_get_active_ports(dev, t);
 555                        switch (i) {
 556                        case RES_QP:
 557                                initialize_res_quotas(dev, res_alloc, RES_QP,
 558                                                      t, dev->caps.num_qps -
 559                                                      dev->caps.reserved_qps -
 560                                                      mlx4_num_reserved_sqps(dev));
 561                                break;
 562                        case RES_CQ:
 563                                initialize_res_quotas(dev, res_alloc, RES_CQ,
 564                                                      t, dev->caps.num_cqs -
 565                                                      dev->caps.reserved_cqs);
 566                                break;
 567                        case RES_SRQ:
 568                                initialize_res_quotas(dev, res_alloc, RES_SRQ,
 569                                                      t, dev->caps.num_srqs -
 570                                                      dev->caps.reserved_srqs);
 571                                break;
 572                        case RES_MPT:
 573                                initialize_res_quotas(dev, res_alloc, RES_MPT,
 574                                                      t, dev->caps.num_mpts -
 575                                                      dev->caps.reserved_mrws);
 576                                break;
 577                        case RES_MTT:
 578                                initialize_res_quotas(dev, res_alloc, RES_MTT,
 579                                                      t, dev->caps.num_mtts -
 580                                                      dev->caps.reserved_mtts);
 581                                break;
 582                        case RES_MAC:
 583                                if (t == mlx4_master_func_num(dev)) {
 584                                        int max_vfs_pport = 0;
 585                                        /* Calculate the max vfs per port for */
 586                                        /* both ports.                        */
 587                                        for (j = 0; j < dev->caps.num_ports;
 588                                             j++) {
 589                                                struct mlx4_slaves_pport slaves_pport =
 590                                                        mlx4_phys_to_slaves_pport(dev, j + 1);
 591                                                unsigned current_slaves =
 592                                                        bitmap_weight(slaves_pport.slaves,
 593                                                                      dev->caps.num_ports) - 1;
 594                                                if (max_vfs_pport < current_slaves)
 595                                                        max_vfs_pport =
 596                                                                current_slaves;
 597                                        }
 598                                        res_alloc->quota[t] =
 599                                                MLX4_MAX_MAC_NUM -
 600                                                2 * max_vfs_pport;
 601                                        res_alloc->guaranteed[t] = 2;
 602                                        for (j = 0; j < MLX4_MAX_PORTS; j++)
 603                                                res_alloc->res_port_free[j] =
 604                                                        MLX4_MAX_MAC_NUM;
 605                                } else {
 606                                        res_alloc->quota[t] = MLX4_MAX_MAC_NUM;
 607                                        res_alloc->guaranteed[t] = 2;
 608                                }
 609                                break;
 610                        case RES_VLAN:
 611                                if (t == mlx4_master_func_num(dev)) {
 612                                        res_alloc->quota[t] = MLX4_MAX_VLAN_NUM;
 613                                        res_alloc->guaranteed[t] = MLX4_MAX_VLAN_NUM / 2;
 614                                        for (j = 0; j < MLX4_MAX_PORTS; j++)
 615                                                res_alloc->res_port_free[j] =
 616                                                        res_alloc->quota[t];
 617                                } else {
 618                                        res_alloc->quota[t] = MLX4_MAX_VLAN_NUM / 2;
 619                                        res_alloc->guaranteed[t] = 0;
 620                                }
 621                                break;
 622                        case RES_COUNTER:
 623                                res_alloc->quota[t] = dev->caps.max_counters;
 624                                res_alloc->guaranteed[t] =
 625                                        mlx4_calc_res_counter_guaranteed(dev, res_alloc, t);
 626                                break;
 627                        default:
 628                                break;
 629                        }
 630                        if (i == RES_MAC || i == RES_VLAN) {
 631                                for (j = 0; j < dev->caps.num_ports; j++)
 632                                        if (test_bit(j, actv_ports.ports))
 633                                                res_alloc->res_port_rsvd[j] +=
 634                                                        res_alloc->guaranteed[t];
 635                        } else {
 636                                res_alloc->res_reserved += res_alloc->guaranteed[t];
 637                        }
 638                }
 639        }
 640        spin_lock_init(&priv->mfunc.master.res_tracker.lock);
 641        return 0;
 642
 643no_mem_err:
 644        for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) {
 645                kfree(priv->mfunc.master.res_tracker.res_alloc[i].allocated);
 646                priv->mfunc.master.res_tracker.res_alloc[i].allocated = NULL;
 647                kfree(priv->mfunc.master.res_tracker.res_alloc[i].guaranteed);
 648                priv->mfunc.master.res_tracker.res_alloc[i].guaranteed = NULL;
 649                kfree(priv->mfunc.master.res_tracker.res_alloc[i].quota);
 650                priv->mfunc.master.res_tracker.res_alloc[i].quota = NULL;
 651        }
 652        return -ENOMEM;
 653}
 654
 655void mlx4_free_resource_tracker(struct mlx4_dev *dev,
 656                                enum mlx4_res_tracker_free_type type)
 657{
 658        struct mlx4_priv *priv = mlx4_priv(dev);
 659        int i;
 660
 661        if (priv->mfunc.master.res_tracker.slave_list) {
 662                if (type != RES_TR_FREE_STRUCTS_ONLY) {
 663                        for (i = 0; i < dev->num_slaves; i++) {
 664                                if (type == RES_TR_FREE_ALL ||
 665                                    dev->caps.function != i)
 666                                        mlx4_delete_all_resources_for_slave(dev, i);
 667                        }
 668                        /* free master's vlans */
 669                        i = dev->caps.function;
 670                        mlx4_reset_roce_gids(dev, i);
 671                        mutex_lock(&priv->mfunc.master.res_tracker.slave_list[i].mutex);
 672                        rem_slave_vlans(dev, i);
 673                        mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[i].mutex);
 674                }
 675
 676                if (type != RES_TR_FREE_SLAVES_ONLY) {
 677                        for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) {
 678                                kfree(priv->mfunc.master.res_tracker.res_alloc[i].allocated);
 679                                priv->mfunc.master.res_tracker.res_alloc[i].allocated = NULL;
 680                                kfree(priv->mfunc.master.res_tracker.res_alloc[i].guaranteed);
 681                                priv->mfunc.master.res_tracker.res_alloc[i].guaranteed = NULL;
 682                                kfree(priv->mfunc.master.res_tracker.res_alloc[i].quota);
 683                                priv->mfunc.master.res_tracker.res_alloc[i].quota = NULL;
 684                        }
 685                        kfree(priv->mfunc.master.res_tracker.slave_list);
 686                        priv->mfunc.master.res_tracker.slave_list = NULL;
 687                }
 688        }
 689}
 690
 691static void update_pkey_index(struct mlx4_dev *dev, int slave,
 692                              struct mlx4_cmd_mailbox *inbox)
 693{
 694        u8 sched = *(u8 *)(inbox->buf + 64);
 695        u8 orig_index = *(u8 *)(inbox->buf + 35);
 696        u8 new_index;
 697        struct mlx4_priv *priv = mlx4_priv(dev);
 698        int port;
 699
 700        port = (sched >> 6 & 1) + 1;
 701
 702        new_index = priv->virt2phys_pkey[slave][port - 1][orig_index];
 703        *(u8 *)(inbox->buf + 35) = new_index;
 704}
 705
 706static void update_gid(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *inbox,
 707                       u8 slave)
 708{
 709        struct mlx4_qp_context  *qp_ctx = inbox->buf + 8;
 710        enum mlx4_qp_optpar     optpar = be32_to_cpu(*(__be32 *) inbox->buf);
 711        u32                     ts = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff;
 712        int port;
 713
 714        if (MLX4_QP_ST_UD == ts) {
 715                port = (qp_ctx->pri_path.sched_queue >> 6 & 1) + 1;
 716                if (mlx4_is_eth(dev, port))
 717                        qp_ctx->pri_path.mgid_index =
 718                                mlx4_get_base_gid_ix(dev, slave, port) | 0x80;
 719                else
 720                        qp_ctx->pri_path.mgid_index = slave | 0x80;
 721
 722        } else if (MLX4_QP_ST_RC == ts || MLX4_QP_ST_XRC == ts || MLX4_QP_ST_UC == ts) {
 723                if (optpar & MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH) {
 724                        port = (qp_ctx->pri_path.sched_queue >> 6 & 1) + 1;
 725                        if (mlx4_is_eth(dev, port)) {
 726                                qp_ctx->pri_path.mgid_index +=
 727                                        mlx4_get_base_gid_ix(dev, slave, port);
 728                                qp_ctx->pri_path.mgid_index &= 0x7f;
 729                        } else {
 730                                qp_ctx->pri_path.mgid_index = slave & 0x7F;
 731                        }
 732                }
 733                if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) {
 734                        port = (qp_ctx->alt_path.sched_queue >> 6 & 1) + 1;
 735                        if (mlx4_is_eth(dev, port)) {
 736                                qp_ctx->alt_path.mgid_index +=
 737                                        mlx4_get_base_gid_ix(dev, slave, port);
 738                                qp_ctx->alt_path.mgid_index &= 0x7f;
 739                        } else {
 740                                qp_ctx->alt_path.mgid_index = slave & 0x7F;
 741                        }
 742                }
 743        }
 744}
 745
 746static int handle_counter(struct mlx4_dev *dev, struct mlx4_qp_context *qpc,
 747                          u8 slave, int port);
 748
 749static int update_vport_qp_param(struct mlx4_dev *dev,
 750                                 struct mlx4_cmd_mailbox *inbox,
 751                                 u8 slave, u32 qpn)
 752{
 753        struct mlx4_qp_context  *qpc = inbox->buf + 8;
 754        struct mlx4_vport_oper_state *vp_oper;
 755        struct mlx4_priv *priv;
 756        u32 qp_type;
 757        int port, err = 0;
 758
 759        port = (qpc->pri_path.sched_queue & 0x40) ? 2 : 1;
 760        priv = mlx4_priv(dev);
 761        vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port];
 762        qp_type = (be32_to_cpu(qpc->flags) >> 16) & 0xff;
 763
 764        err = handle_counter(dev, qpc, slave, port);
 765        if (err)
 766                goto out;
 767
 768        if (MLX4_VGT != vp_oper->state.default_vlan) {
 769                /* the reserved QPs (special, proxy, tunnel)
 770                 * do not operate over vlans
 771                 */
 772                if (mlx4_is_qp_reserved(dev, qpn))
 773                        return 0;
 774
 775                /* force strip vlan by clear vsd, MLX QP refers to Raw Ethernet */
 776                if (qp_type == MLX4_QP_ST_UD ||
 777                    (qp_type == MLX4_QP_ST_MLX && mlx4_is_eth(dev, port))) {
 778                        if (dev->caps.bmme_flags & MLX4_BMME_FLAG_VSD_INIT2RTR) {
 779                                *(__be32 *)inbox->buf =
 780                                        cpu_to_be32(be32_to_cpu(*(__be32 *)inbox->buf) |
 781                                        MLX4_QP_OPTPAR_VLAN_STRIPPING);
 782                                qpc->param3 &= ~cpu_to_be32(MLX4_STRIP_VLAN);
 783                        } else {
 784                                struct mlx4_update_qp_params params = {.flags = 0};
 785
 786                                err = mlx4_update_qp(dev, qpn, MLX4_UPDATE_QP_VSD, &params);
 787                                if (err)
 788                                        goto out;
 789                        }
 790                }
 791
 792                /* preserve IF_COUNTER flag */
 793                qpc->pri_path.vlan_control &=
 794                        MLX4_CTRL_ETH_SRC_CHECK_IF_COUNTER;
 795                if (vp_oper->state.link_state == IFLA_VF_LINK_STATE_DISABLE &&
 796                    dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_UPDATE_QP) {
 797                        qpc->pri_path.vlan_control |=
 798                                MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
 799                                MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED |
 800                                MLX4_VLAN_CTRL_ETH_TX_BLOCK_UNTAGGED |
 801                                MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
 802                                MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED |
 803                                MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED;
 804                } else if (0 != vp_oper->state.default_vlan) {
 805                        if (vp_oper->state.vlan_proto == htons(ETH_P_8021AD)) {
 806                                /* vst QinQ should block untagged on TX,
 807                                 * but cvlan is in payload and phv is set so
 808                                 * hw see it as untagged. Block tagged instead.
 809                                 */
 810                                qpc->pri_path.vlan_control |=
 811                                        MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED |
 812                                        MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
 813                                        MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
 814                                        MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED;
 815                        } else { /* vst 802.1Q */
 816                                qpc->pri_path.vlan_control |=
 817                                        MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
 818                                        MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
 819                                        MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED;
 820                        }
 821                } else { /* priority tagged */
 822                        qpc->pri_path.vlan_control |=
 823                                MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
 824                                MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED;
 825                }
 826
 827                qpc->pri_path.fvl_rx |= MLX4_FVL_RX_FORCE_ETH_VLAN;
 828                qpc->pri_path.vlan_index = vp_oper->vlan_idx;
 829                qpc->pri_path.fl |= MLX4_FL_ETH_HIDE_CQE_VLAN;
 830                if (vp_oper->state.vlan_proto == htons(ETH_P_8021AD))
 831                        qpc->pri_path.fl |= MLX4_FL_SV;
 832                else
 833                        qpc->pri_path.fl |= MLX4_FL_CV;
 834                qpc->pri_path.feup |= MLX4_FEUP_FORCE_ETH_UP | MLX4_FVL_FORCE_ETH_VLAN;
 835                qpc->pri_path.sched_queue &= 0xC7;
 836                qpc->pri_path.sched_queue |= (vp_oper->state.default_qos) << 3;
 837                qpc->qos_vport = vp_oper->state.qos_vport;
 838        }
 839        if (vp_oper->state.spoofchk) {
 840                qpc->pri_path.feup |= MLX4_FSM_FORCE_ETH_SRC_MAC;
 841                qpc->pri_path.grh_mylmc = (0x80 & qpc->pri_path.grh_mylmc) + vp_oper->mac_idx;
 842        }
 843out:
 844        return err;
 845}
 846
 847static int mpt_mask(struct mlx4_dev *dev)
 848{
 849        return dev->caps.num_mpts - 1;
 850}
 851
 852static const char *mlx4_resource_type_to_str(enum mlx4_resource t)
 853{
 854        switch (t) {
 855        case RES_QP:
 856                return "QP";
 857        case RES_CQ:
 858                return "CQ";
 859        case RES_SRQ:
 860                return "SRQ";
 861        case RES_XRCD:
 862                return "XRCD";
 863        case RES_MPT:
 864                return "MPT";
 865        case RES_MTT:
 866                return "MTT";
 867        case RES_MAC:
 868                return "MAC";
 869        case RES_VLAN:
 870                return "VLAN";
 871        case RES_COUNTER:
 872                return "COUNTER";
 873        case RES_FS_RULE:
 874                return "FS_RULE";
 875        case RES_EQ:
 876                return "EQ";
 877        default:
 878                return "INVALID RESOURCE";
 879        }
 880}
 881
 882static void *find_res(struct mlx4_dev *dev, u64 res_id,
 883                      enum mlx4_resource type)
 884{
 885        struct mlx4_priv *priv = mlx4_priv(dev);
 886
 887        return res_tracker_lookup(&priv->mfunc.master.res_tracker.res_tree[type],
 888                                  res_id);
 889}
 890
 891static int _get_res(struct mlx4_dev *dev, int slave, u64 res_id,
 892                    enum mlx4_resource type,
 893                    void *res, const char *func_name)
 894{
 895        struct res_common *r;
 896        int err = 0;
 897
 898        spin_lock_irq(mlx4_tlock(dev));
 899        r = find_res(dev, res_id, type);
 900        if (!r) {
 901                err = -ENONET;
 902                goto exit;
 903        }
 904
 905        if (r->state == RES_ANY_BUSY) {
 906                mlx4_warn(dev,
 907                          "%s(%d) trying to get resource %llx of type %s, but it's already taken by %s\n",
 908                          func_name, slave, res_id, mlx4_resource_type_to_str(type),
 909                          r->func_name);
 910                err = -EBUSY;
 911                goto exit;
 912        }
 913
 914        if (r->owner != slave) {
 915                err = -EPERM;
 916                goto exit;
 917        }
 918
 919        r->from_state = r->state;
 920        r->state = RES_ANY_BUSY;
 921        r->func_name = func_name;
 922
 923        if (res)
 924                *((struct res_common **)res) = r;
 925
 926exit:
 927        spin_unlock_irq(mlx4_tlock(dev));
 928        return err;
 929}
 930
 931#define get_res(dev, slave, res_id, type, res) \
 932        _get_res((dev), (slave), (res_id), (type), (res), __func__)
 933
 934int mlx4_get_slave_from_resource_id(struct mlx4_dev *dev,
 935                                    enum mlx4_resource type,
 936                                    u64 res_id, int *slave)
 937{
 938
 939        struct res_common *r;
 940        int err = -ENOENT;
 941        int id = res_id;
 942
 943        if (type == RES_QP)
 944                id &= 0x7fffff;
 945        spin_lock(mlx4_tlock(dev));
 946
 947        r = find_res(dev, id, type);
 948        if (r) {
 949                *slave = r->owner;
 950                err = 0;
 951        }
 952        spin_unlock(mlx4_tlock(dev));
 953
 954        return err;
 955}
 956
 957static void put_res(struct mlx4_dev *dev, int slave, u64 res_id,
 958                    enum mlx4_resource type)
 959{
 960        struct res_common *r;
 961
 962        spin_lock_irq(mlx4_tlock(dev));
 963        r = find_res(dev, res_id, type);
 964        if (r) {
 965                r->state = r->from_state;
 966                r->func_name = "";
 967        }
 968        spin_unlock_irq(mlx4_tlock(dev));
 969}
 970
 971static int counter_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
 972                             u64 in_param, u64 *out_param, int port);
 973
 974static int handle_existing_counter(struct mlx4_dev *dev, u8 slave, int port,
 975                                   int counter_index)
 976{
 977        struct res_common *r;
 978        struct res_counter *counter;
 979        int ret = 0;
 980
 981        if (counter_index == MLX4_SINK_COUNTER_INDEX(dev))
 982                return ret;
 983
 984        spin_lock_irq(mlx4_tlock(dev));
 985        r = find_res(dev, counter_index, RES_COUNTER);
 986        if (!r || r->owner != slave) {
 987                ret = -EINVAL;
 988        } else {
 989                counter = container_of(r, struct res_counter, com);
 990                if (!counter->port)
 991                        counter->port = port;
 992        }
 993
 994        spin_unlock_irq(mlx4_tlock(dev));
 995        return ret;
 996}
 997
 998static int handle_unexisting_counter(struct mlx4_dev *dev,
 999                                     struct mlx4_qp_context *qpc, u8 slave,
1000                                     int port)
1001{
1002        struct mlx4_priv *priv = mlx4_priv(dev);
1003        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1004        struct res_common *tmp;
1005        struct res_counter *counter;
1006        u64 counter_idx = MLX4_SINK_COUNTER_INDEX(dev);
1007        int err = 0;
1008
1009        spin_lock_irq(mlx4_tlock(dev));
1010        list_for_each_entry(tmp,
1011                            &tracker->slave_list[slave].res_list[RES_COUNTER],
1012                            list) {
1013                counter = container_of(tmp, struct res_counter, com);
1014                if (port == counter->port) {
1015                        qpc->pri_path.counter_index  = counter->com.res_id;
1016                        spin_unlock_irq(mlx4_tlock(dev));
1017                        return 0;
1018                }
1019        }
1020        spin_unlock_irq(mlx4_tlock(dev));
1021
1022        /* No existing counter, need to allocate a new counter */
1023        err = counter_alloc_res(dev, slave, RES_OP_RESERVE, 0, 0, &counter_idx,
1024                                port);
1025        if (err == -ENOENT) {
1026                err = 0;
1027        } else if (err && err != -ENOSPC) {
1028                mlx4_err(dev, "%s: failed to create new counter for slave %d err %d\n",
1029                         __func__, slave, err);
1030        } else {
1031                qpc->pri_path.counter_index = counter_idx;
1032                mlx4_dbg(dev, "%s: alloc new counter for slave %d index %d\n",
1033                         __func__, slave, qpc->pri_path.counter_index);
1034                err = 0;
1035        }
1036
1037        return err;
1038}
1039
1040static int handle_counter(struct mlx4_dev *dev, struct mlx4_qp_context *qpc,
1041                          u8 slave, int port)
1042{
1043        if (qpc->pri_path.counter_index != MLX4_SINK_COUNTER_INDEX(dev))
1044                return handle_existing_counter(dev, slave, port,
1045                                               qpc->pri_path.counter_index);
1046
1047        return handle_unexisting_counter(dev, qpc, slave, port);
1048}
1049
1050static struct res_common *alloc_qp_tr(int id)
1051{
1052        struct res_qp *ret;
1053
1054        ret = kzalloc(sizeof(*ret), GFP_KERNEL);
1055        if (!ret)
1056                return NULL;
1057
1058        ret->com.res_id = id;
1059        ret->com.state = RES_QP_RESERVED;
1060        ret->local_qpn = id;
1061        INIT_LIST_HEAD(&ret->mcg_list);
1062        spin_lock_init(&ret->mcg_spl);
1063        atomic_set(&ret->ref_count, 0);
1064
1065        return &ret->com;
1066}
1067
1068static struct res_common *alloc_mtt_tr(int id, int order)
1069{
1070        struct res_mtt *ret;
1071
1072        ret = kzalloc(sizeof(*ret), GFP_KERNEL);
1073        if (!ret)
1074                return NULL;
1075
1076        ret->com.res_id = id;
1077        ret->order = order;
1078        ret->com.state = RES_MTT_ALLOCATED;
1079        atomic_set(&ret->ref_count, 0);
1080
1081        return &ret->com;
1082}
1083
1084static struct res_common *alloc_mpt_tr(int id, int key)
1085{
1086        struct res_mpt *ret;
1087
1088        ret = kzalloc(sizeof(*ret), GFP_KERNEL);
1089        if (!ret)
1090                return NULL;
1091
1092        ret->com.res_id = id;
1093        ret->com.state = RES_MPT_RESERVED;
1094        ret->key = key;
1095
1096        return &ret->com;
1097}
1098
1099static struct res_common *alloc_eq_tr(int id)
1100{
1101        struct res_eq *ret;
1102
1103        ret = kzalloc(sizeof(*ret), GFP_KERNEL);
1104        if (!ret)
1105                return NULL;
1106
1107        ret->com.res_id = id;
1108        ret->com.state = RES_EQ_RESERVED;
1109
1110        return &ret->com;
1111}
1112
1113static struct res_common *alloc_cq_tr(int id)
1114{
1115        struct res_cq *ret;
1116
1117        ret = kzalloc(sizeof(*ret), GFP_KERNEL);
1118        if (!ret)
1119                return NULL;
1120
1121        ret->com.res_id = id;
1122        ret->com.state = RES_CQ_ALLOCATED;
1123        atomic_set(&ret->ref_count, 0);
1124
1125        return &ret->com;
1126}
1127
1128static struct res_common *alloc_srq_tr(int id)
1129{
1130        struct res_srq *ret;
1131
1132        ret = kzalloc(sizeof(*ret), GFP_KERNEL);
1133        if (!ret)
1134                return NULL;
1135
1136        ret->com.res_id = id;
1137        ret->com.state = RES_SRQ_ALLOCATED;
1138        atomic_set(&ret->ref_count, 0);
1139
1140        return &ret->com;
1141}
1142
1143static struct res_common *alloc_counter_tr(int id, int port)
1144{
1145        struct res_counter *ret;
1146
1147        ret = kzalloc(sizeof(*ret), GFP_KERNEL);
1148        if (!ret)
1149                return NULL;
1150
1151        ret->com.res_id = id;
1152        ret->com.state = RES_COUNTER_ALLOCATED;
1153        ret->port = port;
1154
1155        return &ret->com;
1156}
1157
1158static struct res_common *alloc_xrcdn_tr(int id)
1159{
1160        struct res_xrcdn *ret;
1161
1162        ret = kzalloc(sizeof(*ret), GFP_KERNEL);
1163        if (!ret)
1164                return NULL;
1165
1166        ret->com.res_id = id;
1167        ret->com.state = RES_XRCD_ALLOCATED;
1168
1169        return &ret->com;
1170}
1171
1172static struct res_common *alloc_fs_rule_tr(u64 id, int qpn)
1173{
1174        struct res_fs_rule *ret;
1175
1176        ret = kzalloc(sizeof(*ret), GFP_KERNEL);
1177        if (!ret)
1178                return NULL;
1179
1180        ret->com.res_id = id;
1181        ret->com.state = RES_FS_RULE_ALLOCATED;
1182        ret->qpn = qpn;
1183        return &ret->com;
1184}
1185
1186static struct res_common *alloc_tr(u64 id, enum mlx4_resource type, int slave,
1187                                   int extra)
1188{
1189        struct res_common *ret;
1190
1191        switch (type) {
1192        case RES_QP:
1193                ret = alloc_qp_tr(id);
1194                break;
1195        case RES_MPT:
1196                ret = alloc_mpt_tr(id, extra);
1197                break;
1198        case RES_MTT:
1199                ret = alloc_mtt_tr(id, extra);
1200                break;
1201        case RES_EQ:
1202                ret = alloc_eq_tr(id);
1203                break;
1204        case RES_CQ:
1205                ret = alloc_cq_tr(id);
1206                break;
1207        case RES_SRQ:
1208                ret = alloc_srq_tr(id);
1209                break;
1210        case RES_MAC:
1211                pr_err("implementation missing\n");
1212                return NULL;
1213        case RES_COUNTER:
1214                ret = alloc_counter_tr(id, extra);
1215                break;
1216        case RES_XRCD:
1217                ret = alloc_xrcdn_tr(id);
1218                break;
1219        case RES_FS_RULE:
1220                ret = alloc_fs_rule_tr(id, extra);
1221                break;
1222        default:
1223                return NULL;
1224        }
1225        if (ret)
1226                ret->owner = slave;
1227
1228        return ret;
1229}
1230
1231int mlx4_calc_vf_counters(struct mlx4_dev *dev, int slave, int port,
1232                          struct mlx4_counter *data)
1233{
1234        struct mlx4_priv *priv = mlx4_priv(dev);
1235        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1236        struct res_common *tmp;
1237        struct res_counter *counter;
1238        int *counters_arr;
1239        int i = 0, err = 0;
1240
1241        memset(data, 0, sizeof(*data));
1242
1243        counters_arr = kmalloc_array(dev->caps.max_counters,
1244                                     sizeof(*counters_arr), GFP_KERNEL);
1245        if (!counters_arr)
1246                return -ENOMEM;
1247
1248        spin_lock_irq(mlx4_tlock(dev));
1249        list_for_each_entry(tmp,
1250                            &tracker->slave_list[slave].res_list[RES_COUNTER],
1251                            list) {
1252                counter = container_of(tmp, struct res_counter, com);
1253                if (counter->port == port) {
1254                        counters_arr[i] = (int)tmp->res_id;
1255                        i++;
1256                }
1257        }
1258        spin_unlock_irq(mlx4_tlock(dev));
1259        counters_arr[i] = -1;
1260
1261        i = 0;
1262
1263        while (counters_arr[i] != -1) {
1264                err = mlx4_get_counter_stats(dev, counters_arr[i], data,
1265                                             0);
1266                if (err) {
1267                        memset(data, 0, sizeof(*data));
1268                        goto table_changed;
1269                }
1270                i++;
1271        }
1272
1273table_changed:
1274        kfree(counters_arr);
1275        return 0;
1276}
1277
1278static int add_res_range(struct mlx4_dev *dev, int slave, u64 base, int count,
1279                         enum mlx4_resource type, int extra)
1280{
1281        int i;
1282        int err;
1283        struct mlx4_priv *priv = mlx4_priv(dev);
1284        struct res_common **res_arr;
1285        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1286        struct rb_root *root = &tracker->res_tree[type];
1287
1288        res_arr = kcalloc(count, sizeof(*res_arr), GFP_KERNEL);
1289        if (!res_arr)
1290                return -ENOMEM;
1291
1292        for (i = 0; i < count; ++i) {
1293                res_arr[i] = alloc_tr(base + i, type, slave, extra);
1294                if (!res_arr[i]) {
1295                        for (--i; i >= 0; --i)
1296                                kfree(res_arr[i]);
1297
1298                        kfree(res_arr);
1299                        return -ENOMEM;
1300                }
1301        }
1302
1303        spin_lock_irq(mlx4_tlock(dev));
1304        for (i = 0; i < count; ++i) {
1305                if (find_res(dev, base + i, type)) {
1306                        err = -EEXIST;
1307                        goto undo;
1308                }
1309                err = res_tracker_insert(root, res_arr[i]);
1310                if (err)
1311                        goto undo;
1312                list_add_tail(&res_arr[i]->list,
1313                              &tracker->slave_list[slave].res_list[type]);
1314        }
1315        spin_unlock_irq(mlx4_tlock(dev));
1316        kfree(res_arr);
1317
1318        return 0;
1319
1320undo:
1321        for (--i; i >= 0; --i) {
1322                rb_erase(&res_arr[i]->node, root);
1323                list_del_init(&res_arr[i]->list);
1324        }
1325
1326        spin_unlock_irq(mlx4_tlock(dev));
1327
1328        for (i = 0; i < count; ++i)
1329                kfree(res_arr[i]);
1330
1331        kfree(res_arr);
1332
1333        return err;
1334}
1335
1336static int remove_qp_ok(struct res_qp *res)
1337{
1338        if (res->com.state == RES_QP_BUSY || atomic_read(&res->ref_count) ||
1339            !list_empty(&res->mcg_list)) {
1340                pr_err("resource tracker: fail to remove qp, state %d, ref_count %d\n",
1341                       res->com.state, atomic_read(&res->ref_count));
1342                return -EBUSY;
1343        } else if (res->com.state != RES_QP_RESERVED) {
1344                return -EPERM;
1345        }
1346
1347        return 0;
1348}
1349
1350static int remove_mtt_ok(struct res_mtt *res, int order)
1351{
1352        if (res->com.state == RES_MTT_BUSY ||
1353            atomic_read(&res->ref_count)) {
1354                pr_devel("%s-%d: state %s, ref_count %d\n",
1355                         __func__, __LINE__,
1356                         mtt_states_str(res->com.state),
1357                         atomic_read(&res->ref_count));
1358                return -EBUSY;
1359        } else if (res->com.state != RES_MTT_ALLOCATED)
1360                return -EPERM;
1361        else if (res->order != order)
1362                return -EINVAL;
1363
1364        return 0;
1365}
1366
1367static int remove_mpt_ok(struct res_mpt *res)
1368{
1369        if (res->com.state == RES_MPT_BUSY)
1370                return -EBUSY;
1371        else if (res->com.state != RES_MPT_RESERVED)
1372                return -EPERM;
1373
1374        return 0;
1375}
1376
1377static int remove_eq_ok(struct res_eq *res)
1378{
1379        if (res->com.state == RES_MPT_BUSY)
1380                return -EBUSY;
1381        else if (res->com.state != RES_MPT_RESERVED)
1382                return -EPERM;
1383
1384        return 0;
1385}
1386
1387static int remove_counter_ok(struct res_counter *res)
1388{
1389        if (res->com.state == RES_COUNTER_BUSY)
1390                return -EBUSY;
1391        else if (res->com.state != RES_COUNTER_ALLOCATED)
1392                return -EPERM;
1393
1394        return 0;
1395}
1396
1397static int remove_xrcdn_ok(struct res_xrcdn *res)
1398{
1399        if (res->com.state == RES_XRCD_BUSY)
1400                return -EBUSY;
1401        else if (res->com.state != RES_XRCD_ALLOCATED)
1402                return -EPERM;
1403
1404        return 0;
1405}
1406
1407static int remove_fs_rule_ok(struct res_fs_rule *res)
1408{
1409        if (res->com.state == RES_FS_RULE_BUSY)
1410                return -EBUSY;
1411        else if (res->com.state != RES_FS_RULE_ALLOCATED)
1412                return -EPERM;
1413
1414        return 0;
1415}
1416
1417static int remove_cq_ok(struct res_cq *res)
1418{
1419        if (res->com.state == RES_CQ_BUSY)
1420                return -EBUSY;
1421        else if (res->com.state != RES_CQ_ALLOCATED)
1422                return -EPERM;
1423
1424        return 0;
1425}
1426
1427static int remove_srq_ok(struct res_srq *res)
1428{
1429        if (res->com.state == RES_SRQ_BUSY)
1430                return -EBUSY;
1431        else if (res->com.state != RES_SRQ_ALLOCATED)
1432                return -EPERM;
1433
1434        return 0;
1435}
1436
1437static int remove_ok(struct res_common *res, enum mlx4_resource type, int extra)
1438{
1439        switch (type) {
1440        case RES_QP:
1441                return remove_qp_ok((struct res_qp *)res);
1442        case RES_CQ:
1443                return remove_cq_ok((struct res_cq *)res);
1444        case RES_SRQ:
1445                return remove_srq_ok((struct res_srq *)res);
1446        case RES_MPT:
1447                return remove_mpt_ok((struct res_mpt *)res);
1448        case RES_MTT:
1449                return remove_mtt_ok((struct res_mtt *)res, extra);
1450        case RES_MAC:
1451                return -EOPNOTSUPP;
1452        case RES_EQ:
1453                return remove_eq_ok((struct res_eq *)res);
1454        case RES_COUNTER:
1455                return remove_counter_ok((struct res_counter *)res);
1456        case RES_XRCD:
1457                return remove_xrcdn_ok((struct res_xrcdn *)res);
1458        case RES_FS_RULE:
1459                return remove_fs_rule_ok((struct res_fs_rule *)res);
1460        default:
1461                return -EINVAL;
1462        }
1463}
1464
1465static int rem_res_range(struct mlx4_dev *dev, int slave, u64 base, int count,
1466                         enum mlx4_resource type, int extra)
1467{
1468        u64 i;
1469        int err;
1470        struct mlx4_priv *priv = mlx4_priv(dev);
1471        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1472        struct res_common *r;
1473
1474        spin_lock_irq(mlx4_tlock(dev));
1475        for (i = base; i < base + count; ++i) {
1476                r = res_tracker_lookup(&tracker->res_tree[type], i);
1477                if (!r) {
1478                        err = -ENOENT;
1479                        goto out;
1480                }
1481                if (r->owner != slave) {
1482                        err = -EPERM;
1483                        goto out;
1484                }
1485                err = remove_ok(r, type, extra);
1486                if (err)
1487                        goto out;
1488        }
1489
1490        for (i = base; i < base + count; ++i) {
1491                r = res_tracker_lookup(&tracker->res_tree[type], i);
1492                rb_erase(&r->node, &tracker->res_tree[type]);
1493                list_del(&r->list);
1494                kfree(r);
1495        }
1496        err = 0;
1497
1498out:
1499        spin_unlock_irq(mlx4_tlock(dev));
1500
1501        return err;
1502}
1503
1504static int qp_res_start_move_to(struct mlx4_dev *dev, int slave, int qpn,
1505                                enum res_qp_states state, struct res_qp **qp,
1506                                int alloc)
1507{
1508        struct mlx4_priv *priv = mlx4_priv(dev);
1509        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1510        struct res_qp *r;
1511        int err = 0;
1512
1513        spin_lock_irq(mlx4_tlock(dev));
1514        r = res_tracker_lookup(&tracker->res_tree[RES_QP], qpn);
1515        if (!r)
1516                err = -ENOENT;
1517        else if (r->com.owner != slave)
1518                err = -EPERM;
1519        else {
1520                switch (state) {
1521                case RES_QP_BUSY:
1522                        mlx4_dbg(dev, "%s: failed RES_QP, 0x%llx\n",
1523                                 __func__, r->com.res_id);
1524                        err = -EBUSY;
1525                        break;
1526
1527                case RES_QP_RESERVED:
1528                        if (r->com.state == RES_QP_MAPPED && !alloc)
1529                                break;
1530
1531                        mlx4_dbg(dev, "failed RES_QP, 0x%llx\n", r->com.res_id);
1532                        err = -EINVAL;
1533                        break;
1534
1535                case RES_QP_MAPPED:
1536                        if ((r->com.state == RES_QP_RESERVED && alloc) ||
1537                            r->com.state == RES_QP_HW)
1538                                break;
1539                        else {
1540                                mlx4_dbg(dev, "failed RES_QP, 0x%llx\n",
1541                                          r->com.res_id);
1542                                err = -EINVAL;
1543                        }
1544
1545                        break;
1546
1547                case RES_QP_HW:
1548                        if (r->com.state != RES_QP_MAPPED)
1549                                err = -EINVAL;
1550                        break;
1551                default:
1552                        err = -EINVAL;
1553                }
1554
1555                if (!err) {
1556                        r->com.from_state = r->com.state;
1557                        r->com.to_state = state;
1558                        r->com.state = RES_QP_BUSY;
1559                        if (qp)
1560                                *qp = r;
1561                }
1562        }
1563
1564        spin_unlock_irq(mlx4_tlock(dev));
1565
1566        return err;
1567}
1568
1569static int mr_res_start_move_to(struct mlx4_dev *dev, int slave, int index,
1570                                enum res_mpt_states state, struct res_mpt **mpt)
1571{
1572        struct mlx4_priv *priv = mlx4_priv(dev);
1573        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1574        struct res_mpt *r;
1575        int err = 0;
1576
1577        spin_lock_irq(mlx4_tlock(dev));
1578        r = res_tracker_lookup(&tracker->res_tree[RES_MPT], index);
1579        if (!r)
1580                err = -ENOENT;
1581        else if (r->com.owner != slave)
1582                err = -EPERM;
1583        else {
1584                switch (state) {
1585                case RES_MPT_BUSY:
1586                        err = -EINVAL;
1587                        break;
1588
1589                case RES_MPT_RESERVED:
1590                        if (r->com.state != RES_MPT_MAPPED)
1591                                err = -EINVAL;
1592                        break;
1593
1594                case RES_MPT_MAPPED:
1595                        if (r->com.state != RES_MPT_RESERVED &&
1596                            r->com.state != RES_MPT_HW)
1597                                err = -EINVAL;
1598                        break;
1599
1600                case RES_MPT_HW:
1601                        if (r->com.state != RES_MPT_MAPPED)
1602                                err = -EINVAL;
1603                        break;
1604                default:
1605                        err = -EINVAL;
1606                }
1607
1608                if (!err) {
1609                        r->com.from_state = r->com.state;
1610                        r->com.to_state = state;
1611                        r->com.state = RES_MPT_BUSY;
1612                        if (mpt)
1613                                *mpt = r;
1614                }
1615        }
1616
1617        spin_unlock_irq(mlx4_tlock(dev));
1618
1619        return err;
1620}
1621
1622static int eq_res_start_move_to(struct mlx4_dev *dev, int slave, int index,
1623                                enum res_eq_states state, struct res_eq **eq)
1624{
1625        struct mlx4_priv *priv = mlx4_priv(dev);
1626        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1627        struct res_eq *r;
1628        int err = 0;
1629
1630        spin_lock_irq(mlx4_tlock(dev));
1631        r = res_tracker_lookup(&tracker->res_tree[RES_EQ], index);
1632        if (!r)
1633                err = -ENOENT;
1634        else if (r->com.owner != slave)
1635                err = -EPERM;
1636        else {
1637                switch (state) {
1638                case RES_EQ_BUSY:
1639                        err = -EINVAL;
1640                        break;
1641
1642                case RES_EQ_RESERVED:
1643                        if (r->com.state != RES_EQ_HW)
1644                                err = -EINVAL;
1645                        break;
1646
1647                case RES_EQ_HW:
1648                        if (r->com.state != RES_EQ_RESERVED)
1649                                err = -EINVAL;
1650                        break;
1651
1652                default:
1653                        err = -EINVAL;
1654                }
1655
1656                if (!err) {
1657                        r->com.from_state = r->com.state;
1658                        r->com.to_state = state;
1659                        r->com.state = RES_EQ_BUSY;
1660                }
1661        }
1662
1663        spin_unlock_irq(mlx4_tlock(dev));
1664
1665        if (!err && eq)
1666                *eq = r;
1667
1668        return err;
1669}
1670
1671static int cq_res_start_move_to(struct mlx4_dev *dev, int slave, int cqn,
1672                                enum res_cq_states state, struct res_cq **cq)
1673{
1674        struct mlx4_priv *priv = mlx4_priv(dev);
1675        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1676        struct res_cq *r;
1677        int err;
1678
1679        spin_lock_irq(mlx4_tlock(dev));
1680        r = res_tracker_lookup(&tracker->res_tree[RES_CQ], cqn);
1681        if (!r) {
1682                err = -ENOENT;
1683        } else if (r->com.owner != slave) {
1684                err = -EPERM;
1685        } else if (state == RES_CQ_ALLOCATED) {
1686                if (r->com.state != RES_CQ_HW)
1687                        err = -EINVAL;
1688                else if (atomic_read(&r->ref_count))
1689                        err = -EBUSY;
1690                else
1691                        err = 0;
1692        } else if (state != RES_CQ_HW || r->com.state != RES_CQ_ALLOCATED) {
1693                err = -EINVAL;
1694        } else {
1695                err = 0;
1696        }
1697
1698        if (!err) {
1699                r->com.from_state = r->com.state;
1700                r->com.to_state = state;
1701                r->com.state = RES_CQ_BUSY;
1702                if (cq)
1703                        *cq = r;
1704        }
1705
1706        spin_unlock_irq(mlx4_tlock(dev));
1707
1708        return err;
1709}
1710
1711static int srq_res_start_move_to(struct mlx4_dev *dev, int slave, int index,
1712                                 enum res_srq_states state, struct res_srq **srq)
1713{
1714        struct mlx4_priv *priv = mlx4_priv(dev);
1715        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1716        struct res_srq *r;
1717        int err = 0;
1718
1719        spin_lock_irq(mlx4_tlock(dev));
1720        r = res_tracker_lookup(&tracker->res_tree[RES_SRQ], index);
1721        if (!r) {
1722                err = -ENOENT;
1723        } else if (r->com.owner != slave) {
1724                err = -EPERM;
1725        } else if (state == RES_SRQ_ALLOCATED) {
1726                if (r->com.state != RES_SRQ_HW)
1727                        err = -EINVAL;
1728                else if (atomic_read(&r->ref_count))
1729                        err = -EBUSY;
1730        } else if (state != RES_SRQ_HW || r->com.state != RES_SRQ_ALLOCATED) {
1731                err = -EINVAL;
1732        }
1733
1734        if (!err) {
1735                r->com.from_state = r->com.state;
1736                r->com.to_state = state;
1737                r->com.state = RES_SRQ_BUSY;
1738                if (srq)
1739                        *srq = r;
1740        }
1741
1742        spin_unlock_irq(mlx4_tlock(dev));
1743
1744        return err;
1745}
1746
1747static void res_abort_move(struct mlx4_dev *dev, int slave,
1748                           enum mlx4_resource type, int id)
1749{
1750        struct mlx4_priv *priv = mlx4_priv(dev);
1751        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1752        struct res_common *r;
1753
1754        spin_lock_irq(mlx4_tlock(dev));
1755        r = res_tracker_lookup(&tracker->res_tree[type], id);
1756        if (r && (r->owner == slave))
1757                r->state = r->from_state;
1758        spin_unlock_irq(mlx4_tlock(dev));
1759}
1760
1761static void res_end_move(struct mlx4_dev *dev, int slave,
1762                         enum mlx4_resource type, int id)
1763{
1764        struct mlx4_priv *priv = mlx4_priv(dev);
1765        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
1766        struct res_common *r;
1767
1768        spin_lock_irq(mlx4_tlock(dev));
1769        r = res_tracker_lookup(&tracker->res_tree[type], id);
1770        if (r && (r->owner == slave))
1771                r->state = r->to_state;
1772        spin_unlock_irq(mlx4_tlock(dev));
1773}
1774
1775static int valid_reserved(struct mlx4_dev *dev, int slave, int qpn)
1776{
1777        return mlx4_is_qp_reserved(dev, qpn) &&
1778                (mlx4_is_master(dev) || mlx4_is_guest_proxy(dev, slave, qpn));
1779}
1780
1781static int fw_reserved(struct mlx4_dev *dev, int qpn)
1782{
1783        return qpn < dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW];
1784}
1785
1786static int qp_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1787                        u64 in_param, u64 *out_param)
1788{
1789        int err;
1790        int count;
1791        int align;
1792        int base;
1793        int qpn;
1794        u8 flags;
1795
1796        switch (op) {
1797        case RES_OP_RESERVE:
1798                count = get_param_l(&in_param) & 0xffffff;
1799                /* Turn off all unsupported QP allocation flags that the
1800                 * slave tries to set.
1801                 */
1802                flags = (get_param_l(&in_param) >> 24) & dev->caps.alloc_res_qp_mask;
1803                align = get_param_h(&in_param);
1804                err = mlx4_grant_resource(dev, slave, RES_QP, count, 0);
1805                if (err)
1806                        return err;
1807
1808                err = __mlx4_qp_reserve_range(dev, count, align, &base, flags);
1809                if (err) {
1810                        mlx4_release_resource(dev, slave, RES_QP, count, 0);
1811                        return err;
1812                }
1813
1814                err = add_res_range(dev, slave, base, count, RES_QP, 0);
1815                if (err) {
1816                        mlx4_release_resource(dev, slave, RES_QP, count, 0);
1817                        __mlx4_qp_release_range(dev, base, count);
1818                        return err;
1819                }
1820                set_param_l(out_param, base);
1821                break;
1822        case RES_OP_MAP_ICM:
1823                qpn = get_param_l(&in_param) & 0x7fffff;
1824                if (valid_reserved(dev, slave, qpn)) {
1825                        err = add_res_range(dev, slave, qpn, 1, RES_QP, 0);
1826                        if (err)
1827                                return err;
1828                }
1829
1830                err = qp_res_start_move_to(dev, slave, qpn, RES_QP_MAPPED,
1831                                           NULL, 1);
1832                if (err)
1833                        return err;
1834
1835                if (!fw_reserved(dev, qpn)) {
1836                        err = __mlx4_qp_alloc_icm(dev, qpn);
1837                        if (err) {
1838                                res_abort_move(dev, slave, RES_QP, qpn);
1839                                return err;
1840                        }
1841                }
1842
1843                res_end_move(dev, slave, RES_QP, qpn);
1844                break;
1845
1846        default:
1847                err = -EINVAL;
1848                break;
1849        }
1850        return err;
1851}
1852
1853static int mtt_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1854                         u64 in_param, u64 *out_param)
1855{
1856        int err = -EINVAL;
1857        int base;
1858        int order;
1859
1860        if (op != RES_OP_RESERVE_AND_MAP)
1861                return err;
1862
1863        order = get_param_l(&in_param);
1864
1865        err = mlx4_grant_resource(dev, slave, RES_MTT, 1 << order, 0);
1866        if (err)
1867                return err;
1868
1869        base = __mlx4_alloc_mtt_range(dev, order);
1870        if (base == -1) {
1871                mlx4_release_resource(dev, slave, RES_MTT, 1 << order, 0);
1872                return -ENOMEM;
1873        }
1874
1875        err = add_res_range(dev, slave, base, 1, RES_MTT, order);
1876        if (err) {
1877                mlx4_release_resource(dev, slave, RES_MTT, 1 << order, 0);
1878                __mlx4_free_mtt_range(dev, base, order);
1879        } else {
1880                set_param_l(out_param, base);
1881        }
1882
1883        return err;
1884}
1885
1886static int mpt_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1887                         u64 in_param, u64 *out_param)
1888{
1889        int err = -EINVAL;
1890        int index;
1891        int id;
1892        struct res_mpt *mpt;
1893
1894        switch (op) {
1895        case RES_OP_RESERVE:
1896                err = mlx4_grant_resource(dev, slave, RES_MPT, 1, 0);
1897                if (err)
1898                        break;
1899
1900                index = __mlx4_mpt_reserve(dev);
1901                if (index == -1) {
1902                        mlx4_release_resource(dev, slave, RES_MPT, 1, 0);
1903                        break;
1904                }
1905                id = index & mpt_mask(dev);
1906
1907                err = add_res_range(dev, slave, id, 1, RES_MPT, index);
1908                if (err) {
1909                        mlx4_release_resource(dev, slave, RES_MPT, 1, 0);
1910                        __mlx4_mpt_release(dev, index);
1911                        break;
1912                }
1913                set_param_l(out_param, index);
1914                break;
1915        case RES_OP_MAP_ICM:
1916                index = get_param_l(&in_param);
1917                id = index & mpt_mask(dev);
1918                err = mr_res_start_move_to(dev, slave, id,
1919                                           RES_MPT_MAPPED, &mpt);
1920                if (err)
1921                        return err;
1922
1923                err = __mlx4_mpt_alloc_icm(dev, mpt->key);
1924                if (err) {
1925                        res_abort_move(dev, slave, RES_MPT, id);
1926                        return err;
1927                }
1928
1929                res_end_move(dev, slave, RES_MPT, id);
1930                break;
1931        }
1932        return err;
1933}
1934
1935static int cq_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1936                        u64 in_param, u64 *out_param)
1937{
1938        int cqn;
1939        int err;
1940
1941        switch (op) {
1942        case RES_OP_RESERVE_AND_MAP:
1943                err = mlx4_grant_resource(dev, slave, RES_CQ, 1, 0);
1944                if (err)
1945                        break;
1946
1947                err = __mlx4_cq_alloc_icm(dev, &cqn);
1948                if (err) {
1949                        mlx4_release_resource(dev, slave, RES_CQ, 1, 0);
1950                        break;
1951                }
1952
1953                err = add_res_range(dev, slave, cqn, 1, RES_CQ, 0);
1954                if (err) {
1955                        mlx4_release_resource(dev, slave, RES_CQ, 1, 0);
1956                        __mlx4_cq_free_icm(dev, cqn);
1957                        break;
1958                }
1959
1960                set_param_l(out_param, cqn);
1961                break;
1962
1963        default:
1964                err = -EINVAL;
1965        }
1966
1967        return err;
1968}
1969
1970static int srq_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
1971                         u64 in_param, u64 *out_param)
1972{
1973        int srqn;
1974        int err;
1975
1976        switch (op) {
1977        case RES_OP_RESERVE_AND_MAP:
1978                err = mlx4_grant_resource(dev, slave, RES_SRQ, 1, 0);
1979                if (err)
1980                        break;
1981
1982                err = __mlx4_srq_alloc_icm(dev, &srqn);
1983                if (err) {
1984                        mlx4_release_resource(dev, slave, RES_SRQ, 1, 0);
1985                        break;
1986                }
1987
1988                err = add_res_range(dev, slave, srqn, 1, RES_SRQ, 0);
1989                if (err) {
1990                        mlx4_release_resource(dev, slave, RES_SRQ, 1, 0);
1991                        __mlx4_srq_free_icm(dev, srqn);
1992                        break;
1993                }
1994
1995                set_param_l(out_param, srqn);
1996                break;
1997
1998        default:
1999                err = -EINVAL;
2000        }
2001
2002        return err;
2003}
2004
2005static int mac_find_smac_ix_in_slave(struct mlx4_dev *dev, int slave, int port,
2006                                     u8 smac_index, u64 *mac)
2007{
2008        struct mlx4_priv *priv = mlx4_priv(dev);
2009        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
2010        struct list_head *mac_list =
2011                &tracker->slave_list[slave].res_list[RES_MAC];
2012        struct mac_res *res, *tmp;
2013
2014        list_for_each_entry_safe(res, tmp, mac_list, list) {
2015                if (res->smac_index == smac_index && res->port == (u8) port) {
2016                        *mac = res->mac;
2017                        return 0;
2018                }
2019        }
2020        return -ENOENT;
2021}
2022
2023static int mac_add_to_slave(struct mlx4_dev *dev, int slave, u64 mac, int port, u8 smac_index)
2024{
2025        struct mlx4_priv *priv = mlx4_priv(dev);
2026        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
2027        struct list_head *mac_list =
2028                &tracker->slave_list[slave].res_list[RES_MAC];
2029        struct mac_res *res, *tmp;
2030
2031        list_for_each_entry_safe(res, tmp, mac_list, list) {
2032                if (res->mac == mac && res->port == (u8) port) {
2033                        /* mac found. update ref count */
2034                        ++res->ref_count;
2035                        return 0;
2036                }
2037        }
2038
2039        if (mlx4_grant_resource(dev, slave, RES_MAC, 1, port))
2040                return -EINVAL;
2041        res = kzalloc(sizeof(*res), GFP_KERNEL);
2042        if (!res) {
2043                mlx4_release_resource(dev, slave, RES_MAC, 1, port);
2044                return -ENOMEM;
2045        }
2046        res->mac = mac;
2047        res->port = (u8) port;
2048        res->smac_index = smac_index;
2049        res->ref_count = 1;
2050        list_add_tail(&res->list,
2051                      &tracker->slave_list[slave].res_list[RES_MAC]);
2052        return 0;
2053}
2054
2055static void mac_del_from_slave(struct mlx4_dev *dev, int slave, u64 mac,
2056                               int port)
2057{
2058        struct mlx4_priv *priv = mlx4_priv(dev);
2059        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
2060        struct list_head *mac_list =
2061                &tracker->slave_list[slave].res_list[RES_MAC];
2062        struct mac_res *res, *tmp;
2063
2064        list_for_each_entry_safe(res, tmp, mac_list, list) {
2065                if (res->mac == mac && res->port == (u8) port) {
2066                        if (!--res->ref_count) {
2067                                list_del(&res->list);
2068                                mlx4_release_resource(dev, slave, RES_MAC, 1, port);
2069                                kfree(res);
2070                        }
2071                        break;
2072                }
2073        }
2074}
2075
2076static void rem_slave_macs(struct mlx4_dev *dev, int slave)
2077{
2078        struct mlx4_priv *priv = mlx4_priv(dev);
2079        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
2080        struct list_head *mac_list =
2081                &tracker->slave_list[slave].res_list[RES_MAC];
2082        struct mac_res *res, *tmp;
2083        int i;
2084
2085        list_for_each_entry_safe(res, tmp, mac_list, list) {
2086                list_del(&res->list);
2087                /* dereference the mac the num times the slave referenced it */
2088                for (i = 0; i < res->ref_count; i++)
2089                        __mlx4_unregister_mac(dev, res->port, res->mac);
2090                mlx4_release_resource(dev, slave, RES_MAC, 1, res->port);
2091                kfree(res);
2092        }
2093}
2094
2095static int mac_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
2096                         u64 in_param, u64 *out_param, int in_port)
2097{
2098        int err = -EINVAL;
2099        int port;
2100        u64 mac;
2101        u8 smac_index;
2102
2103        if (op != RES_OP_RESERVE_AND_MAP)
2104                return err;
2105
2106        port = !in_port ? get_param_l(out_param) : in_port;
2107        port = mlx4_slave_convert_port(
2108                        dev, slave, port);
2109
2110        if (port < 0)
2111                return -EINVAL;
2112        mac = in_param;
2113
2114        err = __mlx4_register_mac(dev, port, mac);
2115        if (err >= 0) {
2116                smac_index = err;
2117                set_param_l(out_param, err);
2118                err = 0;
2119        }
2120
2121        if (!err) {
2122                err = mac_add_to_slave(dev, slave, mac, port, smac_index);
2123                if (err)
2124                        __mlx4_unregister_mac(dev, port, mac);
2125        }
2126        return err;
2127}
2128
2129static int vlan_add_to_slave(struct mlx4_dev *dev, int slave, u16 vlan,
2130                             int port, int vlan_index)
2131{
2132        struct mlx4_priv *priv = mlx4_priv(dev);
2133        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
2134        struct list_head *vlan_list =
2135                &tracker->slave_list[slave].res_list[RES_VLAN];
2136        struct vlan_res *res, *tmp;
2137
2138        list_for_each_entry_safe(res, tmp, vlan_list, list) {
2139                if (res->vlan == vlan && res->port == (u8) port) {
2140                        /* vlan found. update ref count */
2141                        ++res->ref_count;
2142                        return 0;
2143                }
2144        }
2145
2146        if (mlx4_grant_resource(dev, slave, RES_VLAN, 1, port))
2147                return -EINVAL;
2148        res = kzalloc(sizeof(*res), GFP_KERNEL);
2149        if (!res) {
2150                mlx4_release_resource(dev, slave, RES_VLAN, 1, port);
2151                return -ENOMEM;
2152        }
2153        res->vlan = vlan;
2154        res->port = (u8) port;
2155        res->vlan_index = vlan_index;
2156        res->ref_count = 1;
2157        list_add_tail(&res->list,
2158                      &tracker->slave_list[slave].res_list[RES_VLAN]);
2159        return 0;
2160}
2161
2162
2163static void vlan_del_from_slave(struct mlx4_dev *dev, int slave, u16 vlan,
2164                                int port)
2165{
2166        struct mlx4_priv *priv = mlx4_priv(dev);
2167        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
2168        struct list_head *vlan_list =
2169                &tracker->slave_list[slave].res_list[RES_VLAN];
2170        struct vlan_res *res, *tmp;
2171
2172        list_for_each_entry_safe(res, tmp, vlan_list, list) {
2173                if (res->vlan == vlan && res->port == (u8) port) {
2174                        if (!--res->ref_count) {
2175                                list_del(&res->list);
2176                                mlx4_release_resource(dev, slave, RES_VLAN,
2177                                                      1, port);
2178                                kfree(res);
2179                        }
2180                        break;
2181                }
2182        }
2183}
2184
2185static void rem_slave_vlans(struct mlx4_dev *dev, int slave)
2186{
2187        struct mlx4_priv *priv = mlx4_priv(dev);
2188        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
2189        struct list_head *vlan_list =
2190                &tracker->slave_list[slave].res_list[RES_VLAN];
2191        struct vlan_res *res, *tmp;
2192        int i;
2193
2194        list_for_each_entry_safe(res, tmp, vlan_list, list) {
2195                list_del(&res->list);
2196                /* dereference the vlan the num times the slave referenced it */
2197                for (i = 0; i < res->ref_count; i++)
2198                        __mlx4_unregister_vlan(dev, res->port, res->vlan);
2199                mlx4_release_resource(dev, slave, RES_VLAN, 1, res->port);
2200                kfree(res);
2201        }
2202}
2203
2204static int vlan_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
2205                          u64 in_param, u64 *out_param, int in_port)
2206{
2207        struct mlx4_priv *priv = mlx4_priv(dev);
2208        struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state;
2209        int err;
2210        u16 vlan;
2211        int vlan_index;
2212        int port;
2213
2214        port = !in_port ? get_param_l(out_param) : in_port;
2215
2216        if (!port || op != RES_OP_RESERVE_AND_MAP)
2217                return -EINVAL;
2218
2219        port = mlx4_slave_convert_port(
2220                        dev, slave, port);
2221
2222        if (port < 0)
2223                return -EINVAL;
2224        /* upstream kernels had NOP for reg/unreg vlan. Continue this. */
2225        if (!in_port && port > 0 && port <= dev->caps.num_ports) {
2226                slave_state[slave].old_vlan_api = true;
2227                return 0;
2228        }
2229
2230        vlan = (u16) in_param;
2231
2232        err = __mlx4_register_vlan(dev, port, vlan, &vlan_index);
2233        if (!err) {
2234                set_param_l(out_param, (u32) vlan_index);
2235                err = vlan_add_to_slave(dev, slave, vlan, port, vlan_index);
2236                if (err)
2237                        __mlx4_unregister_vlan(dev, port, vlan);
2238        }
2239        return err;
2240}
2241
2242static int counter_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
2243                             u64 in_param, u64 *out_param, int port)
2244{
2245        u32 index;
2246        int err;
2247
2248        if (op != RES_OP_RESERVE)
2249                return -EINVAL;
2250
2251        err = mlx4_grant_resource(dev, slave, RES_COUNTER, 1, 0);
2252        if (err)
2253                return err;
2254
2255        err = __mlx4_counter_alloc(dev, &index);
2256        if (err) {
2257                mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
2258                return err;
2259        }
2260
2261        err = add_res_range(dev, slave, index, 1, RES_COUNTER, port);
2262        if (err) {
2263                __mlx4_counter_free(dev, index);
2264                mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
2265        } else {
2266                set_param_l(out_param, index);
2267        }
2268
2269        return err;
2270}
2271
2272static int xrcdn_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
2273                           u64 in_param, u64 *out_param)
2274{
2275        u32 xrcdn;
2276        int err;
2277
2278        if (op != RES_OP_RESERVE)
2279                return -EINVAL;
2280
2281        err = __mlx4_xrcd_alloc(dev, &xrcdn);
2282        if (err)
2283                return err;
2284
2285        err = add_res_range(dev, slave, xrcdn, 1, RES_XRCD, 0);
2286        if (err)
2287                __mlx4_xrcd_free(dev, xrcdn);
2288        else
2289                set_param_l(out_param, xrcdn);
2290
2291        return err;
2292}
2293
2294int mlx4_ALLOC_RES_wrapper(struct mlx4_dev *dev, int slave,
2295                           struct mlx4_vhcr *vhcr,
2296                           struct mlx4_cmd_mailbox *inbox,
2297                           struct mlx4_cmd_mailbox *outbox,
2298                           struct mlx4_cmd_info *cmd)
2299{
2300        int err;
2301        int alop = vhcr->op_modifier;
2302
2303        switch (vhcr->in_modifier & 0xFF) {
2304        case RES_QP:
2305                err = qp_alloc_res(dev, slave, vhcr->op_modifier, alop,
2306                                   vhcr->in_param, &vhcr->out_param);
2307                break;
2308
2309        case RES_MTT:
2310                err = mtt_alloc_res(dev, slave, vhcr->op_modifier, alop,
2311                                    vhcr->in_param, &vhcr->out_param);
2312                break;
2313
2314        case RES_MPT:
2315                err = mpt_alloc_res(dev, slave, vhcr->op_modifier, alop,
2316                                    vhcr->in_param, &vhcr->out_param);
2317                break;
2318
2319        case RES_CQ:
2320                err = cq_alloc_res(dev, slave, vhcr->op_modifier, alop,
2321                                   vhcr->in_param, &vhcr->out_param);
2322                break;
2323
2324        case RES_SRQ:
2325                err = srq_alloc_res(dev, slave, vhcr->op_modifier, alop,
2326                                    vhcr->in_param, &vhcr->out_param);
2327                break;
2328
2329        case RES_MAC:
2330                err = mac_alloc_res(dev, slave, vhcr->op_modifier, alop,
2331                                    vhcr->in_param, &vhcr->out_param,
2332                                    (vhcr->in_modifier >> 8) & 0xFF);
2333                break;
2334
2335        case RES_VLAN:
2336                err = vlan_alloc_res(dev, slave, vhcr->op_modifier, alop,
2337                                     vhcr->in_param, &vhcr->out_param,
2338                                     (vhcr->in_modifier >> 8) & 0xFF);
2339                break;
2340
2341        case RES_COUNTER:
2342                err = counter_alloc_res(dev, slave, vhcr->op_modifier, alop,
2343                                        vhcr->in_param, &vhcr->out_param, 0);
2344                break;
2345
2346        case RES_XRCD:
2347                err = xrcdn_alloc_res(dev, slave, vhcr->op_modifier, alop,
2348                                      vhcr->in_param, &vhcr->out_param);
2349                break;
2350
2351        default:
2352                err = -EINVAL;
2353                break;
2354        }
2355
2356        return err;
2357}
2358
2359static int qp_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
2360                       u64 in_param)
2361{
2362        int err;
2363        int count;
2364        int base;
2365        int qpn;
2366
2367        switch (op) {
2368        case RES_OP_RESERVE:
2369                base = get_param_l(&in_param) & 0x7fffff;
2370                count = get_param_h(&in_param);
2371                err = rem_res_range(dev, slave, base, count, RES_QP, 0);
2372                if (err)
2373                        break;
2374                mlx4_release_resource(dev, slave, RES_QP, count, 0);
2375                __mlx4_qp_release_range(dev, base, count);
2376                break;
2377        case RES_OP_MAP_ICM:
2378                qpn = get_param_l(&in_param) & 0x7fffff;
2379                err = qp_res_start_move_to(dev, slave, qpn, RES_QP_RESERVED,
2380                                           NULL, 0);
2381                if (err)
2382                        return err;
2383
2384                if (!fw_reserved(dev, qpn))
2385                        __mlx4_qp_free_icm(dev, qpn);
2386
2387                res_end_move(dev, slave, RES_QP, qpn);
2388
2389                if (valid_reserved(dev, slave, qpn))
2390                        err = rem_res_range(dev, slave, qpn, 1, RES_QP, 0);
2391                break;
2392        default:
2393                err = -EINVAL;
2394                break;
2395        }
2396        return err;
2397}
2398
2399static int mtt_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
2400                        u64 in_param, u64 *out_param)
2401{
2402        int err = -EINVAL;
2403        int base;
2404        int order;
2405
2406        if (op != RES_OP_RESERVE_AND_MAP)
2407                return err;
2408
2409        base = get_param_l(&in_param);
2410        order = get_param_h(&in_param);
2411        err = rem_res_range(dev, slave, base, 1, RES_MTT, order);
2412        if (!err) {
2413                mlx4_release_resource(dev, slave, RES_MTT, 1 << order, 0);
2414                __mlx4_free_mtt_range(dev, base, order);
2415        }
2416        return err;
2417}
2418
2419static int mpt_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
2420                        u64 in_param)
2421{
2422        int err = -EINVAL;
2423        int index;
2424        int id;
2425        struct res_mpt *mpt;
2426
2427        switch (op) {
2428        case RES_OP_RESERVE:
2429                index = get_param_l(&in_param);
2430                id = index & mpt_mask(dev);
2431                err = get_res(dev, slave, id, RES_MPT, &mpt);
2432                if (err)
2433                        break;
2434                index = mpt->key;
2435                put_res(dev, slave, id, RES_MPT);
2436
2437                err = rem_res_range(dev, slave, id, 1, RES_MPT, 0);
2438                if (err)
2439                        break;
2440                mlx4_release_resource(dev, slave, RES_MPT, 1, 0);
2441                __mlx4_mpt_release(dev, index);
2442                break;
2443        case RES_OP_MAP_ICM:
2444                index = get_param_l(&in_param);
2445                id = index & mpt_mask(dev);
2446                err = mr_res_start_move_to(dev, slave, id,
2447                                           RES_MPT_RESERVED, &mpt);
2448                if (err)
2449                        return err;
2450
2451                __mlx4_mpt_free_icm(dev, mpt->key);
2452                res_end_move(dev, slave, RES_MPT, id);
2453                break;
2454        default:
2455                err = -EINVAL;
2456                break;
2457        }
2458        return err;
2459}
2460
2461static int cq_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
2462                       u64 in_param, u64 *out_param)
2463{
2464        int cqn;
2465        int err;
2466
2467        switch (op) {
2468        case RES_OP_RESERVE_AND_MAP:
2469                cqn = get_param_l(&in_param);
2470                err = rem_res_range(dev, slave, cqn, 1, RES_CQ, 0);
2471                if (err)
2472                        break;
2473
2474                mlx4_release_resource(dev, slave, RES_CQ, 1, 0);
2475                __mlx4_cq_free_icm(dev, cqn);
2476                break;
2477
2478        default:
2479                err = -EINVAL;
2480                break;
2481        }
2482
2483        return err;
2484}
2485
2486static int srq_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
2487                        u64 in_param, u64 *out_param)
2488{
2489        int srqn;
2490        int err;
2491
2492        switch (op) {
2493        case RES_OP_RESERVE_AND_MAP:
2494                srqn = get_param_l(&in_param);
2495                err = rem_res_range(dev, slave, srqn, 1, RES_SRQ, 0);
2496                if (err)
2497                        break;
2498
2499                mlx4_release_resource(dev, slave, RES_SRQ, 1, 0);
2500                __mlx4_srq_free_icm(dev, srqn);
2501                break;
2502
2503        default:
2504                err = -EINVAL;
2505                break;
2506        }
2507
2508        return err;
2509}
2510
2511static int mac_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
2512                            u64 in_param, u64 *out_param, int in_port)
2513{
2514        int port;
2515        int err = 0;
2516
2517        switch (op) {
2518        case RES_OP_RESERVE_AND_MAP:
2519                port = !in_port ? get_param_l(out_param) : in_port;
2520                port = mlx4_slave_convert_port(
2521                                dev, slave, port);
2522
2523                if (port < 0)
2524                        return -EINVAL;
2525                mac_del_from_slave(dev, slave, in_param, port);
2526                __mlx4_unregister_mac(dev, port, in_param);
2527                break;
2528        default:
2529                err = -EINVAL;
2530                break;
2531        }
2532
2533        return err;
2534
2535}
2536
2537static int vlan_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
2538                            u64 in_param, u64 *out_param, int port)
2539{
2540        struct mlx4_priv *priv = mlx4_priv(dev);
2541        struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state;
2542        int err = 0;
2543
2544        port = mlx4_slave_convert_port(
2545                        dev, slave, port);
2546
2547        if (port < 0)
2548                return -EINVAL;
2549        switch (op) {
2550        case RES_OP_RESERVE_AND_MAP:
2551                if (slave_state[slave].old_vlan_api)
2552                        return 0;
2553                if (!port)
2554                        return -EINVAL;
2555                vlan_del_from_slave(dev, slave, in_param, port);
2556                __mlx4_unregister_vlan(dev, port, in_param);
2557                break;
2558        default:
2559                err = -EINVAL;
2560                break;
2561        }
2562
2563        return err;
2564}
2565
2566static int counter_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
2567                            u64 in_param, u64 *out_param)
2568{
2569        int index;
2570        int err;
2571
2572        if (op != RES_OP_RESERVE)
2573                return -EINVAL;
2574
2575        index = get_param_l(&in_param);
2576        if (index == MLX4_SINK_COUNTER_INDEX(dev))
2577                return 0;
2578
2579        err = rem_res_range(dev, slave, index, 1, RES_COUNTER, 0);
2580        if (err)
2581                return err;
2582
2583        __mlx4_counter_free(dev, index);
2584        mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
2585
2586        return err;
2587}
2588
2589static int xrcdn_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
2590                          u64 in_param, u64 *out_param)
2591{
2592        int xrcdn;
2593        int err;
2594
2595        if (op != RES_OP_RESERVE)
2596                return -EINVAL;
2597
2598        xrcdn = get_param_l(&in_param);
2599        err = rem_res_range(dev, slave, xrcdn, 1, RES_XRCD, 0);
2600        if (err)
2601                return err;
2602
2603        __mlx4_xrcd_free(dev, xrcdn);
2604
2605        return err;
2606}
2607
2608int mlx4_FREE_RES_wrapper(struct mlx4_dev *dev, int slave,
2609                          struct mlx4_vhcr *vhcr,
2610                          struct mlx4_cmd_mailbox *inbox,
2611                          struct mlx4_cmd_mailbox *outbox,
2612                          struct mlx4_cmd_info *cmd)
2613{
2614        int err = -EINVAL;
2615        int alop = vhcr->op_modifier;
2616
2617        switch (vhcr->in_modifier & 0xFF) {
2618        case RES_QP:
2619                err = qp_free_res(dev, slave, vhcr->op_modifier, alop,
2620                                  vhcr->in_param);
2621                break;
2622
2623        case RES_MTT:
2624                err = mtt_free_res(dev, slave, vhcr->op_modifier, alop,
2625                                   vhcr->in_param, &vhcr->out_param);
2626                break;
2627
2628        case RES_MPT:
2629                err = mpt_free_res(dev, slave, vhcr->op_modifier, alop,
2630                                   vhcr->in_param);
2631                break;
2632
2633        case RES_CQ:
2634                err = cq_free_res(dev, slave, vhcr->op_modifier, alop,
2635                                  vhcr->in_param, &vhcr->out_param);
2636                break;
2637
2638        case RES_SRQ:
2639                err = srq_free_res(dev, slave, vhcr->op_modifier, alop,
2640                                   vhcr->in_param, &vhcr->out_param);
2641                break;
2642
2643        case RES_MAC:
2644                err = mac_free_res(dev, slave, vhcr->op_modifier, alop,
2645                                   vhcr->in_param, &vhcr->out_param,
2646                                   (vhcr->in_modifier >> 8) & 0xFF);
2647                break;
2648
2649        case RES_VLAN:
2650                err = vlan_free_res(dev, slave, vhcr->op_modifier, alop,
2651                                    vhcr->in_param, &vhcr->out_param,
2652                                    (vhcr->in_modifier >> 8) & 0xFF);
2653                break;
2654
2655        case RES_COUNTER:
2656                err = counter_free_res(dev, slave, vhcr->op_modifier, alop,
2657                                       vhcr->in_param, &vhcr->out_param);
2658                break;
2659
2660        case RES_XRCD:
2661                err = xrcdn_free_res(dev, slave, vhcr->op_modifier, alop,
2662                                     vhcr->in_param, &vhcr->out_param);
2663                break;
2664
2665        default:
2666                break;
2667        }
2668        return err;
2669}
2670
2671/* ugly but other choices are uglier */
2672static int mr_phys_mpt(struct mlx4_mpt_entry *mpt)
2673{
2674        return (be32_to_cpu(mpt->flags) >> 9) & 1;
2675}
2676
2677static int mr_get_mtt_addr(struct mlx4_mpt_entry *mpt)
2678{
2679        return (int)be64_to_cpu(mpt->mtt_addr) & 0xfffffff8;
2680}
2681
2682static int mr_get_mtt_size(struct mlx4_mpt_entry *mpt)
2683{
2684        return be32_to_cpu(mpt->mtt_sz);
2685}
2686
2687static u32 mr_get_pd(struct mlx4_mpt_entry *mpt)
2688{
2689        return be32_to_cpu(mpt->pd_flags) & 0x00ffffff;
2690}
2691
2692static int mr_is_fmr(struct mlx4_mpt_entry *mpt)
2693{
2694        return be32_to_cpu(mpt->pd_flags) & MLX4_MPT_PD_FLAG_FAST_REG;
2695}
2696
2697static int mr_is_bind_enabled(struct mlx4_mpt_entry *mpt)
2698{
2699        return be32_to_cpu(mpt->flags) & MLX4_MPT_FLAG_BIND_ENABLE;
2700}
2701
2702static int mr_is_region(struct mlx4_mpt_entry *mpt)
2703{
2704        return be32_to_cpu(mpt->flags) & MLX4_MPT_FLAG_REGION;
2705}
2706
2707static int qp_get_mtt_addr(struct mlx4_qp_context *qpc)
2708{
2709        return be32_to_cpu(qpc->mtt_base_addr_l) & 0xfffffff8;
2710}
2711
2712static int srq_get_mtt_addr(struct mlx4_srq_context *srqc)
2713{
2714        return be32_to_cpu(srqc->mtt_base_addr_l) & 0xfffffff8;
2715}
2716
2717static int qp_get_mtt_size(struct mlx4_qp_context *qpc)
2718{
2719        int page_shift = (qpc->log_page_size & 0x3f) + 12;
2720        int log_sq_size = (qpc->sq_size_stride >> 3) & 0xf;
2721        int log_sq_sride = qpc->sq_size_stride & 7;
2722        int log_rq_size = (qpc->rq_size_stride >> 3) & 0xf;
2723        int log_rq_stride = qpc->rq_size_stride & 7;
2724        int srq = (be32_to_cpu(qpc->srqn) >> 24) & 1;
2725        int rss = (be32_to_cpu(qpc->flags) >> 13) & 1;
2726        u32 ts = (be32_to_cpu(qpc->flags) >> 16) & 0xff;
2727        int xrc = (ts == MLX4_QP_ST_XRC) ? 1 : 0;
2728        int sq_size;
2729        int rq_size;
2730        int total_pages;
2731        int total_mem;
2732        int page_offset = (be32_to_cpu(qpc->params2) >> 6) & 0x3f;
2733        int tot;
2734
2735        sq_size = 1 << (log_sq_size + log_sq_sride + 4);
2736        rq_size = (srq|rss|xrc) ? 0 : (1 << (log_rq_size + log_rq_stride + 4));
2737        total_mem = sq_size + rq_size;
2738        tot = (total_mem + (page_offset << 6)) >> page_shift;
2739        total_pages = !tot ? 1 : roundup_pow_of_two(tot);
2740
2741        return total_pages;
2742}
2743
2744static int check_mtt_range(struct mlx4_dev *dev, int slave, int start,
2745                           int size, struct res_mtt *mtt)
2746{
2747        int res_start = mtt->com.res_id;
2748        int res_size = (1 << mtt->order);
2749
2750        if (start < res_start || start + size > res_start + res_size)
2751                return -EPERM;
2752        return 0;
2753}
2754
2755int mlx4_SW2HW_MPT_wrapper(struct mlx4_dev *dev, int slave,
2756                           struct mlx4_vhcr *vhcr,
2757                           struct mlx4_cmd_mailbox *inbox,
2758                           struct mlx4_cmd_mailbox *outbox,
2759                           struct mlx4_cmd_info *cmd)
2760{
2761        int err;
2762        int index = vhcr->in_modifier;
2763        struct res_mtt *mtt;
2764        struct res_mpt *mpt = NULL;
2765        int mtt_base = mr_get_mtt_addr(inbox->buf) / dev->caps.mtt_entry_sz;
2766        int phys;
2767        int id;
2768        u32 pd;
2769        int pd_slave;
2770
2771        id = index & mpt_mask(dev);
2772        err = mr_res_start_move_to(dev, slave, id, RES_MPT_HW, &mpt);
2773        if (err)
2774                return err;
2775
2776        /* Disable memory windows for VFs. */
2777        if (!mr_is_region(inbox->buf)) {
2778                err = -EPERM;
2779                goto ex_abort;
2780        }
2781
2782        /* Make sure that the PD bits related to the slave id are zeros. */
2783        pd = mr_get_pd(inbox->buf);
2784        pd_slave = (pd >> 17) & 0x7f;
2785        if (pd_slave != 0 && --pd_slave != slave) {
2786                err = -EPERM;
2787                goto ex_abort;
2788        }
2789
2790        if (mr_is_fmr(inbox->buf)) {
2791                /* FMR and Bind Enable are forbidden in slave devices. */
2792                if (mr_is_bind_enabled(inbox->buf)) {
2793                        err = -EPERM;
2794                        goto ex_abort;
2795                }
2796                /* FMR and Memory Windows are also forbidden. */
2797                if (!mr_is_region(inbox->buf)) {
2798                        err = -EPERM;
2799                        goto ex_abort;
2800                }
2801        }
2802
2803        phys = mr_phys_mpt(inbox->buf);
2804        if (!phys) {
2805                err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
2806                if (err)
2807                        goto ex_abort;
2808
2809                err = check_mtt_range(dev, slave, mtt_base,
2810                                      mr_get_mtt_size(inbox->buf), mtt);
2811                if (err)
2812                        goto ex_put;
2813
2814                mpt->mtt = mtt;
2815        }
2816
2817        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2818        if (err)
2819                goto ex_put;
2820
2821        if (!phys) {
2822                atomic_inc(&mtt->ref_count);
2823                put_res(dev, slave, mtt->com.res_id, RES_MTT);
2824        }
2825
2826        res_end_move(dev, slave, RES_MPT, id);
2827        return 0;
2828
2829ex_put:
2830        if (!phys)
2831                put_res(dev, slave, mtt->com.res_id, RES_MTT);
2832ex_abort:
2833        res_abort_move(dev, slave, RES_MPT, id);
2834
2835        return err;
2836}
2837
2838int mlx4_HW2SW_MPT_wrapper(struct mlx4_dev *dev, int slave,
2839                           struct mlx4_vhcr *vhcr,
2840                           struct mlx4_cmd_mailbox *inbox,
2841                           struct mlx4_cmd_mailbox *outbox,
2842                           struct mlx4_cmd_info *cmd)
2843{
2844        int err;
2845        int index = vhcr->in_modifier;
2846        struct res_mpt *mpt;
2847        int id;
2848
2849        id = index & mpt_mask(dev);
2850        err = mr_res_start_move_to(dev, slave, id, RES_MPT_MAPPED, &mpt);
2851        if (err)
2852                return err;
2853
2854        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2855        if (err)
2856                goto ex_abort;
2857
2858        if (mpt->mtt)
2859                atomic_dec(&mpt->mtt->ref_count);
2860
2861        res_end_move(dev, slave, RES_MPT, id);
2862        return 0;
2863
2864ex_abort:
2865        res_abort_move(dev, slave, RES_MPT, id);
2866
2867        return err;
2868}
2869
2870int mlx4_QUERY_MPT_wrapper(struct mlx4_dev *dev, int slave,
2871                           struct mlx4_vhcr *vhcr,
2872                           struct mlx4_cmd_mailbox *inbox,
2873                           struct mlx4_cmd_mailbox *outbox,
2874                           struct mlx4_cmd_info *cmd)
2875{
2876        int err;
2877        int index = vhcr->in_modifier;
2878        struct res_mpt *mpt;
2879        int id;
2880
2881        id = index & mpt_mask(dev);
2882        err = get_res(dev, slave, id, RES_MPT, &mpt);
2883        if (err)
2884                return err;
2885
2886        if (mpt->com.from_state == RES_MPT_MAPPED) {
2887                /* In order to allow rereg in SRIOV, we need to alter the MPT entry. To do
2888                 * that, the VF must read the MPT. But since the MPT entry memory is not
2889                 * in the VF's virtual memory space, it must use QUERY_MPT to obtain the
2890                 * entry contents. To guarantee that the MPT cannot be changed, the driver
2891                 * must perform HW2SW_MPT before this query and return the MPT entry to HW
2892                 * ownership fofollowing the change. The change here allows the VF to
2893                 * perform QUERY_MPT also when the entry is in SW ownership.
2894                 */
2895                struct mlx4_mpt_entry *mpt_entry = mlx4_table_find(
2896                                        &mlx4_priv(dev)->mr_table.dmpt_table,
2897                                        mpt->key, NULL);
2898
2899                if (NULL == mpt_entry || NULL == outbox->buf) {
2900                        err = -EINVAL;
2901                        goto out;
2902                }
2903
2904                memcpy(outbox->buf, mpt_entry, sizeof(*mpt_entry));
2905
2906                err = 0;
2907        } else if (mpt->com.from_state == RES_MPT_HW) {
2908                err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
2909        } else {
2910                err = -EBUSY;
2911                goto out;
2912        }
2913
2914
2915out:
2916        put_res(dev, slave, id, RES_MPT);
2917        return err;
2918}
2919
2920static int qp_get_rcqn(struct mlx4_qp_context *qpc)
2921{
2922        return be32_to_cpu(qpc->cqn_recv) & 0xffffff;
2923}
2924
2925static int qp_get_scqn(struct mlx4_qp_context *qpc)
2926{
2927        return be32_to_cpu(qpc->cqn_send) & 0xffffff;
2928}
2929
2930static u32 qp_get_srqn(struct mlx4_qp_context *qpc)
2931{
2932        return be32_to_cpu(qpc->srqn) & 0x1ffffff;
2933}
2934
2935static void adjust_proxy_tun_qkey(struct mlx4_dev *dev, struct mlx4_vhcr *vhcr,
2936                                  struct mlx4_qp_context *context)
2937{
2938        u32 qpn = vhcr->in_modifier & 0xffffff;
2939        u32 qkey = 0;
2940
2941        if (mlx4_get_parav_qkey(dev, qpn, &qkey))
2942                return;
2943
2944        /* adjust qkey in qp context */
2945        context->qkey = cpu_to_be32(qkey);
2946}
2947
2948static int adjust_qp_sched_queue(struct mlx4_dev *dev, int slave,
2949                                 struct mlx4_qp_context *qpc,
2950                                 struct mlx4_cmd_mailbox *inbox);
2951
2952int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
2953                             struct mlx4_vhcr *vhcr,
2954                             struct mlx4_cmd_mailbox *inbox,
2955                             struct mlx4_cmd_mailbox *outbox,
2956                             struct mlx4_cmd_info *cmd)
2957{
2958        int err;
2959        int qpn = vhcr->in_modifier & 0x7fffff;
2960        struct res_mtt *mtt;
2961        struct res_qp *qp;
2962        struct mlx4_qp_context *qpc = inbox->buf + 8;
2963        int mtt_base = qp_get_mtt_addr(qpc) / dev->caps.mtt_entry_sz;
2964        int mtt_size = qp_get_mtt_size(qpc);
2965        struct res_cq *rcq;
2966        struct res_cq *scq;
2967        int rcqn = qp_get_rcqn(qpc);
2968        int scqn = qp_get_scqn(qpc);
2969        u32 srqn = qp_get_srqn(qpc) & 0xffffff;
2970        int use_srq = (qp_get_srqn(qpc) >> 24) & 1;
2971        struct res_srq *srq;
2972        int local_qpn = vhcr->in_modifier & 0xffffff;
2973
2974        err = adjust_qp_sched_queue(dev, slave, qpc, inbox);
2975        if (err)
2976                return err;
2977
2978        err = qp_res_start_move_to(dev, slave, qpn, RES_QP_HW, &qp, 0);
2979        if (err)
2980                return err;
2981        qp->local_qpn = local_qpn;
2982        qp->sched_queue = 0;
2983        qp->param3 = 0;
2984        qp->vlan_control = 0;
2985        qp->fvl_rx = 0;
2986        qp->pri_path_fl = 0;
2987        qp->vlan_index = 0;
2988        qp->feup = 0;
2989        qp->qpc_flags = be32_to_cpu(qpc->flags);
2990
2991        err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
2992        if (err)
2993                goto ex_abort;
2994
2995        err = check_mtt_range(dev, slave, mtt_base, mtt_size, mtt);
2996        if (err)
2997                goto ex_put_mtt;
2998
2999        err = get_res(dev, slave, rcqn, RES_CQ, &rcq);
3000        if (err)
3001                goto ex_put_mtt;
3002
3003        if (scqn != rcqn) {
3004                err = get_res(dev, slave, scqn, RES_CQ, &scq);
3005                if (err)
3006                        goto ex_put_rcq;
3007        } else
3008                scq = rcq;
3009
3010        if (use_srq) {
3011                err = get_res(dev, slave, srqn, RES_SRQ, &srq);
3012                if (err)
3013                        goto ex_put_scq;
3014        }
3015
3016        adjust_proxy_tun_qkey(dev, vhcr, qpc);
3017        update_pkey_index(dev, slave, inbox);
3018        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3019        if (err)
3020                goto ex_put_srq;
3021        atomic_inc(&mtt->ref_count);
3022        qp->mtt = mtt;
3023        atomic_inc(&rcq->ref_count);
3024        qp->rcq = rcq;
3025        atomic_inc(&scq->ref_count);
3026        qp->scq = scq;
3027
3028        if (scqn != rcqn)
3029                put_res(dev, slave, scqn, RES_CQ);
3030
3031        if (use_srq) {
3032                atomic_inc(&srq->ref_count);
3033                put_res(dev, slave, srqn, RES_SRQ);
3034                qp->srq = srq;
3035        }
3036
3037        /* Save param3 for dynamic changes from VST back to VGT */
3038        qp->param3 = qpc->param3;
3039        put_res(dev, slave, rcqn, RES_CQ);
3040        put_res(dev, slave, mtt_base, RES_MTT);
3041        res_end_move(dev, slave, RES_QP, qpn);
3042
3043        return 0;
3044
3045ex_put_srq:
3046        if (use_srq)
3047                put_res(dev, slave, srqn, RES_SRQ);
3048ex_put_scq:
3049        if (scqn != rcqn)
3050                put_res(dev, slave, scqn, RES_CQ);
3051ex_put_rcq:
3052        put_res(dev, slave, rcqn, RES_CQ);
3053ex_put_mtt:
3054        put_res(dev, slave, mtt_base, RES_MTT);
3055ex_abort:
3056        res_abort_move(dev, slave, RES_QP, qpn);
3057
3058        return err;
3059}
3060
3061static int eq_get_mtt_addr(struct mlx4_eq_context *eqc)
3062{
3063        return be32_to_cpu(eqc->mtt_base_addr_l) & 0xfffffff8;
3064}
3065
3066static int eq_get_mtt_size(struct mlx4_eq_context *eqc)
3067{
3068        int log_eq_size = eqc->log_eq_size & 0x1f;
3069        int page_shift = (eqc->log_page_size & 0x3f) + 12;
3070
3071        if (log_eq_size + 5 < page_shift)
3072                return 1;
3073
3074        return 1 << (log_eq_size + 5 - page_shift);
3075}
3076
3077static int cq_get_mtt_addr(struct mlx4_cq_context *cqc)
3078{
3079        return be32_to_cpu(cqc->mtt_base_addr_l) & 0xfffffff8;
3080}
3081
3082static int cq_get_mtt_size(struct mlx4_cq_context *cqc)
3083{
3084        int log_cq_size = (be32_to_cpu(cqc->logsize_usrpage) >> 24) & 0x1f;
3085        int page_shift = (cqc->log_page_size & 0x3f) + 12;
3086
3087        if (log_cq_size + 5 < page_shift)
3088                return 1;
3089
3090        return 1 << (log_cq_size + 5 - page_shift);
3091}
3092
3093int mlx4_SW2HW_EQ_wrapper(struct mlx4_dev *dev, int slave,
3094                          struct mlx4_vhcr *vhcr,
3095                          struct mlx4_cmd_mailbox *inbox,
3096                          struct mlx4_cmd_mailbox *outbox,
3097                          struct mlx4_cmd_info *cmd)
3098{
3099        int err;
3100        int eqn = vhcr->in_modifier;
3101        int res_id = (slave << 10) | eqn;
3102        struct mlx4_eq_context *eqc = inbox->buf;
3103        int mtt_base = eq_get_mtt_addr(eqc) / dev->caps.mtt_entry_sz;
3104        int mtt_size = eq_get_mtt_size(eqc);
3105        struct res_eq *eq;
3106        struct res_mtt *mtt;
3107
3108        err = add_res_range(dev, slave, res_id, 1, RES_EQ, 0);
3109        if (err)
3110                return err;
3111        err = eq_res_start_move_to(dev, slave, res_id, RES_EQ_HW, &eq);
3112        if (err)
3113                goto out_add;
3114
3115        err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
3116        if (err)
3117                goto out_move;
3118
3119        err = check_mtt_range(dev, slave, mtt_base, mtt_size, mtt);
3120        if (err)
3121                goto out_put;
3122
3123        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3124        if (err)
3125                goto out_put;
3126
3127        atomic_inc(&mtt->ref_count);
3128        eq->mtt = mtt;
3129        put_res(dev, slave, mtt->com.res_id, RES_MTT);
3130        res_end_move(dev, slave, RES_EQ, res_id);
3131        return 0;
3132
3133out_put:
3134        put_res(dev, slave, mtt->com.res_id, RES_MTT);
3135out_move:
3136        res_abort_move(dev, slave, RES_EQ, res_id);
3137out_add:
3138        rem_res_range(dev, slave, res_id, 1, RES_EQ, 0);
3139        return err;
3140}
3141
3142int mlx4_CONFIG_DEV_wrapper(struct mlx4_dev *dev, int slave,
3143                            struct mlx4_vhcr *vhcr,
3144                            struct mlx4_cmd_mailbox *inbox,
3145                            struct mlx4_cmd_mailbox *outbox,
3146                            struct mlx4_cmd_info *cmd)
3147{
3148        int err;
3149        u8 get = vhcr->op_modifier;
3150
3151        if (get != 1)
3152                return -EPERM;
3153
3154        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3155
3156        return err;
3157}
3158
3159static int get_containing_mtt(struct mlx4_dev *dev, int slave, int start,
3160                              int len, struct res_mtt **res)
3161{
3162        struct mlx4_priv *priv = mlx4_priv(dev);
3163        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
3164        struct res_mtt *mtt;
3165        int err = -EINVAL;
3166
3167        spin_lock_irq(mlx4_tlock(dev));
3168        list_for_each_entry(mtt, &tracker->slave_list[slave].res_list[RES_MTT],
3169                            com.list) {
3170                if (!check_mtt_range(dev, slave, start, len, mtt)) {
3171                        *res = mtt;
3172                        mtt->com.from_state = mtt->com.state;
3173                        mtt->com.state = RES_MTT_BUSY;
3174                        err = 0;
3175                        break;
3176                }
3177        }
3178        spin_unlock_irq(mlx4_tlock(dev));
3179
3180        return err;
3181}
3182
3183static int verify_qp_parameters(struct mlx4_dev *dev,
3184                                struct mlx4_vhcr *vhcr,
3185                                struct mlx4_cmd_mailbox *inbox,
3186                                enum qp_transition transition, u8 slave)
3187{
3188        u32                     qp_type;
3189        u32                     qpn;
3190        struct mlx4_qp_context  *qp_ctx;
3191        enum mlx4_qp_optpar     optpar;
3192        int port;
3193        int num_gids;
3194
3195        qp_ctx  = inbox->buf + 8;
3196        qp_type = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff;
3197        optpar  = be32_to_cpu(*(__be32 *) inbox->buf);
3198
3199        if (slave != mlx4_master_func_num(dev)) {
3200                qp_ctx->params2 &= ~cpu_to_be32(MLX4_QP_BIT_FPP);
3201                /* setting QP rate-limit is disallowed for VFs */
3202                if (qp_ctx->rate_limit_params)
3203                        return -EPERM;
3204        }
3205
3206        switch (qp_type) {
3207        case MLX4_QP_ST_RC:
3208        case MLX4_QP_ST_XRC:
3209        case MLX4_QP_ST_UC:
3210                switch (transition) {
3211                case QP_TRANS_INIT2RTR:
3212                case QP_TRANS_RTR2RTS:
3213                case QP_TRANS_RTS2RTS:
3214                case QP_TRANS_SQD2SQD:
3215                case QP_TRANS_SQD2RTS:
3216                        if (slave != mlx4_master_func_num(dev)) {
3217                                if (optpar & MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH) {
3218                                        port = (qp_ctx->pri_path.sched_queue >> 6 & 1) + 1;
3219                                        if (dev->caps.port_mask[port] != MLX4_PORT_TYPE_IB)
3220                                                num_gids = mlx4_get_slave_num_gids(dev, slave, port);
3221                                        else
3222                                                num_gids = 1;
3223                                        if (qp_ctx->pri_path.mgid_index >= num_gids)
3224                                                return -EINVAL;
3225                                }
3226                                if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) {
3227                                        port = (qp_ctx->alt_path.sched_queue >> 6 & 1) + 1;
3228                                        if (dev->caps.port_mask[port] != MLX4_PORT_TYPE_IB)
3229                                                num_gids = mlx4_get_slave_num_gids(dev, slave, port);
3230                                        else
3231                                                num_gids = 1;
3232                                        if (qp_ctx->alt_path.mgid_index >= num_gids)
3233                                                return -EINVAL;
3234                                }
3235                        }
3236                        break;
3237                default:
3238                        break;
3239                }
3240                break;
3241
3242        case MLX4_QP_ST_MLX:
3243                qpn = vhcr->in_modifier & 0x7fffff;
3244                port = (qp_ctx->pri_path.sched_queue >> 6 & 1) + 1;
3245                if (transition == QP_TRANS_INIT2RTR &&
3246                    slave != mlx4_master_func_num(dev) &&
3247                    mlx4_is_qp_reserved(dev, qpn) &&
3248                    !mlx4_vf_smi_enabled(dev, slave, port)) {
3249                        /* only enabled VFs may create MLX proxy QPs */
3250                        mlx4_err(dev, "%s: unprivileged slave %d attempting to create an MLX proxy special QP on port %d\n",
3251                                 __func__, slave, port);
3252                        return -EPERM;
3253                }
3254                break;
3255
3256        default:
3257                break;
3258        }
3259
3260        return 0;
3261}
3262
3263int mlx4_WRITE_MTT_wrapper(struct mlx4_dev *dev, int slave,
3264                           struct mlx4_vhcr *vhcr,
3265                           struct mlx4_cmd_mailbox *inbox,
3266                           struct mlx4_cmd_mailbox *outbox,
3267                           struct mlx4_cmd_info *cmd)
3268{
3269        struct mlx4_mtt mtt;
3270        __be64 *page_list = inbox->buf;
3271        u64 *pg_list = (u64 *)page_list;
3272        int i;
3273        struct res_mtt *rmtt = NULL;
3274        int start = be64_to_cpu(page_list[0]);
3275        int npages = vhcr->in_modifier;
3276        int err;
3277
3278        err = get_containing_mtt(dev, slave, start, npages, &rmtt);
3279        if (err)
3280                return err;
3281
3282        /* Call the SW implementation of write_mtt:
3283         * - Prepare a dummy mtt struct
3284         * - Translate inbox contents to simple addresses in host endianness */
3285        mtt.offset = 0;  /* TBD this is broken but I don't handle it since
3286                            we don't really use it */
3287        mtt.order = 0;
3288        mtt.page_shift = 0;
3289        for (i = 0; i < npages; ++i)
3290                pg_list[i + 2] = (be64_to_cpu(page_list[i + 2]) & ~1ULL);
3291
3292        err = __mlx4_write_mtt(dev, &mtt, be64_to_cpu(page_list[0]), npages,
3293                               ((u64 *)page_list + 2));
3294
3295        if (rmtt)
3296                put_res(dev, slave, rmtt->com.res_id, RES_MTT);
3297
3298        return err;
3299}
3300
3301int mlx4_HW2SW_EQ_wrapper(struct mlx4_dev *dev, int slave,
3302                          struct mlx4_vhcr *vhcr,
3303                          struct mlx4_cmd_mailbox *inbox,
3304                          struct mlx4_cmd_mailbox *outbox,
3305                          struct mlx4_cmd_info *cmd)
3306{
3307        int eqn = vhcr->in_modifier;
3308        int res_id = eqn | (slave << 10);
3309        struct res_eq *eq;
3310        int err;
3311
3312        err = eq_res_start_move_to(dev, slave, res_id, RES_EQ_RESERVED, &eq);
3313        if (err)
3314                return err;
3315
3316        err = get_res(dev, slave, eq->mtt->com.res_id, RES_MTT, NULL);
3317        if (err)
3318                goto ex_abort;
3319
3320        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3321        if (err)
3322                goto ex_put;
3323
3324        atomic_dec(&eq->mtt->ref_count);
3325        put_res(dev, slave, eq->mtt->com.res_id, RES_MTT);
3326        res_end_move(dev, slave, RES_EQ, res_id);
3327        rem_res_range(dev, slave, res_id, 1, RES_EQ, 0);
3328
3329        return 0;
3330
3331ex_put:
3332        put_res(dev, slave, eq->mtt->com.res_id, RES_MTT);
3333ex_abort:
3334        res_abort_move(dev, slave, RES_EQ, res_id);
3335
3336        return err;
3337}
3338
3339int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe)
3340{
3341        struct mlx4_priv *priv = mlx4_priv(dev);
3342        struct mlx4_slave_event_eq_info *event_eq;
3343        struct mlx4_cmd_mailbox *mailbox;
3344        u32 in_modifier = 0;
3345        int err;
3346        int res_id;
3347        struct res_eq *req;
3348
3349        if (!priv->mfunc.master.slave_state)
3350                return -EINVAL;
3351
3352        /* check for slave valid, slave not PF, and slave active */
3353        if (slave < 0 || slave > dev->persist->num_vfs ||
3354            slave == dev->caps.function ||
3355            !priv->mfunc.master.slave_state[slave].active)
3356                return 0;
3357
3358        event_eq = &priv->mfunc.master.slave_state[slave].event_eq[eqe->type];
3359
3360        /* Create the event only if the slave is registered */
3361        if (event_eq->eqn < 0)
3362                return 0;
3363
3364        mutex_lock(&priv->mfunc.master.gen_eqe_mutex[slave]);
3365        res_id = (slave << 10) | event_eq->eqn;
3366        err = get_res(dev, slave, res_id, RES_EQ, &req);
3367        if (err)
3368                goto unlock;
3369
3370        if (req->com.from_state != RES_EQ_HW) {
3371                err = -EINVAL;
3372                goto put;
3373        }
3374
3375        mailbox = mlx4_alloc_cmd_mailbox(dev);
3376        if (IS_ERR(mailbox)) {
3377                err = PTR_ERR(mailbox);
3378                goto put;
3379        }
3380
3381        if (eqe->type == MLX4_EVENT_TYPE_CMD) {
3382                ++event_eq->token;
3383                eqe->event.cmd.token = cpu_to_be16(event_eq->token);
3384        }
3385
3386        memcpy(mailbox->buf, (u8 *) eqe, 28);
3387
3388        in_modifier = (slave & 0xff) | ((event_eq->eqn & 0x3ff) << 16);
3389
3390        err = mlx4_cmd(dev, mailbox->dma, in_modifier, 0,
3391                       MLX4_CMD_GEN_EQE, MLX4_CMD_TIME_CLASS_B,
3392                       MLX4_CMD_NATIVE);
3393
3394        put_res(dev, slave, res_id, RES_EQ);
3395        mutex_unlock(&priv->mfunc.master.gen_eqe_mutex[slave]);
3396        mlx4_free_cmd_mailbox(dev, mailbox);
3397        return err;
3398
3399put:
3400        put_res(dev, slave, res_id, RES_EQ);
3401
3402unlock:
3403        mutex_unlock(&priv->mfunc.master.gen_eqe_mutex[slave]);
3404        return err;
3405}
3406
3407int mlx4_QUERY_EQ_wrapper(struct mlx4_dev *dev, int slave,
3408                          struct mlx4_vhcr *vhcr,
3409                          struct mlx4_cmd_mailbox *inbox,
3410                          struct mlx4_cmd_mailbox *outbox,
3411                          struct mlx4_cmd_info *cmd)
3412{
3413        int eqn = vhcr->in_modifier;
3414        int res_id = eqn | (slave << 10);
3415        struct res_eq *eq;
3416        int err;
3417
3418        err = get_res(dev, slave, res_id, RES_EQ, &eq);
3419        if (err)
3420                return err;
3421
3422        if (eq->com.from_state != RES_EQ_HW) {
3423                err = -EINVAL;
3424                goto ex_put;
3425        }
3426
3427        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3428
3429ex_put:
3430        put_res(dev, slave, res_id, RES_EQ);
3431        return err;
3432}
3433
3434int mlx4_SW2HW_CQ_wrapper(struct mlx4_dev *dev, int slave,
3435                          struct mlx4_vhcr *vhcr,
3436                          struct mlx4_cmd_mailbox *inbox,
3437                          struct mlx4_cmd_mailbox *outbox,
3438                          struct mlx4_cmd_info *cmd)
3439{
3440        int err;
3441        int cqn = vhcr->in_modifier;
3442        struct mlx4_cq_context *cqc = inbox->buf;
3443        int mtt_base = cq_get_mtt_addr(cqc) / dev->caps.mtt_entry_sz;
3444        struct res_cq *cq = NULL;
3445        struct res_mtt *mtt;
3446
3447        err = cq_res_start_move_to(dev, slave, cqn, RES_CQ_HW, &cq);
3448        if (err)
3449                return err;
3450        err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
3451        if (err)
3452                goto out_move;
3453        err = check_mtt_range(dev, slave, mtt_base, cq_get_mtt_size(cqc), mtt);
3454        if (err)
3455                goto out_put;
3456        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3457        if (err)
3458                goto out_put;
3459        atomic_inc(&mtt->ref_count);
3460        cq->mtt = mtt;
3461        put_res(dev, slave, mtt->com.res_id, RES_MTT);
3462        res_end_move(dev, slave, RES_CQ, cqn);
3463        return 0;
3464
3465out_put:
3466        put_res(dev, slave, mtt->com.res_id, RES_MTT);
3467out_move:
3468        res_abort_move(dev, slave, RES_CQ, cqn);
3469        return err;
3470}
3471
3472int mlx4_HW2SW_CQ_wrapper(struct mlx4_dev *dev, int slave,
3473                          struct mlx4_vhcr *vhcr,
3474                          struct mlx4_cmd_mailbox *inbox,
3475                          struct mlx4_cmd_mailbox *outbox,
3476                          struct mlx4_cmd_info *cmd)
3477{
3478        int err;
3479        int cqn = vhcr->in_modifier;
3480        struct res_cq *cq = NULL;
3481
3482        err = cq_res_start_move_to(dev, slave, cqn, RES_CQ_ALLOCATED, &cq);
3483        if (err)
3484                return err;
3485        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3486        if (err)
3487                goto out_move;
3488        atomic_dec(&cq->mtt->ref_count);
3489        res_end_move(dev, slave, RES_CQ, cqn);
3490        return 0;
3491
3492out_move:
3493        res_abort_move(dev, slave, RES_CQ, cqn);
3494        return err;
3495}
3496
3497int mlx4_QUERY_CQ_wrapper(struct mlx4_dev *dev, int slave,
3498                          struct mlx4_vhcr *vhcr,
3499                          struct mlx4_cmd_mailbox *inbox,
3500                          struct mlx4_cmd_mailbox *outbox,
3501                          struct mlx4_cmd_info *cmd)
3502{
3503        int cqn = vhcr->in_modifier;
3504        struct res_cq *cq;
3505        int err;
3506
3507        err = get_res(dev, slave, cqn, RES_CQ, &cq);
3508        if (err)
3509                return err;
3510
3511        if (cq->com.from_state != RES_CQ_HW)
3512                goto ex_put;
3513
3514        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3515ex_put:
3516        put_res(dev, slave, cqn, RES_CQ);
3517
3518        return err;
3519}
3520
3521static int handle_resize(struct mlx4_dev *dev, int slave,
3522                         struct mlx4_vhcr *vhcr,
3523                         struct mlx4_cmd_mailbox *inbox,
3524                         struct mlx4_cmd_mailbox *outbox,
3525                         struct mlx4_cmd_info *cmd,
3526                         struct res_cq *cq)
3527{
3528        int err;
3529        struct res_mtt *orig_mtt;
3530        struct res_mtt *mtt;
3531        struct mlx4_cq_context *cqc = inbox->buf;
3532        int mtt_base = cq_get_mtt_addr(cqc) / dev->caps.mtt_entry_sz;
3533
3534        err = get_res(dev, slave, cq->mtt->com.res_id, RES_MTT, &orig_mtt);
3535        if (err)
3536                return err;
3537
3538        if (orig_mtt != cq->mtt) {
3539                err = -EINVAL;
3540                goto ex_put;
3541        }
3542
3543        err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
3544        if (err)
3545                goto ex_put;
3546
3547        err = check_mtt_range(dev, slave, mtt_base, cq_get_mtt_size(cqc), mtt);
3548        if (err)
3549                goto ex_put1;
3550        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3551        if (err)
3552                goto ex_put1;
3553        atomic_dec(&orig_mtt->ref_count);
3554        put_res(dev, slave, orig_mtt->com.res_id, RES_MTT);
3555        atomic_inc(&mtt->ref_count);
3556        cq->mtt = mtt;
3557        put_res(dev, slave, mtt->com.res_id, RES_MTT);
3558        return 0;
3559
3560ex_put1:
3561        put_res(dev, slave, mtt->com.res_id, RES_MTT);
3562ex_put:
3563        put_res(dev, slave, orig_mtt->com.res_id, RES_MTT);
3564
3565        return err;
3566
3567}
3568
3569int mlx4_MODIFY_CQ_wrapper(struct mlx4_dev *dev, int slave,
3570                           struct mlx4_vhcr *vhcr,
3571                           struct mlx4_cmd_mailbox *inbox,
3572                           struct mlx4_cmd_mailbox *outbox,
3573                           struct mlx4_cmd_info *cmd)
3574{
3575        int cqn = vhcr->in_modifier;
3576        struct res_cq *cq;
3577        int err;
3578
3579        err = get_res(dev, slave, cqn, RES_CQ, &cq);
3580        if (err)
3581                return err;
3582
3583        if (cq->com.from_state != RES_CQ_HW)
3584                goto ex_put;
3585
3586        if (vhcr->op_modifier == 0) {
3587                err = handle_resize(dev, slave, vhcr, inbox, outbox, cmd, cq);
3588                goto ex_put;
3589        }
3590
3591        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3592ex_put:
3593        put_res(dev, slave, cqn, RES_CQ);
3594
3595        return err;
3596}
3597
3598static int srq_get_mtt_size(struct mlx4_srq_context *srqc)
3599{
3600        int log_srq_size = (be32_to_cpu(srqc->state_logsize_srqn) >> 24) & 0xf;
3601        int log_rq_stride = srqc->logstride & 7;
3602        int page_shift = (srqc->log_page_size & 0x3f) + 12;
3603
3604        if (log_srq_size + log_rq_stride + 4 < page_shift)
3605                return 1;
3606
3607        return 1 << (log_srq_size + log_rq_stride + 4 - page_shift);
3608}
3609
3610int mlx4_SW2HW_SRQ_wrapper(struct mlx4_dev *dev, int slave,
3611                           struct mlx4_vhcr *vhcr,
3612                           struct mlx4_cmd_mailbox *inbox,
3613                           struct mlx4_cmd_mailbox *outbox,
3614                           struct mlx4_cmd_info *cmd)
3615{
3616        int err;
3617        int srqn = vhcr->in_modifier;
3618        struct res_mtt *mtt;
3619        struct res_srq *srq = NULL;
3620        struct mlx4_srq_context *srqc = inbox->buf;
3621        int mtt_base = srq_get_mtt_addr(srqc) / dev->caps.mtt_entry_sz;
3622
3623        if (srqn != (be32_to_cpu(srqc->state_logsize_srqn) & 0xffffff))
3624                return -EINVAL;
3625
3626        err = srq_res_start_move_to(dev, slave, srqn, RES_SRQ_HW, &srq);
3627        if (err)
3628                return err;
3629        err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
3630        if (err)
3631                goto ex_abort;
3632        err = check_mtt_range(dev, slave, mtt_base, srq_get_mtt_size(srqc),
3633                              mtt);
3634        if (err)
3635                goto ex_put_mtt;
3636
3637        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3638        if (err)
3639                goto ex_put_mtt;
3640
3641        atomic_inc(&mtt->ref_count);
3642        srq->mtt = mtt;
3643        put_res(dev, slave, mtt->com.res_id, RES_MTT);
3644        res_end_move(dev, slave, RES_SRQ, srqn);
3645        return 0;
3646
3647ex_put_mtt:
3648        put_res(dev, slave, mtt->com.res_id, RES_MTT);
3649ex_abort:
3650        res_abort_move(dev, slave, RES_SRQ, srqn);
3651
3652        return err;
3653}
3654
3655int mlx4_HW2SW_SRQ_wrapper(struct mlx4_dev *dev, int slave,
3656                           struct mlx4_vhcr *vhcr,
3657                           struct mlx4_cmd_mailbox *inbox,
3658                           struct mlx4_cmd_mailbox *outbox,
3659                           struct mlx4_cmd_info *cmd)
3660{
3661        int err;
3662        int srqn = vhcr->in_modifier;
3663        struct res_srq *srq = NULL;
3664
3665        err = srq_res_start_move_to(dev, slave, srqn, RES_SRQ_ALLOCATED, &srq);
3666        if (err)
3667                return err;
3668        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3669        if (err)
3670                goto ex_abort;
3671        atomic_dec(&srq->mtt->ref_count);
3672        if (srq->cq)
3673                atomic_dec(&srq->cq->ref_count);
3674        res_end_move(dev, slave, RES_SRQ, srqn);
3675
3676        return 0;
3677
3678ex_abort:
3679        res_abort_move(dev, slave, RES_SRQ, srqn);
3680
3681        return err;
3682}
3683
3684int mlx4_QUERY_SRQ_wrapper(struct mlx4_dev *dev, int slave,
3685                           struct mlx4_vhcr *vhcr,
3686                           struct mlx4_cmd_mailbox *inbox,
3687                           struct mlx4_cmd_mailbox *outbox,
3688                           struct mlx4_cmd_info *cmd)
3689{
3690        int err;
3691        int srqn = vhcr->in_modifier;
3692        struct res_srq *srq;
3693
3694        err = get_res(dev, slave, srqn, RES_SRQ, &srq);
3695        if (err)
3696                return err;
3697        if (srq->com.from_state != RES_SRQ_HW) {
3698                err = -EBUSY;
3699                goto out;
3700        }
3701        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3702out:
3703        put_res(dev, slave, srqn, RES_SRQ);
3704        return err;
3705}
3706
3707int mlx4_ARM_SRQ_wrapper(struct mlx4_dev *dev, int slave,
3708                         struct mlx4_vhcr *vhcr,
3709                         struct mlx4_cmd_mailbox *inbox,
3710                         struct mlx4_cmd_mailbox *outbox,
3711                         struct mlx4_cmd_info *cmd)
3712{
3713        int err;
3714        int srqn = vhcr->in_modifier;
3715        struct res_srq *srq;
3716
3717        err = get_res(dev, slave, srqn, RES_SRQ, &srq);
3718        if (err)
3719                return err;
3720
3721        if (srq->com.from_state != RES_SRQ_HW) {
3722                err = -EBUSY;
3723                goto out;
3724        }
3725
3726        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3727out:
3728        put_res(dev, slave, srqn, RES_SRQ);
3729        return err;
3730}
3731
3732int mlx4_GEN_QP_wrapper(struct mlx4_dev *dev, int slave,
3733                        struct mlx4_vhcr *vhcr,
3734                        struct mlx4_cmd_mailbox *inbox,
3735                        struct mlx4_cmd_mailbox *outbox,
3736                        struct mlx4_cmd_info *cmd)
3737{
3738        int err;
3739        int qpn = vhcr->in_modifier & 0x7fffff;
3740        struct res_qp *qp;
3741
3742        err = get_res(dev, slave, qpn, RES_QP, &qp);
3743        if (err)
3744                return err;
3745        if (qp->com.from_state != RES_QP_HW) {
3746                err = -EBUSY;
3747                goto out;
3748        }
3749
3750        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3751out:
3752        put_res(dev, slave, qpn, RES_QP);
3753        return err;
3754}
3755
3756int mlx4_INIT2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
3757                              struct mlx4_vhcr *vhcr,
3758                              struct mlx4_cmd_mailbox *inbox,
3759                              struct mlx4_cmd_mailbox *outbox,
3760                              struct mlx4_cmd_info *cmd)
3761{
3762        struct mlx4_qp_context *context = inbox->buf + 8;
3763        adjust_proxy_tun_qkey(dev, vhcr, context);
3764        update_pkey_index(dev, slave, inbox);
3765        return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3766}
3767
3768static int adjust_qp_sched_queue(struct mlx4_dev *dev, int slave,
3769                                  struct mlx4_qp_context *qpc,
3770                                  struct mlx4_cmd_mailbox *inbox)
3771{
3772        enum mlx4_qp_optpar optpar = be32_to_cpu(*(__be32 *)inbox->buf);
3773        u8 pri_sched_queue;
3774        int port = mlx4_slave_convert_port(
3775                   dev, slave, (qpc->pri_path.sched_queue >> 6 & 1) + 1) - 1;
3776
3777        if (port < 0)
3778                return -EINVAL;
3779
3780        pri_sched_queue = (qpc->pri_path.sched_queue & ~(1 << 6)) |
3781                          ((port & 1) << 6);
3782
3783        if (optpar & (MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH | MLX4_QP_OPTPAR_SCHED_QUEUE) ||
3784            qpc->pri_path.sched_queue || mlx4_is_eth(dev, port + 1)) {
3785                qpc->pri_path.sched_queue = pri_sched_queue;
3786        }
3787
3788        if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) {
3789                port = mlx4_slave_convert_port(
3790                                dev, slave, (qpc->alt_path.sched_queue >> 6 & 1)
3791                                + 1) - 1;
3792                if (port < 0)
3793                        return -EINVAL;
3794                qpc->alt_path.sched_queue =
3795                        (qpc->alt_path.sched_queue & ~(1 << 6)) |
3796                        (port & 1) << 6;
3797        }
3798        return 0;
3799}
3800
3801static int roce_verify_mac(struct mlx4_dev *dev, int slave,
3802                                struct mlx4_qp_context *qpc,
3803                                struct mlx4_cmd_mailbox *inbox)
3804{
3805        u64 mac;
3806        int port;
3807        u32 ts = (be32_to_cpu(qpc->flags) >> 16) & 0xff;
3808        u8 sched = *(u8 *)(inbox->buf + 64);
3809        u8 smac_ix;
3810
3811        port = (sched >> 6 & 1) + 1;
3812        if (mlx4_is_eth(dev, port) && (ts != MLX4_QP_ST_MLX)) {
3813                smac_ix = qpc->pri_path.grh_mylmc & 0x7f;
3814                if (mac_find_smac_ix_in_slave(dev, slave, port, smac_ix, &mac))
3815                        return -ENOENT;
3816        }
3817        return 0;
3818}
3819
3820int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave,
3821                             struct mlx4_vhcr *vhcr,
3822                             struct mlx4_cmd_mailbox *inbox,
3823                             struct mlx4_cmd_mailbox *outbox,
3824                             struct mlx4_cmd_info *cmd)
3825{
3826        int err;
3827        struct mlx4_qp_context *qpc = inbox->buf + 8;
3828        int qpn = vhcr->in_modifier & 0x7fffff;
3829        struct res_qp *qp;
3830        u8 orig_sched_queue;
3831        u8 orig_vlan_control = qpc->pri_path.vlan_control;
3832        u8 orig_fvl_rx = qpc->pri_path.fvl_rx;
3833        u8 orig_pri_path_fl = qpc->pri_path.fl;
3834        u8 orig_vlan_index = qpc->pri_path.vlan_index;
3835        u8 orig_feup = qpc->pri_path.feup;
3836
3837        err = adjust_qp_sched_queue(dev, slave, qpc, inbox);
3838        if (err)
3839                return err;
3840        err = verify_qp_parameters(dev, vhcr, inbox, QP_TRANS_INIT2RTR, slave);
3841        if (err)
3842                return err;
3843
3844        if (roce_verify_mac(dev, slave, qpc, inbox))
3845                return -EINVAL;
3846
3847        update_pkey_index(dev, slave, inbox);
3848        update_gid(dev, inbox, (u8)slave);
3849        adjust_proxy_tun_qkey(dev, vhcr, qpc);
3850        orig_sched_queue = qpc->pri_path.sched_queue;
3851
3852        err = get_res(dev, slave, qpn, RES_QP, &qp);
3853        if (err)
3854                return err;
3855        if (qp->com.from_state != RES_QP_HW) {
3856                err = -EBUSY;
3857                goto out;
3858        }
3859
3860        err = update_vport_qp_param(dev, inbox, slave, qpn);
3861        if (err)
3862                goto out;
3863
3864        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3865out:
3866        /* if no error, save sched queue value passed in by VF. This is
3867         * essentially the QOS value provided by the VF. This will be useful
3868         * if we allow dynamic changes from VST back to VGT
3869         */
3870        if (!err) {
3871                qp->sched_queue = orig_sched_queue;
3872                qp->vlan_control = orig_vlan_control;
3873                qp->fvl_rx      =  orig_fvl_rx;
3874                qp->pri_path_fl = orig_pri_path_fl;
3875                qp->vlan_index  = orig_vlan_index;
3876                qp->feup        = orig_feup;
3877        }
3878        put_res(dev, slave, qpn, RES_QP);
3879        return err;
3880}
3881
3882int mlx4_RTR2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
3883                            struct mlx4_vhcr *vhcr,
3884                            struct mlx4_cmd_mailbox *inbox,
3885                            struct mlx4_cmd_mailbox *outbox,
3886                            struct mlx4_cmd_info *cmd)
3887{
3888        int err;
3889        struct mlx4_qp_context *context = inbox->buf + 8;
3890
3891        err = adjust_qp_sched_queue(dev, slave, context, inbox);
3892        if (err)
3893                return err;
3894        err = verify_qp_parameters(dev, vhcr, inbox, QP_TRANS_RTR2RTS, slave);
3895        if (err)
3896                return err;
3897
3898        update_pkey_index(dev, slave, inbox);
3899        update_gid(dev, inbox, (u8)slave);
3900        adjust_proxy_tun_qkey(dev, vhcr, context);
3901        return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3902}
3903
3904int mlx4_RTS2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
3905                            struct mlx4_vhcr *vhcr,
3906                            struct mlx4_cmd_mailbox *inbox,
3907                            struct mlx4_cmd_mailbox *outbox,
3908                            struct mlx4_cmd_info *cmd)
3909{
3910        int err;
3911        struct mlx4_qp_context *context = inbox->buf + 8;
3912
3913        err = adjust_qp_sched_queue(dev, slave, context, inbox);
3914        if (err)
3915                return err;
3916        err = verify_qp_parameters(dev, vhcr, inbox, QP_TRANS_RTS2RTS, slave);
3917        if (err)
3918                return err;
3919
3920        update_pkey_index(dev, slave, inbox);
3921        update_gid(dev, inbox, (u8)slave);
3922        adjust_proxy_tun_qkey(dev, vhcr, context);
3923        return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3924}
3925
3926
3927int mlx4_SQERR2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
3928                              struct mlx4_vhcr *vhcr,
3929                              struct mlx4_cmd_mailbox *inbox,
3930                              struct mlx4_cmd_mailbox *outbox,
3931                              struct mlx4_cmd_info *cmd)
3932{
3933        struct mlx4_qp_context *context = inbox->buf + 8;
3934        int err = adjust_qp_sched_queue(dev, slave, context, inbox);
3935        if (err)
3936                return err;
3937        adjust_proxy_tun_qkey(dev, vhcr, context);
3938        return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3939}
3940
3941int mlx4_SQD2SQD_QP_wrapper(struct mlx4_dev *dev, int slave,
3942                            struct mlx4_vhcr *vhcr,
3943                            struct mlx4_cmd_mailbox *inbox,
3944                            struct mlx4_cmd_mailbox *outbox,
3945                            struct mlx4_cmd_info *cmd)
3946{
3947        int err;
3948        struct mlx4_qp_context *context = inbox->buf + 8;
3949
3950        err = adjust_qp_sched_queue(dev, slave, context, inbox);
3951        if (err)
3952                return err;
3953        err = verify_qp_parameters(dev, vhcr, inbox, QP_TRANS_SQD2SQD, slave);
3954        if (err)
3955                return err;
3956
3957        adjust_proxy_tun_qkey(dev, vhcr, context);
3958        update_gid(dev, inbox, (u8)slave);
3959        update_pkey_index(dev, slave, inbox);
3960        return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3961}
3962
3963int mlx4_SQD2RTS_QP_wrapper(struct mlx4_dev *dev, int slave,
3964                            struct mlx4_vhcr *vhcr,
3965                            struct mlx4_cmd_mailbox *inbox,
3966                            struct mlx4_cmd_mailbox *outbox,
3967                            struct mlx4_cmd_info *cmd)
3968{
3969        int err;
3970        struct mlx4_qp_context *context = inbox->buf + 8;
3971
3972        err = adjust_qp_sched_queue(dev, slave, context, inbox);
3973        if (err)
3974                return err;
3975        err = verify_qp_parameters(dev, vhcr, inbox, QP_TRANS_SQD2RTS, slave);
3976        if (err)
3977                return err;
3978
3979        adjust_proxy_tun_qkey(dev, vhcr, context);
3980        update_gid(dev, inbox, (u8)slave);
3981        update_pkey_index(dev, slave, inbox);
3982        return mlx4_GEN_QP_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3983}
3984
3985int mlx4_2RST_QP_wrapper(struct mlx4_dev *dev, int slave,
3986                         struct mlx4_vhcr *vhcr,
3987                         struct mlx4_cmd_mailbox *inbox,
3988                         struct mlx4_cmd_mailbox *outbox,
3989                         struct mlx4_cmd_info *cmd)
3990{
3991        int err;
3992        int qpn = vhcr->in_modifier & 0x7fffff;
3993        struct res_qp *qp;
3994
3995        err = qp_res_start_move_to(dev, slave, qpn, RES_QP_MAPPED, &qp, 0);
3996        if (err)
3997                return err;
3998        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
3999        if (err)
4000                goto ex_abort;
4001
4002        atomic_dec(&qp->mtt->ref_count);
4003        atomic_dec(&qp->rcq->ref_count);
4004        atomic_dec(&qp->scq->ref_count);
4005        if (qp->srq)
4006                atomic_dec(&qp->srq->ref_count);
4007        res_end_move(dev, slave, RES_QP, qpn);
4008        return 0;
4009
4010ex_abort:
4011        res_abort_move(dev, slave, RES_QP, qpn);
4012
4013        return err;
4014}
4015
4016static struct res_gid *find_gid(struct mlx4_dev *dev, int slave,
4017                                struct res_qp *rqp, u8 *gid)
4018{
4019        struct res_gid *res;
4020
4021        list_for_each_entry(res, &rqp->mcg_list, list) {
4022                if (!memcmp(res->gid, gid, 16))
4023                        return res;
4024        }
4025        return NULL;
4026}
4027
4028static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
4029                       u8 *gid, enum mlx4_protocol prot,
4030                       enum mlx4_steer_type steer, u64 reg_id)
4031{
4032        struct res_gid *res;
4033        int err;
4034
4035        res = kzalloc(sizeof(*res), GFP_KERNEL);
4036        if (!res)
4037                return -ENOMEM;
4038
4039        spin_lock_irq(&rqp->mcg_spl);
4040        if (find_gid(dev, slave, rqp, gid)) {
4041                kfree(res);
4042                err = -EEXIST;
4043        } else {
4044                memcpy(res->gid, gid, 16);
4045                res->prot = prot;
4046                res->steer = steer;
4047                res->reg_id = reg_id;
4048                list_add_tail(&res->list, &rqp->mcg_list);
4049                err = 0;
4050        }
4051        spin_unlock_irq(&rqp->mcg_spl);
4052
4053        return err;
4054}
4055
4056static int rem_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp,
4057                       u8 *gid, enum mlx4_protocol prot,
4058                       enum mlx4_steer_type steer, u64 *reg_id)
4059{
4060        struct res_gid *res;
4061        int err;
4062
4063        spin_lock_irq(&rqp->mcg_spl);
4064        res = find_gid(dev, slave, rqp, gid);
4065        if (!res || res->prot != prot || res->steer != steer)
4066                err = -EINVAL;
4067        else {
4068                *reg_id = res->reg_id;
4069                list_del(&res->list);
4070                kfree(res);
4071                err = 0;
4072        }
4073        spin_unlock_irq(&rqp->mcg_spl);
4074
4075        return err;
4076}
4077
4078static int qp_attach(struct mlx4_dev *dev, int slave, struct mlx4_qp *qp,
4079                     u8 gid[16], int block_loopback, enum mlx4_protocol prot,
4080                     enum mlx4_steer_type type, u64 *reg_id)
4081{
4082        switch (dev->caps.steering_mode) {
4083        case MLX4_STEERING_MODE_DEVICE_MANAGED: {
4084                int port = mlx4_slave_convert_port(dev, slave, gid[5]);
4085                if (port < 0)
4086                        return port;
4087                return mlx4_trans_to_dmfs_attach(dev, qp, gid, port,
4088                                                block_loopback, prot,
4089                                                reg_id);
4090        }
4091        case MLX4_STEERING_MODE_B0:
4092                if (prot == MLX4_PROT_ETH) {
4093                        int port = mlx4_slave_convert_port(dev, slave, gid[5]);
4094                        if (port < 0)
4095                                return port;
4096                        gid[5] = port;
4097                }
4098                return mlx4_qp_attach_common(dev, qp, gid,
4099                                            block_loopback, prot, type);
4100        default:
4101                return -EINVAL;
4102        }
4103}
4104
4105static int qp_detach(struct mlx4_dev *dev, struct mlx4_qp *qp,
4106                     u8 gid[16], enum mlx4_protocol prot,
4107                     enum mlx4_steer_type type, u64 reg_id)
4108{
4109        switch (dev->caps.steering_mode) {
4110        case MLX4_STEERING_MODE_DEVICE_MANAGED:
4111                return mlx4_flow_detach(dev, reg_id);
4112        case MLX4_STEERING_MODE_B0:
4113                return mlx4_qp_detach_common(dev, qp, gid, prot, type);
4114        default:
4115                return -EINVAL;
4116        }
4117}
4118
4119static int mlx4_adjust_port(struct mlx4_dev *dev, int slave,
4120                            u8 *gid, enum mlx4_protocol prot)
4121{
4122        int real_port;
4123
4124        if (prot != MLX4_PROT_ETH)
4125                return 0;
4126
4127        if (dev->caps.steering_mode == MLX4_STEERING_MODE_B0 ||
4128            dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) {
4129                real_port = mlx4_slave_convert_port(dev, slave, gid[5]);
4130                if (real_port < 0)
4131                        return -EINVAL;
4132                gid[5] = real_port;
4133        }
4134
4135        return 0;
4136}
4137
4138int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
4139                               struct mlx4_vhcr *vhcr,
4140                               struct mlx4_cmd_mailbox *inbox,
4141                               struct mlx4_cmd_mailbox *outbox,
4142                               struct mlx4_cmd_info *cmd)
4143{
4144        struct mlx4_qp qp; /* dummy for calling attach/detach */
4145        u8 *gid = inbox->buf;
4146        enum mlx4_protocol prot = (vhcr->in_modifier >> 28) & 0x7;
4147        int err;
4148        int qpn;
4149        struct res_qp *rqp;
4150        u64 reg_id = 0;
4151        int attach = vhcr->op_modifier;
4152        int block_loopback = vhcr->in_modifier >> 31;
4153        u8 steer_type_mask = 2;
4154        enum mlx4_steer_type type = (gid[7] & steer_type_mask) >> 1;
4155
4156        qpn = vhcr->in_modifier & 0xffffff;
4157        err = get_res(dev, slave, qpn, RES_QP, &rqp);
4158        if (err)
4159                return err;
4160
4161        qp.qpn = qpn;
4162        if (attach) {
4163                err = qp_attach(dev, slave, &qp, gid, block_loopback, prot,
4164                                type, &reg_id);
4165                if (err) {
4166                        pr_err("Fail to attach rule to qp 0x%x\n", qpn);
4167                        goto ex_put;
4168                }
4169                err = add_mcg_res(dev, slave, rqp, gid, prot, type, reg_id);
4170                if (err)
4171                        goto ex_detach;
4172        } else {
4173                err = mlx4_adjust_port(dev, slave, gid, prot);
4174                if (err)
4175                        goto ex_put;
4176
4177                err = rem_mcg_res(dev, slave, rqp, gid, prot, type, &reg_id);
4178                if (err)
4179                        goto ex_put;
4180
4181                err = qp_detach(dev, &qp, gid, prot, type, reg_id);
4182                if (err)
4183                        pr_err("Fail to detach rule from qp 0x%x reg_id = 0x%llx\n",
4184                               qpn, reg_id);
4185        }
4186        put_res(dev, slave, qpn, RES_QP);
4187        return err;
4188
4189ex_detach:
4190        qp_detach(dev, &qp, gid, prot, type, reg_id);
4191ex_put:
4192        put_res(dev, slave, qpn, RES_QP);
4193        return err;
4194}
4195
4196/*
4197 * MAC validation for Flow Steering rules.
4198 * VF can attach rules only with a mac address which is assigned to it.
4199 */
4200static int validate_eth_header_mac(int slave, struct _rule_hw *eth_header,
4201                                   struct list_head *rlist)
4202{
4203        struct mac_res *res, *tmp;
4204        __be64 be_mac;
4205
4206        /* make sure it isn't multicast or broadcast mac*/
4207        if (!is_multicast_ether_addr(eth_header->eth.dst_mac) &&
4208            !is_broadcast_ether_addr(eth_header->eth.dst_mac)) {
4209                list_for_each_entry_safe(res, tmp, rlist, list) {
4210                        be_mac = cpu_to_be64(res->mac << 16);
4211                        if (ether_addr_equal((u8 *)&be_mac, eth_header->eth.dst_mac))
4212                                return 0;
4213                }
4214                pr_err("MAC %pM doesn't belong to VF %d, Steering rule rejected\n",
4215                       eth_header->eth.dst_mac, slave);
4216                return -EINVAL;
4217        }
4218        return 0;
4219}
4220
4221/*
4222 * In case of missing eth header, append eth header with a MAC address
4223 * assigned to the VF.
4224 */
4225static int add_eth_header(struct mlx4_dev *dev, int slave,
4226                          struct mlx4_cmd_mailbox *inbox,
4227                          struct list_head *rlist, int header_id)
4228{
4229        struct mac_res *res, *tmp;
4230        u8 port;
4231        struct mlx4_net_trans_rule_hw_ctrl *ctrl;
4232        struct mlx4_net_trans_rule_hw_eth *eth_header;
4233        struct mlx4_net_trans_rule_hw_ipv4 *ip_header;
4234        struct mlx4_net_trans_rule_hw_tcp_udp *l4_header;
4235        __be64 be_mac = 0;
4236        __be64 mac_msk = cpu_to_be64(MLX4_MAC_MASK << 16);
4237
4238        ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf;
4239        port = ctrl->port;
4240        eth_header = (struct mlx4_net_trans_rule_hw_eth *)(ctrl + 1);
4241
4242        /* Clear a space in the inbox for eth header */
4243        switch (header_id) {
4244        case MLX4_NET_TRANS_RULE_ID_IPV4:
4245                ip_header =
4246                        (struct mlx4_net_trans_rule_hw_ipv4 *)(eth_header + 1);
4247                memmove(ip_header, eth_header,
4248                        sizeof(*ip_header) + sizeof(*l4_header));
4249                break;
4250        case MLX4_NET_TRANS_RULE_ID_TCP:
4251        case MLX4_NET_TRANS_RULE_ID_UDP:
4252                l4_header = (struct mlx4_net_trans_rule_hw_tcp_udp *)
4253                            (eth_header + 1);
4254                memmove(l4_header, eth_header, sizeof(*l4_header));
4255                break;
4256        default:
4257                return -EINVAL;
4258        }
4259        list_for_each_entry_safe(res, tmp, rlist, list) {
4260                if (port == res->port) {
4261                        be_mac = cpu_to_be64(res->mac << 16);
4262                        break;
4263                }
4264        }
4265        if (!be_mac) {
4266                pr_err("Failed adding eth header to FS rule, Can't find matching MAC for port %d\n",
4267                       port);
4268                return -EINVAL;
4269        }
4270
4271        memset(eth_header, 0, sizeof(*eth_header));
4272        eth_header->size = sizeof(*eth_header) >> 2;
4273        eth_header->id = cpu_to_be16(__sw_id_hw[MLX4_NET_TRANS_RULE_ID_ETH]);
4274        memcpy(eth_header->dst_mac, &be_mac, ETH_ALEN);
4275        memcpy(eth_header->dst_mac_msk, &mac_msk, ETH_ALEN);
4276
4277        return 0;
4278
4279}
4280
4281#define MLX4_UPD_QP_PATH_MASK_SUPPORTED      (                                \
4282        1ULL << MLX4_UPD_QP_PATH_MASK_MAC_INDEX                     |\
4283        1ULL << MLX4_UPD_QP_PATH_MASK_ETH_SRC_CHECK_MC_LB)
4284int mlx4_UPDATE_QP_wrapper(struct mlx4_dev *dev, int slave,
4285                           struct mlx4_vhcr *vhcr,
4286                           struct mlx4_cmd_mailbox *inbox,
4287                           struct mlx4_cmd_mailbox *outbox,
4288                           struct mlx4_cmd_info *cmd_info)
4289{
4290        int err;
4291        u32 qpn = vhcr->in_modifier & 0xffffff;
4292        struct res_qp *rqp;
4293        u64 mac;
4294        unsigned port;
4295        u64 pri_addr_path_mask;
4296        struct mlx4_update_qp_context *cmd;
4297        int smac_index;
4298
4299        cmd = (struct mlx4_update_qp_context *)inbox->buf;
4300
4301        pri_addr_path_mask = be64_to_cpu(cmd->primary_addr_path_mask);
4302        if (cmd->qp_mask || cmd->secondary_addr_path_mask ||
4303            (pri_addr_path_mask & ~MLX4_UPD_QP_PATH_MASK_SUPPORTED))
4304                return -EPERM;
4305
4306        if ((pri_addr_path_mask &
4307             (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_SRC_CHECK_MC_LB)) &&
4308                !(dev->caps.flags2 &
4309                  MLX4_DEV_CAP_FLAG2_UPDATE_QP_SRC_CHECK_LB)) {
4310                mlx4_warn(dev, "Src check LB for slave %d isn't supported\n",
4311                          slave);
4312                return -EOPNOTSUPP;
4313        }
4314
4315        /* Just change the smac for the QP */
4316        err = get_res(dev, slave, qpn, RES_QP, &rqp);
4317        if (err) {
4318                mlx4_err(dev, "Updating qpn 0x%x for slave %d rejected\n", qpn, slave);
4319                return err;
4320        }
4321
4322        port = (rqp->sched_queue >> 6 & 1) + 1;
4323
4324        if (pri_addr_path_mask & (1ULL << MLX4_UPD_QP_PATH_MASK_MAC_INDEX)) {
4325                smac_index = cmd->qp_context.pri_path.grh_mylmc;
4326                err = mac_find_smac_ix_in_slave(dev, slave, port,
4327                                                smac_index, &mac);
4328
4329                if (err) {
4330                        mlx4_err(dev, "Failed to update qpn 0x%x, MAC is invalid. smac_ix: %d\n",
4331                                 qpn, smac_index);
4332                        goto err_mac;
4333                }
4334        }
4335
4336        err = mlx4_cmd(dev, inbox->dma,
4337                       vhcr->in_modifier, 0,
4338                       MLX4_CMD_UPDATE_QP, MLX4_CMD_TIME_CLASS_A,
4339                       MLX4_CMD_NATIVE);
4340        if (err) {
4341                mlx4_err(dev, "Failed to update qpn on qpn 0x%x, command failed\n", qpn);
4342                goto err_mac;
4343        }
4344
4345err_mac:
4346        put_res(dev, slave, qpn, RES_QP);
4347        return err;
4348}
4349
4350static u32 qp_attach_mbox_size(void *mbox)
4351{
4352        u32 size = sizeof(struct mlx4_net_trans_rule_hw_ctrl);
4353        struct _rule_hw  *rule_header;
4354
4355        rule_header = (struct _rule_hw *)(mbox + size);
4356
4357        while (rule_header->size) {
4358                size += rule_header->size * sizeof(u32);
4359                rule_header += 1;
4360        }
4361        return size;
4362}
4363
4364static int mlx4_do_mirror_rule(struct mlx4_dev *dev, struct res_fs_rule *fs_rule);
4365
4366int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
4367                                         struct mlx4_vhcr *vhcr,
4368                                         struct mlx4_cmd_mailbox *inbox,
4369                                         struct mlx4_cmd_mailbox *outbox,
4370                                         struct mlx4_cmd_info *cmd)
4371{
4372
4373        struct mlx4_priv *priv = mlx4_priv(dev);
4374        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
4375        struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC];
4376        int err;
4377        int qpn;
4378        struct res_qp *rqp;
4379        struct mlx4_net_trans_rule_hw_ctrl *ctrl;
4380        struct _rule_hw  *rule_header;
4381        int header_id;
4382        struct res_fs_rule *rrule;
4383        u32 mbox_size;
4384
4385        if (dev->caps.steering_mode !=
4386            MLX4_STEERING_MODE_DEVICE_MANAGED)
4387                return -EOPNOTSUPP;
4388
4389        ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf;
4390        err = mlx4_slave_convert_port(dev, slave, ctrl->port);
4391        if (err <= 0)
4392                return -EINVAL;
4393        ctrl->port = err;
4394        qpn = be32_to_cpu(ctrl->qpn) & 0xffffff;
4395        err = get_res(dev, slave, qpn, RES_QP, &rqp);
4396        if (err) {
4397                pr_err("Steering rule with qpn 0x%x rejected\n", qpn);
4398                return err;
4399        }
4400        rule_header = (struct _rule_hw *)(ctrl + 1);
4401        header_id = map_hw_to_sw_id(be16_to_cpu(rule_header->id));
4402
4403        if (header_id == MLX4_NET_TRANS_RULE_ID_ETH)
4404                mlx4_handle_eth_header_mcast_prio(ctrl, rule_header);
4405
4406        switch (header_id) {
4407        case MLX4_NET_TRANS_RULE_ID_ETH:
4408                if (validate_eth_header_mac(slave, rule_header, rlist)) {
4409                        err = -EINVAL;
4410                        goto err_put_qp;
4411                }
4412                break;
4413        case MLX4_NET_TRANS_RULE_ID_IB:
4414                break;
4415        case MLX4_NET_TRANS_RULE_ID_IPV4:
4416        case MLX4_NET_TRANS_RULE_ID_TCP:
4417        case MLX4_NET_TRANS_RULE_ID_UDP:
4418                pr_warn("Can't attach FS rule without L2 headers, adding L2 header\n");
4419                if (add_eth_header(dev, slave, inbox, rlist, header_id)) {
4420                        err = -EINVAL;
4421                        goto err_put_qp;
4422                }
4423                vhcr->in_modifier +=
4424                        sizeof(struct mlx4_net_trans_rule_hw_eth) >> 2;
4425                break;
4426        default:
4427                pr_err("Corrupted mailbox\n");
4428                err = -EINVAL;
4429                goto err_put_qp;
4430        }
4431
4432        err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param,
4433                           vhcr->in_modifier, 0,
4434                           MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A,
4435                           MLX4_CMD_NATIVE);
4436        if (err)
4437                goto err_put_qp;
4438
4439
4440        err = add_res_range(dev, slave, vhcr->out_param, 1, RES_FS_RULE, qpn);
4441        if (err) {
4442                mlx4_err(dev, "Fail to add flow steering resources\n");
4443                goto err_detach;
4444        }
4445
4446        err = get_res(dev, slave, vhcr->out_param, RES_FS_RULE, &rrule);
4447        if (err)
4448                goto err_detach;
4449
4450        mbox_size = qp_attach_mbox_size(inbox->buf);
4451        rrule->mirr_mbox = kmalloc(mbox_size, GFP_KERNEL);
4452        if (!rrule->mirr_mbox) {
4453                err = -ENOMEM;
4454                goto err_put_rule;
4455        }
4456        rrule->mirr_mbox_size = mbox_size;
4457        rrule->mirr_rule_id = 0;
4458        memcpy(rrule->mirr_mbox, inbox->buf, mbox_size);
4459
4460        /* set different port */
4461        ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)rrule->mirr_mbox;
4462        if (ctrl->port == 1)
4463                ctrl->port = 2;
4464        else
4465                ctrl->port = 1;
4466
4467        if (mlx4_is_bonded(dev))
4468                mlx4_do_mirror_rule(dev, rrule);
4469
4470        atomic_inc(&rqp->ref_count);
4471
4472err_put_rule:
4473        put_res(dev, slave, vhcr->out_param, RES_FS_RULE);
4474err_detach:
4475        /* detach rule on error */
4476        if (err)
4477                mlx4_cmd(dev, vhcr->out_param, 0, 0,
4478                         MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
4479                         MLX4_CMD_NATIVE);
4480err_put_qp:
4481        put_res(dev, slave, qpn, RES_QP);
4482        return err;
4483}
4484
4485static int mlx4_undo_mirror_rule(struct mlx4_dev *dev, struct res_fs_rule *fs_rule)
4486{
4487        int err;
4488
4489        err = rem_res_range(dev, fs_rule->com.owner, fs_rule->com.res_id, 1, RES_FS_RULE, 0);
4490        if (err) {
4491                mlx4_err(dev, "Fail to remove flow steering resources\n");
4492                return err;
4493        }
4494
4495        mlx4_cmd(dev, fs_rule->com.res_id, 0, 0, MLX4_QP_FLOW_STEERING_DETACH,
4496                 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
4497        return 0;
4498}
4499
4500int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave,
4501                                         struct mlx4_vhcr *vhcr,
4502                                         struct mlx4_cmd_mailbox *inbox,
4503                                         struct mlx4_cmd_mailbox *outbox,
4504                                         struct mlx4_cmd_info *cmd)
4505{
4506        int err;
4507        struct res_qp *rqp;
4508        struct res_fs_rule *rrule;
4509        u64 mirr_reg_id;
4510        int qpn;
4511
4512        if (dev->caps.steering_mode !=
4513            MLX4_STEERING_MODE_DEVICE_MANAGED)
4514                return -EOPNOTSUPP;
4515
4516        err = get_res(dev, slave, vhcr->in_param, RES_FS_RULE, &rrule);
4517        if (err)
4518                return err;
4519
4520        if (!rrule->mirr_mbox) {
4521                mlx4_err(dev, "Mirror rules cannot be removed explicitly\n");
4522                put_res(dev, slave, vhcr->in_param, RES_FS_RULE);
4523                return -EINVAL;
4524        }
4525        mirr_reg_id = rrule->mirr_rule_id;
4526        kfree(rrule->mirr_mbox);
4527        qpn = rrule->qpn;
4528
4529        /* Release the rule form busy state before removal */
4530        put_res(dev, slave, vhcr->in_param, RES_FS_RULE);
4531        err = get_res(dev, slave, qpn, RES_QP, &rqp);
4532        if (err)
4533                return err;
4534
4535        if (mirr_reg_id && mlx4_is_bonded(dev)) {
4536                err = get_res(dev, slave, mirr_reg_id, RES_FS_RULE, &rrule);
4537                if (err) {
4538                        mlx4_err(dev, "Fail to get resource of mirror rule\n");
4539                } else {
4540                        put_res(dev, slave, mirr_reg_id, RES_FS_RULE);
4541                        mlx4_undo_mirror_rule(dev, rrule);
4542                }
4543        }
4544        err = rem_res_range(dev, slave, vhcr->in_param, 1, RES_FS_RULE, 0);
4545        if (err) {
4546                mlx4_err(dev, "Fail to remove flow steering resources\n");
4547                goto out;
4548        }
4549
4550        err = mlx4_cmd(dev, vhcr->in_param, 0, 0,
4551                       MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
4552                       MLX4_CMD_NATIVE);
4553        if (!err)
4554                atomic_dec(&rqp->ref_count);
4555out:
4556        put_res(dev, slave, qpn, RES_QP);
4557        return err;
4558}
4559
4560enum {
4561        BUSY_MAX_RETRIES = 10
4562};
4563
4564int mlx4_QUERY_IF_STAT_wrapper(struct mlx4_dev *dev, int slave,
4565                               struct mlx4_vhcr *vhcr,
4566                               struct mlx4_cmd_mailbox *inbox,
4567                               struct mlx4_cmd_mailbox *outbox,
4568                               struct mlx4_cmd_info *cmd)
4569{
4570        int err;
4571        int index = vhcr->in_modifier & 0xffff;
4572
4573        err = get_res(dev, slave, index, RES_COUNTER, NULL);
4574        if (err)
4575                return err;
4576
4577        err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
4578        put_res(dev, slave, index, RES_COUNTER);
4579        return err;
4580}
4581
4582static void detach_qp(struct mlx4_dev *dev, int slave, struct res_qp *rqp)
4583{
4584        struct res_gid *rgid;
4585        struct res_gid *tmp;
4586        struct mlx4_qp qp; /* dummy for calling attach/detach */
4587
4588        list_for_each_entry_safe(rgid, tmp, &rqp->mcg_list, list) {
4589                switch (dev->caps.steering_mode) {
4590                case MLX4_STEERING_MODE_DEVICE_MANAGED:
4591                        mlx4_flow_detach(dev, rgid->reg_id);
4592                        break;
4593                case MLX4_STEERING_MODE_B0:
4594                        qp.qpn = rqp->local_qpn;
4595                        (void) mlx4_qp_detach_common(dev, &qp, rgid->gid,
4596                                                     rgid->prot, rgid->steer);
4597                        break;
4598                }
4599                list_del(&rgid->list);
4600                kfree(rgid);
4601        }
4602}
4603
4604static int _move_all_busy(struct mlx4_dev *dev, int slave,
4605                          enum mlx4_resource type, int print)
4606{
4607        struct mlx4_priv *priv = mlx4_priv(dev);
4608        struct mlx4_resource_tracker *tracker =
4609                &priv->mfunc.master.res_tracker;
4610        struct list_head *rlist = &tracker->slave_list[slave].res_list[type];
4611        struct res_common *r;
4612        struct res_common *tmp;
4613        int busy;
4614
4615        busy = 0;
4616        spin_lock_irq(mlx4_tlock(dev));
4617        list_for_each_entry_safe(r, tmp, rlist, list) {
4618                if (r->owner == slave) {
4619                        if (!r->removing) {
4620                                if (r->state == RES_ANY_BUSY) {
4621                                        if (print)
4622                                                mlx4_dbg(dev,
4623                                                         "%s id 0x%llx is busy\n",
4624                                                          resource_str(type),
4625                                                          r->res_id);
4626                                        ++busy;
4627                                } else {
4628                                        r->from_state = r->state;
4629                                        r->state = RES_ANY_BUSY;
4630                                        r->removing = 1;
4631                                }
4632                        }
4633                }
4634        }
4635        spin_unlock_irq(mlx4_tlock(dev));
4636
4637        return busy;
4638}
4639
4640static int move_all_busy(struct mlx4_dev *dev, int slave,
4641                         enum mlx4_resource type)
4642{
4643        unsigned long begin;
4644        int busy;
4645
4646        begin = jiffies;
4647        do {
4648                busy = _move_all_busy(dev, slave, type, 0);
4649                if (time_after(jiffies, begin + 5 * HZ))
4650                        break;
4651                if (busy)
4652                        cond_resched();
4653        } while (busy);
4654
4655        if (busy)
4656                busy = _move_all_busy(dev, slave, type, 1);
4657
4658        return busy;
4659}
4660static void rem_slave_qps(struct mlx4_dev *dev, int slave)
4661{
4662        struct mlx4_priv *priv = mlx4_priv(dev);
4663        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
4664        struct list_head *qp_list =
4665                &tracker->slave_list[slave].res_list[RES_QP];
4666        struct res_qp *qp;
4667        struct res_qp *tmp;
4668        int state;
4669        u64 in_param;
4670        int qpn;
4671        int err;
4672
4673        err = move_all_busy(dev, slave, RES_QP);
4674        if (err)
4675                mlx4_warn(dev, "rem_slave_qps: Could not move all qps to busy for slave %d\n",
4676                          slave);
4677
4678        spin_lock_irq(mlx4_tlock(dev));
4679        list_for_each_entry_safe(qp, tmp, qp_list, com.list) {
4680                spin_unlock_irq(mlx4_tlock(dev));
4681                if (qp->com.owner == slave) {
4682                        qpn = qp->com.res_id;
4683                        detach_qp(dev, slave, qp);
4684                        state = qp->com.from_state;
4685                        while (state != 0) {
4686                                switch (state) {
4687                                case RES_QP_RESERVED:
4688                                        spin_lock_irq(mlx4_tlock(dev));
4689                                        rb_erase(&qp->com.node,
4690                                                 &tracker->res_tree[RES_QP]);
4691                                        list_del(&qp->com.list);
4692                                        spin_unlock_irq(mlx4_tlock(dev));
4693                                        if (!valid_reserved(dev, slave, qpn)) {
4694                                                __mlx4_qp_release_range(dev, qpn, 1);
4695                                                mlx4_release_resource(dev, slave,
4696                                                                      RES_QP, 1, 0);
4697                                        }
4698                                        kfree(qp);
4699                                        state = 0;
4700                                        break;
4701                                case RES_QP_MAPPED:
4702                                        if (!valid_reserved(dev, slave, qpn))
4703                                                __mlx4_qp_free_icm(dev, qpn);
4704                                        state = RES_QP_RESERVED;
4705                                        break;
4706                                case RES_QP_HW:
4707                                        in_param = slave;
4708                                        err = mlx4_cmd(dev, in_param,
4709                                                       qp->local_qpn, 2,
4710                                                       MLX4_CMD_2RST_QP,
4711                                                       MLX4_CMD_TIME_CLASS_A,
4712                                                       MLX4_CMD_NATIVE);
4713                                        if (err)
4714                                                mlx4_dbg(dev, "rem_slave_qps: failed to move slave %d qpn %d to reset\n",
4715                                                         slave, qp->local_qpn);
4716                                        atomic_dec(&qp->rcq->ref_count);
4717                                        atomic_dec(&qp->scq->ref_count);
4718                                        atomic_dec(&qp->mtt->ref_count);
4719                                        if (qp->srq)
4720                                                atomic_dec(&qp->srq->ref_count);
4721                                        state = RES_QP_MAPPED;
4722                                        break;
4723                                default:
4724                                        state = 0;
4725                                }
4726                        }
4727                }
4728                spin_lock_irq(mlx4_tlock(dev));
4729        }
4730        spin_unlock_irq(mlx4_tlock(dev));
4731}
4732
4733static void rem_slave_srqs(struct mlx4_dev *dev, int slave)
4734{
4735        struct mlx4_priv *priv = mlx4_priv(dev);
4736        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
4737        struct list_head *srq_list =
4738                &tracker->slave_list[slave].res_list[RES_SRQ];
4739        struct res_srq *srq;
4740        struct res_srq *tmp;
4741        int state;
4742        u64 in_param;
4743        int srqn;
4744        int err;
4745
4746        err = move_all_busy(dev, slave, RES_SRQ);
4747        if (err)
4748                mlx4_warn(dev, "rem_slave_srqs: Could not move all srqs - too busy for slave %d\n",
4749                          slave);
4750
4751        spin_lock_irq(mlx4_tlock(dev));
4752        list_for_each_entry_safe(srq, tmp, srq_list, com.list) {
4753                spin_unlock_irq(mlx4_tlock(dev));
4754                if (srq->com.owner == slave) {
4755                        srqn = srq->com.res_id;
4756                        state = srq->com.from_state;
4757                        while (state != 0) {
4758                                switch (state) {
4759                                case RES_SRQ_ALLOCATED:
4760                                        __mlx4_srq_free_icm(dev, srqn);
4761                                        spin_lock_irq(mlx4_tlock(dev));
4762                                        rb_erase(&srq->com.node,
4763                                                 &tracker->res_tree[RES_SRQ]);
4764                                        list_del(&srq->com.list);
4765                                        spin_unlock_irq(mlx4_tlock(dev));
4766                                        mlx4_release_resource(dev, slave,
4767                                                              RES_SRQ, 1, 0);
4768                                        kfree(srq);
4769                                        state = 0;
4770                                        break;
4771
4772                                case RES_SRQ_HW:
4773                                        in_param = slave;
4774                                        err = mlx4_cmd(dev, in_param, srqn, 1,
4775                                                       MLX4_CMD_HW2SW_SRQ,
4776                                                       MLX4_CMD_TIME_CLASS_A,
4777                                                       MLX4_CMD_NATIVE);
4778                                        if (err)
4779                                                mlx4_dbg(dev, "rem_slave_srqs: failed to move slave %d srq %d to SW ownership\n",
4780                                                         slave, srqn);
4781
4782                                        atomic_dec(&srq->mtt->ref_count);
4783                                        if (srq->cq)
4784                                                atomic_dec(&srq->cq->ref_count);
4785                                        state = RES_SRQ_ALLOCATED;
4786                                        break;
4787
4788                                default:
4789                                        state = 0;
4790                                }
4791                        }
4792                }
4793                spin_lock_irq(mlx4_tlock(dev));
4794        }
4795        spin_unlock_irq(mlx4_tlock(dev));
4796}
4797
4798static void rem_slave_cqs(struct mlx4_dev *dev, int slave)
4799{
4800        struct mlx4_priv *priv = mlx4_priv(dev);
4801        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
4802        struct list_head *cq_list =
4803                &tracker->slave_list[slave].res_list[RES_CQ];
4804        struct res_cq *cq;
4805        struct res_cq *tmp;
4806        int state;
4807        u64 in_param;
4808        int cqn;
4809        int err;
4810
4811        err = move_all_busy(dev, slave, RES_CQ);
4812        if (err)
4813                mlx4_warn(dev, "rem_slave_cqs: Could not move all cqs - too busy for slave %d\n",
4814                          slave);
4815
4816        spin_lock_irq(mlx4_tlock(dev));
4817        list_for_each_entry_safe(cq, tmp, cq_list, com.list) {
4818                spin_unlock_irq(mlx4_tlock(dev));
4819                if (cq->com.owner == slave && !atomic_read(&cq->ref_count)) {
4820                        cqn = cq->com.res_id;
4821                        state = cq->com.from_state;
4822                        while (state != 0) {
4823                                switch (state) {
4824                                case RES_CQ_ALLOCATED:
4825                                        __mlx4_cq_free_icm(dev, cqn);
4826                                        spin_lock_irq(mlx4_tlock(dev));
4827                                        rb_erase(&cq->com.node,
4828                                                 &tracker->res_tree[RES_CQ]);
4829                                        list_del(&cq->com.list);
4830                                        spin_unlock_irq(mlx4_tlock(dev));
4831                                        mlx4_release_resource(dev, slave,
4832                                                              RES_CQ, 1, 0);
4833                                        kfree(cq);
4834                                        state = 0;
4835                                        break;
4836
4837                                case RES_CQ_HW:
4838                                        in_param = slave;
4839                                        err = mlx4_cmd(dev, in_param, cqn, 1,
4840                                                       MLX4_CMD_HW2SW_CQ,
4841                                                       MLX4_CMD_TIME_CLASS_A,
4842                                                       MLX4_CMD_NATIVE);
4843                                        if (err)
4844                                                mlx4_dbg(dev, "rem_slave_cqs: failed to move slave %d cq %d to SW ownership\n",
4845                                                         slave, cqn);
4846                                        atomic_dec(&cq->mtt->ref_count);
4847                                        state = RES_CQ_ALLOCATED;
4848                                        break;
4849
4850                                default:
4851                                        state = 0;
4852                                }
4853                        }
4854                }
4855                spin_lock_irq(mlx4_tlock(dev));
4856        }
4857        spin_unlock_irq(mlx4_tlock(dev));
4858}
4859
4860static void rem_slave_mrs(struct mlx4_dev *dev, int slave)
4861{
4862        struct mlx4_priv *priv = mlx4_priv(dev);
4863        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
4864        struct list_head *mpt_list =
4865                &tracker->slave_list[slave].res_list[RES_MPT];
4866        struct res_mpt *mpt;
4867        struct res_mpt *tmp;
4868        int state;
4869        u64 in_param;
4870        int mptn;
4871        int err;
4872
4873        err = move_all_busy(dev, slave, RES_MPT);
4874        if (err)
4875                mlx4_warn(dev, "rem_slave_mrs: Could not move all mpts - too busy for slave %d\n",
4876                          slave);
4877
4878        spin_lock_irq(mlx4_tlock(dev));
4879        list_for_each_entry_safe(mpt, tmp, mpt_list, com.list) {
4880                spin_unlock_irq(mlx4_tlock(dev));
4881                if (mpt->com.owner == slave) {
4882                        mptn = mpt->com.res_id;
4883                        state = mpt->com.from_state;
4884                        while (state != 0) {
4885                                switch (state) {
4886                                case RES_MPT_RESERVED:
4887                                        __mlx4_mpt_release(dev, mpt->key);
4888                                        spin_lock_irq(mlx4_tlock(dev));
4889                                        rb_erase(&mpt->com.node,
4890                                                 &tracker->res_tree[RES_MPT]);
4891                                        list_del(&mpt->com.list);
4892                                        spin_unlock_irq(mlx4_tlock(dev));
4893                                        mlx4_release_resource(dev, slave,
4894                                                              RES_MPT, 1, 0);
4895                                        kfree(mpt);
4896                                        state = 0;
4897                                        break;
4898
4899                                case RES_MPT_MAPPED:
4900                                        __mlx4_mpt_free_icm(dev, mpt->key);
4901                                        state = RES_MPT_RESERVED;
4902                                        break;
4903
4904                                case RES_MPT_HW:
4905                                        in_param = slave;
4906                                        err = mlx4_cmd(dev, in_param, mptn, 0,
4907                                                     MLX4_CMD_HW2SW_MPT,
4908                                                     MLX4_CMD_TIME_CLASS_A,
4909                                                     MLX4_CMD_NATIVE);
4910                                        if (err)
4911                                                mlx4_dbg(dev, "rem_slave_mrs: failed to move slave %d mpt %d to SW ownership\n",
4912                                                         slave, mptn);
4913                                        if (mpt->mtt)
4914                                                atomic_dec(&mpt->mtt->ref_count);
4915                                        state = RES_MPT_MAPPED;
4916                                        break;
4917                                default:
4918                                        state = 0;
4919                                }
4920                        }
4921                }
4922                spin_lock_irq(mlx4_tlock(dev));
4923        }
4924        spin_unlock_irq(mlx4_tlock(dev));
4925}
4926
4927static void rem_slave_mtts(struct mlx4_dev *dev, int slave)
4928{
4929        struct mlx4_priv *priv = mlx4_priv(dev);
4930        struct mlx4_resource_tracker *tracker =
4931                &priv->mfunc.master.res_tracker;
4932        struct list_head *mtt_list =
4933                &tracker->slave_list[slave].res_list[RES_MTT];
4934        struct res_mtt *mtt;
4935        struct res_mtt *tmp;
4936        int state;
4937        int base;
4938        int err;
4939
4940        err = move_all_busy(dev, slave, RES_MTT);
4941        if (err)
4942                mlx4_warn(dev, "rem_slave_mtts: Could not move all mtts  - too busy for slave %d\n",
4943                          slave);
4944
4945        spin_lock_irq(mlx4_tlock(dev));
4946        list_for_each_entry_safe(mtt, tmp, mtt_list, com.list) {
4947                spin_unlock_irq(mlx4_tlock(dev));
4948                if (mtt->com.owner == slave) {
4949                        base = mtt->com.res_id;
4950                        state = mtt->com.from_state;
4951                        while (state != 0) {
4952                                switch (state) {
4953                                case RES_MTT_ALLOCATED:
4954                                        __mlx4_free_mtt_range(dev, base,
4955                                                              mtt->order);
4956                                        spin_lock_irq(mlx4_tlock(dev));
4957                                        rb_erase(&mtt->com.node,
4958                                                 &tracker->res_tree[RES_MTT]);
4959                                        list_del(&mtt->com.list);
4960                                        spin_unlock_irq(mlx4_tlock(dev));
4961                                        mlx4_release_resource(dev, slave, RES_MTT,
4962                                                              1 << mtt->order, 0);
4963                                        kfree(mtt);
4964                                        state = 0;
4965                                        break;
4966
4967                                default:
4968                                        state = 0;
4969                                }
4970                        }
4971                }
4972                spin_lock_irq(mlx4_tlock(dev));
4973        }
4974        spin_unlock_irq(mlx4_tlock(dev));
4975}
4976
4977static int mlx4_do_mirror_rule(struct mlx4_dev *dev, struct res_fs_rule *fs_rule)
4978{
4979        struct mlx4_cmd_mailbox *mailbox;
4980        int err;
4981        struct res_fs_rule *mirr_rule;
4982        u64 reg_id;
4983
4984        mailbox = mlx4_alloc_cmd_mailbox(dev);
4985        if (IS_ERR(mailbox))
4986                return PTR_ERR(mailbox);
4987
4988        if (!fs_rule->mirr_mbox) {
4989                mlx4_err(dev, "rule mirroring mailbox is null\n");
4990                mlx4_free_cmd_mailbox(dev, mailbox);
4991                return -EINVAL;
4992        }
4993        memcpy(mailbox->buf, fs_rule->mirr_mbox, fs_rule->mirr_mbox_size);
4994        err = mlx4_cmd_imm(dev, mailbox->dma, &reg_id, fs_rule->mirr_mbox_size >> 2, 0,
4995                           MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A,
4996                           MLX4_CMD_NATIVE);
4997        mlx4_free_cmd_mailbox(dev, mailbox);
4998
4999        if (err)
5000                goto err;
5001
5002        err = add_res_range(dev, fs_rule->com.owner, reg_id, 1, RES_FS_RULE, fs_rule->qpn);
5003        if (err)
5004                goto err_detach;
5005
5006        err = get_res(dev, fs_rule->com.owner, reg_id, RES_FS_RULE, &mirr_rule);
5007        if (err)
5008                goto err_rem;
5009
5010        fs_rule->mirr_rule_id = reg_id;
5011        mirr_rule->mirr_rule_id = 0;
5012        mirr_rule->mirr_mbox_size = 0;
5013        mirr_rule->mirr_mbox = NULL;
5014        put_res(dev, fs_rule->com.owner, reg_id, RES_FS_RULE);
5015
5016        return 0;
5017err_rem:
5018        rem_res_range(dev, fs_rule->com.owner, reg_id, 1, RES_FS_RULE, 0);
5019err_detach:
5020        mlx4_cmd(dev, reg_id, 0, 0, MLX4_QP_FLOW_STEERING_DETACH,
5021                 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
5022err:
5023        return err;
5024}
5025
5026static int mlx4_mirror_fs_rules(struct mlx4_dev *dev, bool bond)
5027{
5028        struct mlx4_priv *priv = mlx4_priv(dev);
5029        struct mlx4_resource_tracker *tracker =
5030                &priv->mfunc.master.res_tracker;
5031        struct rb_root *root = &tracker->res_tree[RES_FS_RULE];
5032        struct rb_node *p;
5033        struct res_fs_rule *fs_rule;
5034        int err = 0;
5035        LIST_HEAD(mirr_list);
5036
5037        for (p = rb_first(root); p; p = rb_next(p)) {
5038                fs_rule = rb_entry(p, struct res_fs_rule, com.node);
5039                if ((bond && fs_rule->mirr_mbox_size) ||
5040                    (!bond && !fs_rule->mirr_mbox_size))
5041                        list_add_tail(&fs_rule->mirr_list, &mirr_list);
5042        }
5043
5044        list_for_each_entry(fs_rule, &mirr_list, mirr_list) {
5045                if (bond)
5046                        err += mlx4_do_mirror_rule(dev, fs_rule);
5047                else
5048                        err += mlx4_undo_mirror_rule(dev, fs_rule);
5049        }
5050        return err;
5051}
5052
5053int mlx4_bond_fs_rules(struct mlx4_dev *dev)
5054{
5055        return mlx4_mirror_fs_rules(dev, true);
5056}
5057
5058int mlx4_unbond_fs_rules(struct mlx4_dev *dev)
5059{
5060        return mlx4_mirror_fs_rules(dev, false);
5061}
5062
5063static void rem_slave_fs_rule(struct mlx4_dev *dev, int slave)
5064{
5065        struct mlx4_priv *priv = mlx4_priv(dev);
5066        struct mlx4_resource_tracker *tracker =
5067                &priv->mfunc.master.res_tracker;
5068        struct list_head *fs_rule_list =
5069                &tracker->slave_list[slave].res_list[RES_FS_RULE];
5070        struct res_fs_rule *fs_rule;
5071        struct res_fs_rule *tmp;
5072        int state;
5073        u64 base;
5074        int err;
5075
5076        err = move_all_busy(dev, slave, RES_FS_RULE);
5077        if (err)
5078                mlx4_warn(dev, "rem_slave_fs_rule: Could not move all mtts to busy for slave %d\n",
5079                          slave);
5080
5081        spin_lock_irq(mlx4_tlock(dev));
5082        list_for_each_entry_safe(fs_rule, tmp, fs_rule_list, com.list) {
5083                spin_unlock_irq(mlx4_tlock(dev));
5084                if (fs_rule->com.owner == slave) {
5085                        base = fs_rule->com.res_id;
5086                        state = fs_rule->com.from_state;
5087                        while (state != 0) {
5088                                switch (state) {
5089                                case RES_FS_RULE_ALLOCATED:
5090                                        /* detach rule */
5091                                        err = mlx4_cmd(dev, base, 0, 0,
5092                                                       MLX4_QP_FLOW_STEERING_DETACH,
5093                                                       MLX4_CMD_TIME_CLASS_A,
5094                                                       MLX4_CMD_NATIVE);
5095
5096                                        spin_lock_irq(mlx4_tlock(dev));
5097                                        rb_erase(&fs_rule->com.node,
5098                                                 &tracker->res_tree[RES_FS_RULE]);
5099                                        list_del(&fs_rule->com.list);
5100                                        spin_unlock_irq(mlx4_tlock(dev));
5101                                        kfree(fs_rule->mirr_mbox);
5102                                        kfree(fs_rule);
5103                                        state = 0;
5104                                        break;
5105
5106                                default:
5107                                        state = 0;
5108                                }
5109                        }
5110                }
5111                spin_lock_irq(mlx4_tlock(dev));
5112        }
5113        spin_unlock_irq(mlx4_tlock(dev));
5114}
5115
5116static void rem_slave_eqs(struct mlx4_dev *dev, int slave)
5117{
5118        struct mlx4_priv *priv = mlx4_priv(dev);
5119        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
5120        struct list_head *eq_list =
5121                &tracker->slave_list[slave].res_list[RES_EQ];
5122        struct res_eq *eq;
5123        struct res_eq *tmp;
5124        int err;
5125        int state;
5126        int eqn;
5127
5128        err = move_all_busy(dev, slave, RES_EQ);
5129        if (err)
5130                mlx4_warn(dev, "rem_slave_eqs: Could not move all eqs - too busy for slave %d\n",
5131                          slave);
5132
5133        spin_lock_irq(mlx4_tlock(dev));
5134        list_for_each_entry_safe(eq, tmp, eq_list, com.list) {
5135                spin_unlock_irq(mlx4_tlock(dev));
5136                if (eq->com.owner == slave) {
5137                        eqn = eq->com.res_id;
5138                        state = eq->com.from_state;
5139                        while (state != 0) {
5140                                switch (state) {
5141                                case RES_EQ_RESERVED:
5142                                        spin_lock_irq(mlx4_tlock(dev));
5143                                        rb_erase(&eq->com.node,
5144                                                 &tracker->res_tree[RES_EQ]);
5145                                        list_del(&eq->com.list);
5146                                        spin_unlock_irq(mlx4_tlock(dev));
5147                                        kfree(eq);
5148                                        state = 0;
5149                                        break;
5150
5151                                case RES_EQ_HW:
5152                                        err = mlx4_cmd(dev, slave, eqn & 0x3ff,
5153                                                       1, MLX4_CMD_HW2SW_EQ,
5154                                                       MLX4_CMD_TIME_CLASS_A,
5155                                                       MLX4_CMD_NATIVE);
5156                                        if (err)
5157                                                mlx4_dbg(dev, "rem_slave_eqs: failed to move slave %d eqs %d to SW ownership\n",
5158                                                         slave, eqn & 0x3ff);
5159                                        atomic_dec(&eq->mtt->ref_count);
5160                                        state = RES_EQ_RESERVED;
5161                                        break;
5162
5163                                default:
5164                                        state = 0;
5165                                }
5166                        }
5167                }
5168                spin_lock_irq(mlx4_tlock(dev));
5169        }
5170        spin_unlock_irq(mlx4_tlock(dev));
5171}
5172
5173static void rem_slave_counters(struct mlx4_dev *dev, int slave)
5174{
5175        struct mlx4_priv *priv = mlx4_priv(dev);
5176        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
5177        struct list_head *counter_list =
5178                &tracker->slave_list[slave].res_list[RES_COUNTER];
5179        struct res_counter *counter;
5180        struct res_counter *tmp;
5181        int err;
5182        int *counters_arr = NULL;
5183        int i, j;
5184
5185        err = move_all_busy(dev, slave, RES_COUNTER);
5186        if (err)
5187                mlx4_warn(dev, "rem_slave_counters: Could not move all counters - too busy for slave %d\n",
5188                          slave);
5189
5190        counters_arr = kmalloc_array(dev->caps.max_counters,
5191                                     sizeof(*counters_arr), GFP_KERNEL);
5192        if (!counters_arr)
5193                return;
5194
5195        do {
5196                i = 0;
5197                j = 0;
5198                spin_lock_irq(mlx4_tlock(dev));
5199                list_for_each_entry_safe(counter, tmp, counter_list, com.list) {
5200                        if (counter->com.owner == slave) {
5201                                counters_arr[i++] = counter->com.res_id;
5202                                rb_erase(&counter->com.node,
5203                                         &tracker->res_tree[RES_COUNTER]);
5204                                list_del(&counter->com.list);
5205                                kfree(counter);
5206                        }
5207                }
5208                spin_unlock_irq(mlx4_tlock(dev));
5209
5210                while (j < i) {
5211                        __mlx4_counter_free(dev, counters_arr[j++]);
5212                        mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
5213                }
5214        } while (i);
5215
5216        kfree(counters_arr);
5217}
5218
5219static void rem_slave_xrcdns(struct mlx4_dev *dev, int slave)
5220{
5221        struct mlx4_priv *priv = mlx4_priv(dev);
5222        struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
5223        struct list_head *xrcdn_list =
5224                &tracker->slave_list[slave].res_list[RES_XRCD];
5225        struct res_xrcdn *xrcd;
5226        struct res_xrcdn *tmp;
5227        int err;
5228        int xrcdn;
5229
5230        err = move_all_busy(dev, slave, RES_XRCD);
5231        if (err)
5232                mlx4_warn(dev, "rem_slave_xrcdns: Could not move all xrcdns - too busy for slave %d\n",
5233                          slave);
5234
5235        spin_lock_irq(mlx4_tlock(dev));
5236        list_for_each_entry_safe(xrcd, tmp, xrcdn_list, com.list) {
5237                if (xrcd->com.owner == slave) {
5238                        xrcdn = xrcd->com.res_id;
5239                        rb_erase(&xrcd->com.node, &tracker->res_tree[RES_XRCD]);
5240                        list_del(&xrcd->com.list);
5241                        kfree(xrcd);
5242                        __mlx4_xrcd_free(dev, xrcdn);
5243                }
5244        }
5245        spin_unlock_irq(mlx4_tlock(dev));
5246}
5247
5248void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave)
5249{
5250        struct mlx4_priv *priv = mlx4_priv(dev);
5251        mlx4_reset_roce_gids(dev, slave);
5252        mutex_lock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
5253        rem_slave_vlans(dev, slave);
5254        rem_slave_macs(dev, slave);
5255        rem_slave_fs_rule(dev, slave);
5256        rem_slave_qps(dev, slave);
5257        rem_slave_srqs(dev, slave);
5258        rem_slave_cqs(dev, slave);
5259        rem_slave_mrs(dev, slave);
5260        rem_slave_eqs(dev, slave);
5261        rem_slave_mtts(dev, slave);
5262        rem_slave_counters(dev, slave);
5263        rem_slave_xrcdns(dev, slave);
5264        mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
5265}
5266
5267static void update_qos_vpp(struct mlx4_update_qp_context *ctx,
5268                           struct mlx4_vf_immed_vlan_work *work)
5269{
5270        ctx->qp_mask |= cpu_to_be64(1ULL << MLX4_UPD_QP_MASK_QOS_VPP);
5271        ctx->qp_context.qos_vport = work->qos_vport;
5272}
5273
5274void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work)
5275{
5276        struct mlx4_vf_immed_vlan_work *work =
5277                container_of(_work, struct mlx4_vf_immed_vlan_work, work);
5278        struct mlx4_cmd_mailbox *mailbox;
5279        struct mlx4_update_qp_context *upd_context;
5280        struct mlx4_dev *dev = &work->priv->dev;
5281        struct mlx4_resource_tracker *tracker =
5282                &work->priv->mfunc.master.res_tracker;
5283        struct list_head *qp_list =
5284                &tracker->slave_list[work->slave].res_list[RES_QP];
5285        struct res_qp *qp;
5286        struct res_qp *tmp;
5287        u64 qp_path_mask_vlan_ctrl =
5288                       ((1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_UNTAGGED) |
5289                       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_1P) |
5290                       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_TX_BLOCK_TAGGED) |
5291                       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_UNTAGGED) |
5292                       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_1P) |
5293                       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_RX_BLOCK_TAGGED));
5294
5295        u64 qp_path_mask = ((1ULL << MLX4_UPD_QP_PATH_MASK_VLAN_INDEX) |
5296                       (1ULL << MLX4_UPD_QP_PATH_MASK_FVL) |
5297                       (1ULL << MLX4_UPD_QP_PATH_MASK_CV) |
5298                       (1ULL << MLX4_UPD_QP_PATH_MASK_SV) |
5299                       (1ULL << MLX4_UPD_QP_PATH_MASK_ETH_HIDE_CQE_VLAN) |
5300                       (1ULL << MLX4_UPD_QP_PATH_MASK_FEUP) |
5301                       (1ULL << MLX4_UPD_QP_PATH_MASK_FVL_RX) |
5302                       (1ULL << MLX4_UPD_QP_PATH_MASK_SCHED_QUEUE));
5303
5304        int err;
5305        int port, errors = 0;
5306        u8 vlan_control;
5307
5308        if (mlx4_is_slave(dev)) {
5309                mlx4_warn(dev, "Trying to update-qp in slave %d\n",
5310                          work->slave);
5311                goto out;
5312        }
5313
5314        mailbox = mlx4_alloc_cmd_mailbox(dev);
5315        if (IS_ERR(mailbox))
5316                goto out;
5317        if (work->flags & MLX4_VF_IMMED_VLAN_FLAG_LINK_DISABLE) /* block all */
5318                vlan_control = MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
5319                        MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED |
5320                        MLX4_VLAN_CTRL_ETH_TX_BLOCK_UNTAGGED |
5321                        MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
5322                        MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED |
5323                        MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED;
5324        else if (!work->vlan_id)
5325                vlan_control = MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
5326                        MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED;
5327        else if (work->vlan_proto == htons(ETH_P_8021AD))
5328                vlan_control = MLX4_VLAN_CTRL_ETH_TX_BLOCK_PRIO_TAGGED |
5329                        MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
5330                        MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
5331                        MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED;
5332        else  /* vst 802.1Q */
5333                vlan_control = MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED |
5334                        MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED |
5335                        MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED;
5336
5337        upd_context = mailbox->buf;
5338        upd_context->qp_mask = cpu_to_be64(1ULL << MLX4_UPD_QP_MASK_VSD);
5339
5340        spin_lock_irq(mlx4_tlock(dev));
5341        list_for_each_entry_safe(qp, tmp, qp_list, com.list) {
5342                spin_unlock_irq(mlx4_tlock(dev));
5343                if (qp->com.owner == work->slave) {
5344                        if (qp->com.from_state != RES_QP_HW ||
5345                            !qp->sched_queue ||  /* no INIT2RTR trans yet */
5346                            mlx4_is_qp_reserved(dev, qp->local_qpn) ||
5347                            qp->qpc_flags & (1 << MLX4_RSS_QPC_FLAG_OFFSET)) {
5348                                spin_lock_irq(mlx4_tlock(dev));
5349                                continue;
5350                        }
5351                        port = (qp->sched_queue >> 6 & 1) + 1;
5352                        if (port != work->port) {
5353                                spin_lock_irq(mlx4_tlock(dev));
5354                                continue;
5355                        }
5356                        if (MLX4_QP_ST_RC == ((qp->qpc_flags >> 16) & 0xff))
5357                                upd_context->primary_addr_path_mask = cpu_to_be64(qp_path_mask);
5358                        else
5359                                upd_context->primary_addr_path_mask =
5360                                        cpu_to_be64(qp_path_mask | qp_path_mask_vlan_ctrl);
5361                        if (work->vlan_id == MLX4_VGT) {
5362                                upd_context->qp_context.param3 = qp->param3;
5363                                upd_context->qp_context.pri_path.vlan_control = qp->vlan_control;
5364                                upd_context->qp_context.pri_path.fvl_rx = qp->fvl_rx;
5365                                upd_context->qp_context.pri_path.vlan_index = qp->vlan_index;
5366                                upd_context->qp_context.pri_path.fl = qp->pri_path_fl;
5367                                upd_context->qp_context.pri_path.feup = qp->feup;
5368                                upd_context->qp_context.pri_path.sched_queue =
5369                                        qp->sched_queue;
5370                        } else {
5371                                upd_context->qp_context.param3 = qp->param3 & ~cpu_to_be32(MLX4_STRIP_VLAN);
5372                                upd_context->qp_context.pri_path.vlan_control = vlan_control;
5373                                upd_context->qp_context.pri_path.vlan_index = work->vlan_ix;
5374                                upd_context->qp_context.pri_path.fvl_rx =
5375                                        qp->fvl_rx | MLX4_FVL_RX_FORCE_ETH_VLAN;
5376                                upd_context->qp_context.pri_path.fl =
5377                                        qp->pri_path_fl | MLX4_FL_ETH_HIDE_CQE_VLAN;
5378                                if (work->vlan_proto == htons(ETH_P_8021AD))
5379                                        upd_context->qp_context.pri_path.fl |= MLX4_FL_SV;
5380                                else
5381                                        upd_context->qp_context.pri_path.fl |= MLX4_FL_CV;
5382                                upd_context->qp_context.pri_path.feup =
5383                                        qp->feup | MLX4_FEUP_FORCE_ETH_UP | MLX4_FVL_FORCE_ETH_VLAN;
5384                                upd_context->qp_context.pri_path.sched_queue =
5385                                        qp->sched_queue & 0xC7;
5386                                upd_context->qp_context.pri_path.sched_queue |=
5387                                        ((work->qos & 0x7) << 3);
5388
5389                                if (dev->caps.flags2 &
5390                                    MLX4_DEV_CAP_FLAG2_QOS_VPP)
5391                                        update_qos_vpp(upd_context, work);
5392                        }
5393
5394                        err = mlx4_cmd(dev, mailbox->dma,
5395                                       qp->local_qpn & 0xffffff,
5396                                       0, MLX4_CMD_UPDATE_QP,
5397                                       MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE);
5398                        if (err) {
5399                                mlx4_info(dev, "UPDATE_QP failed for slave %d, port %d, qpn %d (%d)\n",
5400                                          work->slave, port, qp->local_qpn, err);
5401                                errors++;
5402                        }
5403                }
5404                spin_lock_irq(mlx4_tlock(dev));
5405        }
5406        spin_unlock_irq(mlx4_tlock(dev));
5407        mlx4_free_cmd_mailbox(dev, mailbox);
5408
5409        if (errors)
5410                mlx4_err(dev, "%d UPDATE_QP failures for slave %d, port %d\n",
5411                         errors, work->slave, work->port);
5412
5413        /* unregister previous vlan_id if needed and we had no errors
5414         * while updating the QPs
5415         */
5416        if (work->flags & MLX4_VF_IMMED_VLAN_FLAG_VLAN && !errors &&
5417            NO_INDX != work->orig_vlan_ix)
5418                __mlx4_unregister_vlan(&work->priv->dev, work->port,
5419                                       work->orig_vlan_id);
5420out:
5421        kfree(work);
5422        return;
5423}
5424