linux/drivers/net/ethernet/mellanox/mlx4/port.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
   3 *
   4 * This software is available to you under a choice of one of two
   5 * licenses.  You may choose to be licensed under the terms of the GNU
   6 * General Public License (GPL) Version 2, available from the file
   7 * COPYING in the main directory of this source tree, or the
   8 * OpenIB.org BSD license below:
   9 *
  10 *     Redistribution and use in source and binary forms, with or
  11 *     without modification, are permitted provided that the following
  12 *     conditions are met:
  13 *
  14 *      - Redistributions of source code must retain the above
  15 *        copyright notice, this list of conditions and the following
  16 *        disclaimer.
  17 *
  18 *      - Redistributions in binary form must reproduce the above
  19 *        copyright notice, this list of conditions and the following
  20 *        disclaimer in the documentation and/or other materials
  21 *        provided with the distribution.
  22 *
  23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30 * SOFTWARE.
  31 */
  32
  33#include <linux/errno.h>
  34#include <linux/if_ether.h>
  35#include <linux/export.h>
  36
  37#include <linux/mlx4/cmd.h>
  38
  39#include "mlx4.h"
  40
  41#define MLX4_MAC_VALID          (1ull << 63)
  42
  43#define MLX4_VLAN_VALID         (1u << 31)
  44#define MLX4_VLAN_MASK          0xfff
  45
  46#define MLX4_STATS_TRAFFIC_COUNTERS_MASK        0xfULL
  47#define MLX4_STATS_TRAFFIC_DROPS_MASK           0xc0ULL
  48#define MLX4_STATS_ERROR_COUNTERS_MASK          0x1ffc30ULL
  49#define MLX4_STATS_PORT_COUNTERS_MASK           0x1fe00000ULL
  50
  51void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table)
  52{
  53        int i;
  54
  55        mutex_init(&table->mutex);
  56        for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
  57                table->entries[i] = 0;
  58                table->refs[i]   = 0;
  59        }
  60        table->max   = 1 << dev->caps.log_num_macs;
  61        table->total = 0;
  62}
  63
  64void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table)
  65{
  66        int i;
  67
  68        mutex_init(&table->mutex);
  69        for (i = 0; i < MLX4_MAX_VLAN_NUM; i++) {
  70                table->entries[i] = 0;
  71                table->refs[i]   = 0;
  72        }
  73        table->max   = (1 << dev->caps.log_num_vlans) - MLX4_VLAN_REGULAR;
  74        table->total = 0;
  75}
  76
  77static int validate_index(struct mlx4_dev *dev,
  78                          struct mlx4_mac_table *table, int index)
  79{
  80        int err = 0;
  81
  82        if (index < 0 || index >= table->max || !table->entries[index]) {
  83                mlx4_warn(dev, "No valid Mac entry for the given index\n");
  84                err = -EINVAL;
  85        }
  86        return err;
  87}
  88
  89static int find_index(struct mlx4_dev *dev,
  90                      struct mlx4_mac_table *table, u64 mac)
  91{
  92        int i;
  93
  94        for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
  95                if ((mac & MLX4_MAC_MASK) ==
  96                    (MLX4_MAC_MASK & be64_to_cpu(table->entries[i])))
  97                        return i;
  98        }
  99        /* Mac not found */
 100        return -EINVAL;
 101}
 102
 103static int mlx4_set_port_mac_table(struct mlx4_dev *dev, u8 port,
 104                                   __be64 *entries)
 105{
 106        struct mlx4_cmd_mailbox *mailbox;
 107        u32 in_mod;
 108        int err;
 109
 110        mailbox = mlx4_alloc_cmd_mailbox(dev);
 111        if (IS_ERR(mailbox))
 112                return PTR_ERR(mailbox);
 113
 114        memcpy(mailbox->buf, entries, MLX4_MAC_TABLE_SIZE);
 115
 116        in_mod = MLX4_SET_PORT_MAC_TABLE << 8 | port;
 117
 118        err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
 119                       MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
 120
 121        mlx4_free_cmd_mailbox(dev, mailbox);
 122        return err;
 123}
 124
 125int __mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
 126{
 127        struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
 128        struct mlx4_mac_table *table = &info->mac_table;
 129        int i, err = 0;
 130        int free = -1;
 131
 132        mlx4_dbg(dev, "Registering MAC: 0x%llx for port %d\n",
 133                 (unsigned long long) mac, port);
 134
 135        mutex_lock(&table->mutex);
 136        for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
 137                if (free < 0 && !table->entries[i]) {
 138                        free = i;
 139                        continue;
 140                }
 141
 142                if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) {
 143                        /* MAC already registered, Must not have duplicates */
 144                        err = -EEXIST;
 145                        goto out;
 146                }
 147        }
 148
 149        mlx4_dbg(dev, "Free MAC index is %d\n", free);
 150
 151        if (table->total == table->max) {
 152                /* No free mac entries */
 153                err = -ENOSPC;
 154                goto out;
 155        }
 156
 157        /* Register new MAC */
 158        table->entries[free] = cpu_to_be64(mac | MLX4_MAC_VALID);
 159
 160        err = mlx4_set_port_mac_table(dev, port, table->entries);
 161        if (unlikely(err)) {
 162                mlx4_err(dev, "Failed adding MAC: 0x%llx\n",
 163                         (unsigned long long) mac);
 164                table->entries[free] = 0;
 165                goto out;
 166        }
 167
 168        err = free;
 169        ++table->total;
 170out:
 171        mutex_unlock(&table->mutex);
 172        return err;
 173}
 174EXPORT_SYMBOL_GPL(__mlx4_register_mac);
 175
 176int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
 177{
 178        u64 out_param = 0;
 179        int err;
 180
 181        if (mlx4_is_mfunc(dev)) {
 182                set_param_l(&out_param, port);
 183                err = mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
 184                                   RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
 185                                   MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
 186                if (err)
 187                        return err;
 188
 189                return get_param_l(&out_param);
 190        }
 191        return __mlx4_register_mac(dev, port, mac);
 192}
 193EXPORT_SYMBOL_GPL(mlx4_register_mac);
 194
 195int mlx4_get_base_qpn(struct mlx4_dev *dev, u8 port)
 196{
 197        return dev->caps.reserved_qps_base[MLX4_QP_REGION_ETH_ADDR] +
 198                        (port - 1) * (1 << dev->caps.log_num_macs);
 199}
 200EXPORT_SYMBOL_GPL(mlx4_get_base_qpn);
 201
 202void __mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
 203{
 204        struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
 205        struct mlx4_mac_table *table = &info->mac_table;
 206        int index;
 207
 208        index = find_index(dev, table, mac);
 209
 210        mutex_lock(&table->mutex);
 211
 212        if (validate_index(dev, table, index))
 213                goto out;
 214
 215        table->entries[index] = 0;
 216        mlx4_set_port_mac_table(dev, port, table->entries);
 217        --table->total;
 218out:
 219        mutex_unlock(&table->mutex);
 220}
 221EXPORT_SYMBOL_GPL(__mlx4_unregister_mac);
 222
 223void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
 224{
 225        u64 out_param = 0;
 226
 227        if (mlx4_is_mfunc(dev)) {
 228                set_param_l(&out_param, port);
 229                (void) mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
 230                                    RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES,
 231                                    MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
 232                return;
 233        }
 234        __mlx4_unregister_mac(dev, port, mac);
 235        return;
 236}
 237EXPORT_SYMBOL_GPL(mlx4_unregister_mac);
 238
 239int __mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac)
 240{
 241        struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
 242        struct mlx4_mac_table *table = &info->mac_table;
 243        int index = qpn - info->base_qpn;
 244        int err = 0;
 245
 246        /* CX1 doesn't support multi-functions */
 247        mutex_lock(&table->mutex);
 248
 249        err = validate_index(dev, table, index);
 250        if (err)
 251                goto out;
 252
 253        table->entries[index] = cpu_to_be64(new_mac | MLX4_MAC_VALID);
 254
 255        err = mlx4_set_port_mac_table(dev, port, table->entries);
 256        if (unlikely(err)) {
 257                mlx4_err(dev, "Failed adding MAC: 0x%llx\n",
 258                         (unsigned long long) new_mac);
 259                table->entries[index] = 0;
 260        }
 261out:
 262        mutex_unlock(&table->mutex);
 263        return err;
 264}
 265EXPORT_SYMBOL_GPL(__mlx4_replace_mac);
 266
 267static int mlx4_set_port_vlan_table(struct mlx4_dev *dev, u8 port,
 268                                    __be32 *entries)
 269{
 270        struct mlx4_cmd_mailbox *mailbox;
 271        u32 in_mod;
 272        int err;
 273
 274        mailbox = mlx4_alloc_cmd_mailbox(dev);
 275        if (IS_ERR(mailbox))
 276                return PTR_ERR(mailbox);
 277
 278        memcpy(mailbox->buf, entries, MLX4_VLAN_TABLE_SIZE);
 279        in_mod = MLX4_SET_PORT_VLAN_TABLE << 8 | port;
 280        err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
 281                       MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
 282
 283        mlx4_free_cmd_mailbox(dev, mailbox);
 284
 285        return err;
 286}
 287
 288int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx)
 289{
 290        struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
 291        int i;
 292
 293        for (i = 0; i < MLX4_MAX_VLAN_NUM; ++i) {
 294                if (table->refs[i] &&
 295                    (vid == (MLX4_VLAN_MASK &
 296                              be32_to_cpu(table->entries[i])))) {
 297                        /* VLAN already registered, increase reference count */
 298                        *idx = i;
 299                        return 0;
 300                }
 301        }
 302
 303        return -ENOENT;
 304}
 305EXPORT_SYMBOL_GPL(mlx4_find_cached_vlan);
 306
 307static int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan,
 308                                int *index)
 309{
 310        struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
 311        int i, err = 0;
 312        int free = -1;
 313
 314        mutex_lock(&table->mutex);
 315
 316        if (table->total == table->max) {
 317                /* No free vlan entries */
 318                err = -ENOSPC;
 319                goto out;
 320        }
 321
 322        for (i = MLX4_VLAN_REGULAR; i < MLX4_MAX_VLAN_NUM; i++) {
 323                if (free < 0 && (table->refs[i] == 0)) {
 324                        free = i;
 325                        continue;
 326                }
 327
 328                if (table->refs[i] &&
 329                    (vlan == (MLX4_VLAN_MASK &
 330                              be32_to_cpu(table->entries[i])))) {
 331                        /* Vlan already registered, increase references count */
 332                        *index = i;
 333                        ++table->refs[i];
 334                        goto out;
 335                }
 336        }
 337
 338        if (free < 0) {
 339                err = -ENOMEM;
 340                goto out;
 341        }
 342
 343        /* Register new VLAN */
 344        table->refs[free] = 1;
 345        table->entries[free] = cpu_to_be32(vlan | MLX4_VLAN_VALID);
 346
 347        err = mlx4_set_port_vlan_table(dev, port, table->entries);
 348        if (unlikely(err)) {
 349                mlx4_warn(dev, "Failed adding vlan: %u\n", vlan);
 350                table->refs[free] = 0;
 351                table->entries[free] = 0;
 352                goto out;
 353        }
 354
 355        *index = free;
 356        ++table->total;
 357out:
 358        mutex_unlock(&table->mutex);
 359        return err;
 360}
 361
 362int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
 363{
 364        u64 out_param = 0;
 365        int err;
 366
 367        if (mlx4_is_mfunc(dev)) {
 368                set_param_l(&out_param, port);
 369                err = mlx4_cmd_imm(dev, vlan, &out_param, RES_VLAN,
 370                                   RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES,
 371                                   MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
 372                if (!err)
 373                        *index = get_param_l(&out_param);
 374
 375                return err;
 376        }
 377        return __mlx4_register_vlan(dev, port, vlan, index);
 378}
 379EXPORT_SYMBOL_GPL(mlx4_register_vlan);
 380
 381static void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
 382{
 383        struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
 384
 385        if (index < MLX4_VLAN_REGULAR) {
 386                mlx4_warn(dev, "Trying to free special vlan index %d\n", index);
 387                return;
 388        }
 389
 390        mutex_lock(&table->mutex);
 391        if (!table->refs[index]) {
 392                mlx4_warn(dev, "No vlan entry for index %d\n", index);
 393                goto out;
 394        }
 395        if (--table->refs[index]) {
 396                mlx4_dbg(dev, "Have more references for index %d,"
 397                         "no need to modify vlan table\n", index);
 398                goto out;
 399        }
 400        table->entries[index] = 0;
 401        mlx4_set_port_vlan_table(dev, port, table->entries);
 402        --table->total;
 403out:
 404        mutex_unlock(&table->mutex);
 405}
 406
 407void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
 408{
 409        u64 in_param = 0;
 410        int err;
 411
 412        if (mlx4_is_mfunc(dev)) {
 413                set_param_l(&in_param, port);
 414                err = mlx4_cmd(dev, in_param, RES_VLAN, RES_OP_RESERVE_AND_MAP,
 415                               MLX4_CMD_FREE_RES, MLX4_CMD_TIME_CLASS_A,
 416                               MLX4_CMD_WRAPPED);
 417                if (!err)
 418                        mlx4_warn(dev, "Failed freeing vlan at index:%d\n",
 419                                        index);
 420
 421                return;
 422        }
 423        __mlx4_unregister_vlan(dev, port, index);
 424}
 425EXPORT_SYMBOL_GPL(mlx4_unregister_vlan);
 426
 427int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps)
 428{
 429        struct mlx4_cmd_mailbox *inmailbox, *outmailbox;
 430        u8 *inbuf, *outbuf;
 431        int err;
 432
 433        inmailbox = mlx4_alloc_cmd_mailbox(dev);
 434        if (IS_ERR(inmailbox))
 435                return PTR_ERR(inmailbox);
 436
 437        outmailbox = mlx4_alloc_cmd_mailbox(dev);
 438        if (IS_ERR(outmailbox)) {
 439                mlx4_free_cmd_mailbox(dev, inmailbox);
 440                return PTR_ERR(outmailbox);
 441        }
 442
 443        inbuf = inmailbox->buf;
 444        outbuf = outmailbox->buf;
 445        memset(inbuf, 0, 256);
 446        memset(outbuf, 0, 256);
 447        inbuf[0] = 1;
 448        inbuf[1] = 1;
 449        inbuf[2] = 1;
 450        inbuf[3] = 1;
 451        *(__be16 *) (&inbuf[16]) = cpu_to_be16(0x0015);
 452        *(__be32 *) (&inbuf[20]) = cpu_to_be32(port);
 453
 454        err = mlx4_cmd_box(dev, inmailbox->dma, outmailbox->dma, port, 3,
 455                           MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C,
 456                           MLX4_CMD_NATIVE);
 457        if (!err)
 458                *caps = *(__be32 *) (outbuf + 84);
 459        mlx4_free_cmd_mailbox(dev, inmailbox);
 460        mlx4_free_cmd_mailbox(dev, outmailbox);
 461        return err;
 462}
 463
 464static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod,
 465                                u8 op_mod, struct mlx4_cmd_mailbox *inbox)
 466{
 467        struct mlx4_priv *priv = mlx4_priv(dev);
 468        struct mlx4_port_info *port_info;
 469        struct mlx4_mfunc_master_ctx *master = &priv->mfunc.master;
 470        struct mlx4_slave_state *slave_st = &master->slave_state[slave];
 471        struct mlx4_set_port_rqp_calc_context *qpn_context;
 472        struct mlx4_set_port_general_context *gen_context;
 473        int reset_qkey_viols;
 474        int port;
 475        int is_eth;
 476        u32 in_modifier;
 477        u32 promisc;
 478        u16 mtu, prev_mtu;
 479        int err;
 480        int i;
 481        __be32 agg_cap_mask;
 482        __be32 slave_cap_mask;
 483        __be32 new_cap_mask;
 484
 485        port = in_mod & 0xff;
 486        in_modifier = in_mod >> 8;
 487        is_eth = op_mod;
 488        port_info = &priv->port[port];
 489
 490        /* Slaves cannot perform SET_PORT operations except changing MTU */
 491        if (is_eth) {
 492                if (slave != dev->caps.function &&
 493                    in_modifier != MLX4_SET_PORT_GENERAL) {
 494                        mlx4_warn(dev, "denying SET_PORT for slave:%d\n",
 495                                        slave);
 496                        return -EINVAL;
 497                }
 498                switch (in_modifier) {
 499                case MLX4_SET_PORT_RQP_CALC:
 500                        qpn_context = inbox->buf;
 501                        qpn_context->base_qpn =
 502                                cpu_to_be32(port_info->base_qpn);
 503                        qpn_context->n_mac = 0x7;
 504                        promisc = be32_to_cpu(qpn_context->promisc) >>
 505                                SET_PORT_PROMISC_SHIFT;
 506                        qpn_context->promisc = cpu_to_be32(
 507                                promisc << SET_PORT_PROMISC_SHIFT |
 508                                port_info->base_qpn);
 509                        promisc = be32_to_cpu(qpn_context->mcast) >>
 510                                SET_PORT_MC_PROMISC_SHIFT;
 511                        qpn_context->mcast = cpu_to_be32(
 512                                promisc << SET_PORT_MC_PROMISC_SHIFT |
 513                                port_info->base_qpn);
 514                        break;
 515                case MLX4_SET_PORT_GENERAL:
 516                        gen_context = inbox->buf;
 517                        /* Mtu is configured as the max MTU among all the
 518                         * the functions on the port. */
 519                        mtu = be16_to_cpu(gen_context->mtu);
 520                        mtu = min_t(int, mtu, dev->caps.eth_mtu_cap[port]);
 521                        prev_mtu = slave_st->mtu[port];
 522                        slave_st->mtu[port] = mtu;
 523                        if (mtu > master->max_mtu[port])
 524                                master->max_mtu[port] = mtu;
 525                        if (mtu < prev_mtu && prev_mtu ==
 526                                                master->max_mtu[port]) {
 527                                slave_st->mtu[port] = mtu;
 528                                master->max_mtu[port] = mtu;
 529                                for (i = 0; i < dev->num_slaves; i++) {
 530                                        master->max_mtu[port] =
 531                                        max(master->max_mtu[port],
 532                                            master->slave_state[i].mtu[port]);
 533                                }
 534                        }
 535
 536                        gen_context->mtu = cpu_to_be16(master->max_mtu[port]);
 537                        break;
 538                }
 539                return mlx4_cmd(dev, inbox->dma, in_mod, op_mod,
 540                                MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B,
 541                                MLX4_CMD_NATIVE);
 542        }
 543
 544        /* For IB, we only consider:
 545         * - The capability mask, which is set to the aggregate of all
 546         *   slave function capabilities
 547         * - The QKey violatin counter - reset according to each request.
 548         */
 549
 550        if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
 551                reset_qkey_viols = (*(u8 *) inbox->buf) & 0x40;
 552                new_cap_mask = ((__be32 *) inbox->buf)[2];
 553        } else {
 554                reset_qkey_viols = ((u8 *) inbox->buf)[3] & 0x1;
 555                new_cap_mask = ((__be32 *) inbox->buf)[1];
 556        }
 557
 558        /* slave may not set the IS_SM capability for the port */
 559        if (slave != mlx4_master_func_num(dev) &&
 560            (be32_to_cpu(new_cap_mask) & MLX4_PORT_CAP_IS_SM))
 561                return -EINVAL;
 562
 563        /* No DEV_MGMT in multifunc mode */
 564        if (mlx4_is_mfunc(dev) &&
 565            (be32_to_cpu(new_cap_mask) & MLX4_PORT_CAP_DEV_MGMT_SUP))
 566                return -EINVAL;
 567
 568        agg_cap_mask = 0;
 569        slave_cap_mask =
 570                priv->mfunc.master.slave_state[slave].ib_cap_mask[port];
 571        priv->mfunc.master.slave_state[slave].ib_cap_mask[port] = new_cap_mask;
 572        for (i = 0; i < dev->num_slaves; i++)
 573                agg_cap_mask |=
 574                        priv->mfunc.master.slave_state[i].ib_cap_mask[port];
 575
 576        /* only clear mailbox for guests.  Master may be setting
 577        * MTU or PKEY table size
 578        */
 579        if (slave != dev->caps.function)
 580                memset(inbox->buf, 0, 256);
 581        if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
 582                *(u8 *) inbox->buf         |= !!reset_qkey_viols << 6;
 583                ((__be32 *) inbox->buf)[2] = agg_cap_mask;
 584        } else {
 585                ((u8 *) inbox->buf)[3]     |= !!reset_qkey_viols;
 586                ((__be32 *) inbox->buf)[1] = agg_cap_mask;
 587        }
 588
 589        err = mlx4_cmd(dev, inbox->dma, port, is_eth, MLX4_CMD_SET_PORT,
 590                       MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
 591        if (err)
 592                priv->mfunc.master.slave_state[slave].ib_cap_mask[port] =
 593                        slave_cap_mask;
 594        return err;
 595}
 596
 597int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave,
 598                          struct mlx4_vhcr *vhcr,
 599                          struct mlx4_cmd_mailbox *inbox,
 600                          struct mlx4_cmd_mailbox *outbox,
 601                          struct mlx4_cmd_info *cmd)
 602{
 603        return mlx4_common_set_port(dev, slave, vhcr->in_modifier,
 604                                    vhcr->op_modifier, inbox);
 605}
 606
 607/* bit locations for set port command with zero op modifier */
 608enum {
 609        MLX4_SET_PORT_VL_CAP     = 4, /* bits 7:4 */
 610        MLX4_SET_PORT_MTU_CAP    = 12, /* bits 15:12 */
 611        MLX4_CHANGE_PORT_PKEY_TBL_SZ = 20,
 612        MLX4_CHANGE_PORT_VL_CAP  = 21,
 613        MLX4_CHANGE_PORT_MTU_CAP = 22,
 614};
 615
 616int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, int pkey_tbl_sz)
 617{
 618        struct mlx4_cmd_mailbox *mailbox;
 619        int err, vl_cap, pkey_tbl_flag = 0;
 620
 621        if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
 622                return 0;
 623
 624        mailbox = mlx4_alloc_cmd_mailbox(dev);
 625        if (IS_ERR(mailbox))
 626                return PTR_ERR(mailbox);
 627
 628        memset(mailbox->buf, 0, 256);
 629
 630        ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];
 631
 632        if (pkey_tbl_sz >= 0 && mlx4_is_master(dev)) {
 633                pkey_tbl_flag = 1;
 634                ((__be16 *) mailbox->buf)[20] = cpu_to_be16(pkey_tbl_sz);
 635        }
 636
 637        /* IB VL CAP enum isn't used by the firmware, just numerical values */
 638        for (vl_cap = 8; vl_cap >= 1; vl_cap >>= 1) {
 639                ((__be32 *) mailbox->buf)[0] = cpu_to_be32(
 640                        (1 << MLX4_CHANGE_PORT_MTU_CAP) |
 641                        (1 << MLX4_CHANGE_PORT_VL_CAP)  |
 642                        (pkey_tbl_flag << MLX4_CHANGE_PORT_PKEY_TBL_SZ) |
 643                        (dev->caps.port_ib_mtu[port] << MLX4_SET_PORT_MTU_CAP) |
 644                        (vl_cap << MLX4_SET_PORT_VL_CAP));
 645                err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT,
 646                                MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
 647                if (err != -ENOMEM)
 648                        break;
 649        }
 650
 651        mlx4_free_cmd_mailbox(dev, mailbox);
 652        return err;
 653}
 654
 655int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu,
 656                          u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx)
 657{
 658        struct mlx4_cmd_mailbox *mailbox;
 659        struct mlx4_set_port_general_context *context;
 660        int err;
 661        u32 in_mod;
 662
 663        mailbox = mlx4_alloc_cmd_mailbox(dev);
 664        if (IS_ERR(mailbox))
 665                return PTR_ERR(mailbox);
 666        context = mailbox->buf;
 667        memset(context, 0, sizeof *context);
 668
 669        context->flags = SET_PORT_GEN_ALL_VALID;
 670        context->mtu = cpu_to_be16(mtu);
 671        context->pptx = (pptx * (!pfctx)) << 7;
 672        context->pfctx = pfctx;
 673        context->pprx = (pprx * (!pfcrx)) << 7;
 674        context->pfcrx = pfcrx;
 675
 676        in_mod = MLX4_SET_PORT_GENERAL << 8 | port;
 677        err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
 678                       MLX4_CMD_TIME_CLASS_B,  MLX4_CMD_WRAPPED);
 679
 680        mlx4_free_cmd_mailbox(dev, mailbox);
 681        return err;
 682}
 683EXPORT_SYMBOL(mlx4_SET_PORT_general);
 684
 685int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
 686                           u8 promisc)
 687{
 688        struct mlx4_cmd_mailbox *mailbox;
 689        struct mlx4_set_port_rqp_calc_context *context;
 690        int err;
 691        u32 in_mod;
 692        u32 m_promisc = (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) ?
 693                MCAST_DIRECT : MCAST_DEFAULT;
 694
 695        if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0)
 696                return 0;
 697
 698        mailbox = mlx4_alloc_cmd_mailbox(dev);
 699        if (IS_ERR(mailbox))
 700                return PTR_ERR(mailbox);
 701        context = mailbox->buf;
 702        memset(context, 0, sizeof *context);
 703
 704        context->base_qpn = cpu_to_be32(base_qpn);
 705        context->n_mac = dev->caps.log_num_macs;
 706        context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT |
 707                                       base_qpn);
 708        context->mcast = cpu_to_be32(m_promisc << SET_PORT_MC_PROMISC_SHIFT |
 709                                     base_qpn);
 710        context->intra_no_vlan = 0;
 711        context->no_vlan = MLX4_NO_VLAN_IDX;
 712        context->intra_vlan_miss = 0;
 713        context->vlan_miss = MLX4_VLAN_MISS_IDX;
 714
 715        in_mod = MLX4_SET_PORT_RQP_CALC << 8 | port;
 716        err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
 717                       MLX4_CMD_TIME_CLASS_B,  MLX4_CMD_WRAPPED);
 718
 719        mlx4_free_cmd_mailbox(dev, mailbox);
 720        return err;
 721}
 722EXPORT_SYMBOL(mlx4_SET_PORT_qpn_calc);
 723
 724int mlx4_SET_PORT_PRIO2TC(struct mlx4_dev *dev, u8 port, u8 *prio2tc)
 725{
 726        struct mlx4_cmd_mailbox *mailbox;
 727        struct mlx4_set_port_prio2tc_context *context;
 728        int err;
 729        u32 in_mod;
 730        int i;
 731
 732        mailbox = mlx4_alloc_cmd_mailbox(dev);
 733        if (IS_ERR(mailbox))
 734                return PTR_ERR(mailbox);
 735        context = mailbox->buf;
 736        memset(context, 0, sizeof *context);
 737
 738        for (i = 0; i < MLX4_NUM_UP; i += 2)
 739                context->prio2tc[i >> 1] = prio2tc[i] << 4 | prio2tc[i + 1];
 740
 741        in_mod = MLX4_SET_PORT_PRIO2TC << 8 | port;
 742        err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
 743                       MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
 744
 745        mlx4_free_cmd_mailbox(dev, mailbox);
 746        return err;
 747}
 748EXPORT_SYMBOL(mlx4_SET_PORT_PRIO2TC);
 749
 750int mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw,
 751                u8 *pg, u16 *ratelimit)
 752{
 753        struct mlx4_cmd_mailbox *mailbox;
 754        struct mlx4_set_port_scheduler_context *context;
 755        int err;
 756        u32 in_mod;
 757        int i;
 758
 759        mailbox = mlx4_alloc_cmd_mailbox(dev);
 760        if (IS_ERR(mailbox))
 761                return PTR_ERR(mailbox);
 762        context = mailbox->buf;
 763        memset(context, 0, sizeof *context);
 764
 765        for (i = 0; i < MLX4_NUM_TC; i++) {
 766                struct mlx4_port_scheduler_tc_cfg_be *tc = &context->tc[i];
 767                u16 r = ratelimit && ratelimit[i] ? ratelimit[i] :
 768                        MLX4_RATELIMIT_DEFAULT;
 769
 770                tc->pg = htons(pg[i]);
 771                tc->bw_precentage = htons(tc_tx_bw[i]);
 772
 773                tc->max_bw_units = htons(MLX4_RATELIMIT_UNITS);
 774                tc->max_bw_value = htons(r);
 775        }
 776
 777        in_mod = MLX4_SET_PORT_SCHEDULER << 8 | port;
 778        err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
 779                       MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
 780
 781        mlx4_free_cmd_mailbox(dev, mailbox);
 782        return err;
 783}
 784EXPORT_SYMBOL(mlx4_SET_PORT_SCHEDULER);
 785
 786int mlx4_SET_MCAST_FLTR_wrapper(struct mlx4_dev *dev, int slave,
 787                                struct mlx4_vhcr *vhcr,
 788                                struct mlx4_cmd_mailbox *inbox,
 789                                struct mlx4_cmd_mailbox *outbox,
 790                                struct mlx4_cmd_info *cmd)
 791{
 792        int err = 0;
 793
 794        return err;
 795}
 796
 797int mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, u8 port,
 798                        u64 mac, u64 clear, u8 mode)
 799{
 800        return mlx4_cmd(dev, (mac | (clear << 63)), port, mode,
 801                        MLX4_CMD_SET_MCAST_FLTR, MLX4_CMD_TIME_CLASS_B,
 802                        MLX4_CMD_WRAPPED);
 803}
 804EXPORT_SYMBOL(mlx4_SET_MCAST_FLTR);
 805
 806int mlx4_SET_VLAN_FLTR_wrapper(struct mlx4_dev *dev, int slave,
 807                               struct mlx4_vhcr *vhcr,
 808                               struct mlx4_cmd_mailbox *inbox,
 809                               struct mlx4_cmd_mailbox *outbox,
 810                               struct mlx4_cmd_info *cmd)
 811{
 812        int err = 0;
 813
 814        return err;
 815}
 816
 817int mlx4_common_dump_eth_stats(struct mlx4_dev *dev, int slave,
 818                               u32 in_mod, struct mlx4_cmd_mailbox *outbox)
 819{
 820        return mlx4_cmd_box(dev, 0, outbox->dma, in_mod, 0,
 821                            MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B,
 822                            MLX4_CMD_NATIVE);
 823}
 824
 825int mlx4_DUMP_ETH_STATS_wrapper(struct mlx4_dev *dev, int slave,
 826                                struct mlx4_vhcr *vhcr,
 827                                struct mlx4_cmd_mailbox *inbox,
 828                                struct mlx4_cmd_mailbox *outbox,
 829                                struct mlx4_cmd_info *cmd)
 830{
 831        if (slave != dev->caps.function)
 832                return 0;
 833        return mlx4_common_dump_eth_stats(dev, slave,
 834                                          vhcr->in_modifier, outbox);
 835}
 836
 837void mlx4_set_stats_bitmap(struct mlx4_dev *dev, u64 *stats_bitmap)
 838{
 839        if (!mlx4_is_mfunc(dev)) {
 840                *stats_bitmap = 0;
 841                return;
 842        }
 843
 844        *stats_bitmap = (MLX4_STATS_TRAFFIC_COUNTERS_MASK |
 845                         MLX4_STATS_TRAFFIC_DROPS_MASK |
 846                         MLX4_STATS_PORT_COUNTERS_MASK);
 847
 848        if (mlx4_is_master(dev))
 849                *stats_bitmap |= MLX4_STATS_ERROR_COUNTERS_MASK;
 850}
 851EXPORT_SYMBOL(mlx4_set_stats_bitmap);
 852