The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/mlx5/mlx5_core/mlx5_vport.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2013-2017, Mellanox Technologies, Ltd.  All rights reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
   14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   16  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   23  * SUCH DAMAGE.
   24  *
   25  * $FreeBSD$
   26  */
   27 
   28 #include "opt_rss.h"
   29 #include "opt_ratelimit.h"
   30 
   31 #include <linux/etherdevice.h>
   32 #include <dev/mlx5/driver.h>
   33 #include <dev/mlx5/vport.h>
   34 #include <dev/mlx5/mlx5_core/mlx5_core.h>
   35 
   36 static int mlx5_modify_nic_vport_context(struct mlx5_core_dev *mdev, void *in,
   37                                          int inlen);
   38 
   39 static int _mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod,
   40                                    u16 vport, u32 *out, int outlen)
   41 {
   42         int err;
   43         u32 in[MLX5_ST_SZ_DW(query_vport_state_in)] = {0};
   44 
   45         MLX5_SET(query_vport_state_in, in, opcode,
   46                  MLX5_CMD_OP_QUERY_VPORT_STATE);
   47         MLX5_SET(query_vport_state_in, in, op_mod, opmod);
   48         MLX5_SET(query_vport_state_in, in, vport_number, vport);
   49         if (vport)
   50                 MLX5_SET(query_vport_state_in, in, other_vport, 1);
   51 
   52         err = mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen);
   53         if (err)
   54                 mlx5_core_warn(mdev, "MLX5_CMD_OP_QUERY_VPORT_STATE failed\n");
   55 
   56         return err;
   57 }
   58 
   59 u8 mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod, u16 vport)
   60 {
   61         u32 out[MLX5_ST_SZ_DW(query_vport_state_out)] = {0};
   62 
   63         _mlx5_query_vport_state(mdev, opmod, vport, out, sizeof(out));
   64 
   65         return MLX5_GET(query_vport_state_out, out, state);
   66 }
   67 EXPORT_SYMBOL_GPL(mlx5_query_vport_state);
   68 
   69 u8 mlx5_query_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod, u16 vport)
   70 {
   71         u32 out[MLX5_ST_SZ_DW(query_vport_state_out)] = {0};
   72 
   73         _mlx5_query_vport_state(mdev, opmod, vport, out, sizeof(out));
   74 
   75         return MLX5_GET(query_vport_state_out, out, admin_state);
   76 }
   77 EXPORT_SYMBOL(mlx5_query_vport_admin_state);
   78 
   79 int mlx5_modify_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod,
   80                                   u16 vport, u8 state)
   81 {
   82         u32 in[MLX5_ST_SZ_DW(modify_vport_state_in)] = {0};
   83         u32 out[MLX5_ST_SZ_DW(modify_vport_state_out)] = {0};
   84         int err;
   85 
   86         MLX5_SET(modify_vport_state_in, in, opcode,
   87                  MLX5_CMD_OP_MODIFY_VPORT_STATE);
   88         MLX5_SET(modify_vport_state_in, in, op_mod, opmod);
   89         MLX5_SET(modify_vport_state_in, in, vport_number, vport);
   90 
   91         if (vport)
   92                 MLX5_SET(modify_vport_state_in, in, other_vport, 1);
   93 
   94         MLX5_SET(modify_vport_state_in, in, admin_state, state);
   95 
   96         err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
   97         if (err)
   98                 mlx5_core_warn(mdev, "MLX5_CMD_OP_MODIFY_VPORT_STATE failed\n");
   99 
  100         return err;
  101 }
  102 EXPORT_SYMBOL(mlx5_modify_vport_admin_state);
  103 
  104 static int mlx5_query_nic_vport_context(struct mlx5_core_dev *mdev, u16 vport,
  105                                         u32 *out, int outlen)
  106 {
  107         u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
  108 
  109         MLX5_SET(query_nic_vport_context_in, in, opcode,
  110                  MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
  111 
  112         MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
  113         if (vport)
  114                 MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);
  115 
  116         return mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen);
  117 }
  118 
  119 static u32 mlx5_vport_max_q_counter_allocator(struct mlx5_core_dev *mdev,
  120                                               int client_id)
  121 {
  122         switch (client_id) {
  123         case MLX5_INTERFACE_PROTOCOL_IB:
  124                 return (MLX5_CAP_GEN(mdev, max_qp_cnt) -
  125                         MLX5_QCOUNTER_SETS_NETDEV);
  126         case MLX5_INTERFACE_PROTOCOL_ETH:
  127                 return MLX5_QCOUNTER_SETS_NETDEV;
  128         default:
  129                 mlx5_core_warn(mdev, "Unknown Client: %d\n", client_id);
  130                 return 0;
  131         }
  132 }
  133 
  134 int mlx5_vport_alloc_q_counter(struct mlx5_core_dev *mdev,
  135                                int client_id, u16 *counter_set_id)
  136 {
  137         u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {0};
  138         u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {0};
  139         int err;
  140 
  141         if (mdev->num_q_counter_allocated[client_id] >
  142             mlx5_vport_max_q_counter_allocator(mdev, client_id))
  143                 return -EINVAL;
  144 
  145         MLX5_SET(alloc_q_counter_in, in, opcode,
  146                  MLX5_CMD_OP_ALLOC_Q_COUNTER);
  147 
  148         err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
  149 
  150         if (!err)
  151                 *counter_set_id = MLX5_GET(alloc_q_counter_out, out,
  152                                            counter_set_id);
  153 
  154         mdev->num_q_counter_allocated[client_id]++;
  155 
  156         return err;
  157 }
  158 
  159 int mlx5_vport_dealloc_q_counter(struct mlx5_core_dev *mdev,
  160                                  int client_id, u16 counter_set_id)
  161 {
  162         u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {0};
  163         u32 out[MLX5_ST_SZ_DW(dealloc_q_counter_out)] = {0};
  164         int err;
  165 
  166         if (mdev->num_q_counter_allocated[client_id] <= 0)
  167                 return -EINVAL;
  168 
  169         MLX5_SET(dealloc_q_counter_in, in, opcode,
  170                  MLX5_CMD_OP_DEALLOC_Q_COUNTER);
  171         MLX5_SET(dealloc_q_counter_in, in, counter_set_id,
  172                  counter_set_id);
  173 
  174         err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
  175 
  176         mdev->num_q_counter_allocated[client_id]--;
  177 
  178         return err;
  179 }
  180 
  181 int mlx5_vport_query_q_counter(struct mlx5_core_dev *mdev,
  182                                       u16 counter_set_id,
  183                                       int reset,
  184                                       void *out,
  185                                       int out_size)
  186 {
  187         u32 in[MLX5_ST_SZ_DW(query_q_counter_in)] = {0};
  188 
  189         MLX5_SET(query_q_counter_in, in, opcode, MLX5_CMD_OP_QUERY_Q_COUNTER);
  190         MLX5_SET(query_q_counter_in, in, clear, reset);
  191         MLX5_SET(query_q_counter_in, in, counter_set_id, counter_set_id);
  192 
  193         return mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size);
  194 }
  195 
  196 int mlx5_vport_query_out_of_rx_buffer(struct mlx5_core_dev *mdev,
  197                                       u16 counter_set_id,
  198                                       u32 *out_of_rx_buffer)
  199 {
  200         u32 out[MLX5_ST_SZ_DW(query_q_counter_out)] = {0};
  201         int err;
  202 
  203         err = mlx5_vport_query_q_counter(mdev, counter_set_id, 0, out,
  204                                          sizeof(out));
  205 
  206         if (err)
  207                 return err;
  208 
  209         *out_of_rx_buffer = MLX5_GET(query_q_counter_out, out,
  210                                      out_of_buffer);
  211         return err;
  212 }
  213 
  214 int mlx5_query_nic_vport_min_inline(struct mlx5_core_dev *mdev,
  215                                     u16 vport, u8 *min_inline)
  216 {
  217         u32 out[MLX5_ST_SZ_DW(query_nic_vport_context_out)] = {0};
  218         int err;
  219 
  220         err = mlx5_query_nic_vport_context(mdev, vport, out, sizeof(out));
  221         if (!err)
  222                 *min_inline = MLX5_GET(query_nic_vport_context_out, out,
  223                                        nic_vport_context.min_wqe_inline_mode);
  224         return err;
  225 }
  226 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_min_inline);
  227 
  228 int mlx5_query_min_inline(struct mlx5_core_dev *mdev,
  229                           u8 *min_inline_mode)
  230 {
  231         int err;
  232 
  233         switch (MLX5_CAP_ETH(mdev, wqe_inline_mode)) {
  234         case MLX5_CAP_INLINE_MODE_L2:
  235                 *min_inline_mode = MLX5_INLINE_MODE_L2;
  236                 err = 0;
  237                 break;
  238         case MLX5_CAP_INLINE_MODE_VPORT_CONTEXT:
  239                 err = mlx5_query_nic_vport_min_inline(mdev, 0, min_inline_mode);
  240                 break;
  241         case MLX5_CAP_INLINE_MODE_NOT_REQUIRED:
  242                 *min_inline_mode = MLX5_INLINE_MODE_NONE;
  243                 err = 0;
  244                 break;
  245         default:
  246                 err = -EINVAL;
  247                 break;
  248         }
  249         return err;
  250 }
  251 EXPORT_SYMBOL_GPL(mlx5_query_min_inline);
  252 
  253 int mlx5_modify_nic_vport_min_inline(struct mlx5_core_dev *mdev,
  254                                      u16 vport, u8 min_inline)
  255 {
  256         u32 in[MLX5_ST_SZ_DW(modify_nic_vport_context_in)] = {0};
  257         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
  258         void *nic_vport_ctx;
  259 
  260         MLX5_SET(modify_nic_vport_context_in, in,
  261                  field_select.min_wqe_inline_mode, 1);
  262         MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
  263         MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
  264 
  265         nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in,
  266                                      in, nic_vport_context);
  267         MLX5_SET(nic_vport_context, nic_vport_ctx,
  268                  min_wqe_inline_mode, min_inline);
  269 
  270         return mlx5_modify_nic_vport_context(mdev, in, inlen);
  271 }
  272 EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_min_inline);
  273 
  274 int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev,
  275                                      u16 vport, u8 *addr)
  276 {
  277         u32 *out;
  278         int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
  279         u8 *out_addr;
  280         int err;
  281 
  282         out = mlx5_vzalloc(outlen);
  283         if (!out)
  284                 return -ENOMEM;
  285 
  286         out_addr = MLX5_ADDR_OF(query_nic_vport_context_out, out,
  287                                 nic_vport_context.permanent_address);
  288 
  289         err = mlx5_query_nic_vport_context(mdev, vport, out, outlen);
  290         if (err)
  291                 goto out;
  292 
  293         ether_addr_copy(addr, &out_addr[2]);
  294 
  295 out:
  296         kvfree(out);
  297         return err;
  298 }
  299 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_mac_address);
  300 
  301 int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *mdev,
  302                                       u16 vport, u8 *addr)
  303 {
  304         void *in;
  305         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
  306         int err;
  307         void *nic_vport_ctx;
  308         u8 *perm_mac;
  309 
  310         in = mlx5_vzalloc(inlen);
  311         if (!in) {
  312                 mlx5_core_warn(mdev, "failed to allocate inbox\n");
  313                 return -ENOMEM;
  314         }
  315 
  316         MLX5_SET(modify_nic_vport_context_in, in,
  317                  field_select.permanent_address, 1);
  318         MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
  319 
  320         if (vport)
  321                 MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
  322 
  323         nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in,
  324                                      in, nic_vport_context);
  325         perm_mac = MLX5_ADDR_OF(nic_vport_context, nic_vport_ctx,
  326                                 permanent_address);
  327 
  328         ether_addr_copy(&perm_mac[2], addr);
  329 
  330         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
  331 
  332         kvfree(in);
  333 
  334         return err;
  335 }
  336 EXPORT_SYMBOL(mlx5_modify_nic_vport_mac_address);
  337 
  338 int mlx5_query_nic_vport_system_image_guid(struct mlx5_core_dev *mdev,
  339                                            u64 *system_image_guid)
  340 {
  341         u32 *out;
  342         int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
  343         int err;
  344 
  345         out = mlx5_vzalloc(outlen);
  346         if (!out)
  347                 return -ENOMEM;
  348 
  349         err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
  350         if (err)
  351                 goto out;
  352 
  353         *system_image_guid = MLX5_GET64(query_nic_vport_context_out, out,
  354                                         nic_vport_context.system_image_guid);
  355 out:
  356         kvfree(out);
  357         return err;
  358 }
  359 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_system_image_guid);
  360 
  361 int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid)
  362 {
  363         u32 *out;
  364         int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
  365         int err;
  366 
  367         out = mlx5_vzalloc(outlen);
  368         if (!out)
  369                 return -ENOMEM;
  370 
  371         err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
  372         if (err)
  373                 goto out;
  374 
  375         *node_guid = MLX5_GET64(query_nic_vport_context_out, out,
  376                                 nic_vport_context.node_guid);
  377 
  378 out:
  379         kvfree(out);
  380         return err;
  381 }
  382 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_node_guid);
  383 
  384 static int mlx5_query_nic_vport_port_guid(struct mlx5_core_dev *mdev,
  385                                           u64 *port_guid)
  386 {
  387         u32 *out;
  388         int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
  389         int err;
  390 
  391         out = mlx5_vzalloc(outlen);
  392         if (!out)
  393                 return -ENOMEM;
  394 
  395         err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
  396         if (err)
  397                 goto out;
  398 
  399         *port_guid = MLX5_GET64(query_nic_vport_context_out, out,
  400                                 nic_vport_context.port_guid);
  401 
  402 out:
  403         kvfree(out);
  404         return err;
  405 }
  406 
  407 int mlx5_query_nic_vport_qkey_viol_cntr(struct mlx5_core_dev *mdev,
  408                                         u16 *qkey_viol_cntr)
  409 {
  410         u32 *out;
  411         int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
  412         int err;
  413 
  414         out = mlx5_vzalloc(outlen);
  415         if (!out)
  416                 return -ENOMEM;
  417 
  418         err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
  419         if (err)
  420                 goto out;
  421 
  422         *qkey_viol_cntr = MLX5_GET(query_nic_vport_context_out, out,
  423                                 nic_vport_context.qkey_violation_counter);
  424 
  425 out:
  426         kvfree(out);
  427         return err;
  428 }
  429 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_qkey_viol_cntr);
  430 
  431 static int mlx5_modify_nic_vport_context(struct mlx5_core_dev *mdev, void *in,
  432                                          int inlen)
  433 {
  434         u32 out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)] = {0};
  435 
  436         MLX5_SET(modify_nic_vport_context_in, in, opcode,
  437                  MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
  438 
  439         return mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
  440 }
  441 
  442 static int mlx5_nic_vport_enable_disable_roce(struct mlx5_core_dev *mdev,
  443                                               int enable_disable)
  444 {
  445         void *in;
  446         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
  447         int err;
  448 
  449         in = mlx5_vzalloc(inlen);
  450         if (!in) {
  451                 mlx5_core_warn(mdev, "failed to allocate inbox\n");
  452                 return -ENOMEM;
  453         }
  454 
  455         MLX5_SET(modify_nic_vport_context_in, in, field_select.roce_en, 1);
  456         MLX5_SET(modify_nic_vport_context_in, in, nic_vport_context.roce_en,
  457                  enable_disable);
  458 
  459         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
  460 
  461         kvfree(in);
  462 
  463         return err;
  464 }
  465 
  466 int mlx5_set_nic_vport_current_mac(struct mlx5_core_dev *mdev, int vport,
  467                                    bool other_vport, u8 *addr)
  468 {
  469         void *in;
  470         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in)
  471                   + MLX5_ST_SZ_BYTES(mac_address_layout);
  472         u8  *mac_layout;
  473         u8  *mac_ptr;
  474         int err;
  475 
  476         in = mlx5_vzalloc(inlen);
  477         if (!in) {
  478                 mlx5_core_warn(mdev, "failed to allocate inbox\n");
  479                 return -ENOMEM;
  480         }
  481 
  482         MLX5_SET(modify_nic_vport_context_in, in,
  483                  opcode, MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
  484         MLX5_SET(modify_nic_vport_context_in, in,
  485                  vport_number, vport);
  486         MLX5_SET(modify_nic_vport_context_in, in,
  487                  other_vport, other_vport);
  488         MLX5_SET(modify_nic_vport_context_in, in,
  489                  field_select.addresses_list, 1);
  490         MLX5_SET(modify_nic_vport_context_in, in,
  491                  nic_vport_context.allowed_list_type,
  492                  MLX5_NIC_VPORT_LIST_TYPE_UC);
  493         MLX5_SET(modify_nic_vport_context_in, in,
  494                  nic_vport_context.allowed_list_size, 1);
  495 
  496         mac_layout = (u8 *)MLX5_ADDR_OF(modify_nic_vport_context_in, in,
  497                 nic_vport_context.current_uc_mac_address);
  498         mac_ptr = (u8 *)MLX5_ADDR_OF(mac_address_layout, mac_layout,
  499                 mac_addr_47_32);
  500         ether_addr_copy(mac_ptr, addr);
  501 
  502         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
  503 
  504         kvfree(in);
  505 
  506         return err;
  507 }
  508 EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_current_mac);
  509 
  510 int mlx5_modify_nic_vport_node_guid(struct mlx5_core_dev *mdev,
  511                                     u32 vport, u64 node_guid)
  512 {
  513         void *in;
  514         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
  515         int err;
  516         void *nic_vport_context;
  517 
  518         if (!vport)
  519                 return -EINVAL;
  520         if (!MLX5_CAP_GEN(mdev, vport_group_manager))
  521                 return -EPERM;
  522         if (!MLX5_CAP_ESW(mdev, nic_vport_node_guid_modify))
  523                 return -ENOTSUPP;
  524 
  525         in = mlx5_vzalloc(inlen);
  526         if (!in) {
  527                 mlx5_core_warn(mdev, "failed to allocate inbox\n");
  528                 return -ENOMEM;
  529         }
  530 
  531         MLX5_SET(modify_nic_vport_context_in, in,
  532                  field_select.node_guid, 1);
  533         MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
  534 
  535         MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
  536 
  537         nic_vport_context = MLX5_ADDR_OF(modify_nic_vport_context_in,
  538                                          in, nic_vport_context);
  539         MLX5_SET64(nic_vport_context, nic_vport_context, node_guid, node_guid);
  540 
  541         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
  542 
  543         kvfree(in);
  544 
  545         return err;
  546 }
  547 EXPORT_SYMBOL(mlx5_modify_nic_vport_node_guid);
  548 
  549 int mlx5_modify_nic_vport_port_guid(struct mlx5_core_dev *mdev,
  550                                     u32 vport, u64 port_guid)
  551 {
  552         void *in;
  553         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
  554         int err;
  555         void *nic_vport_context;
  556 
  557         if (!vport)
  558                 return -EINVAL;
  559         if (!MLX5_CAP_GEN(mdev, vport_group_manager))
  560                 return -EPERM;
  561         if (!MLX5_CAP_ESW(mdev, nic_vport_port_guid_modify))
  562                 return -ENOTSUPP;
  563 
  564         in = mlx5_vzalloc(inlen);
  565         if (!in) {
  566                 mlx5_core_warn(mdev, "failed to allocate inbox\n");
  567                 return -ENOMEM;
  568         }
  569 
  570         MLX5_SET(modify_nic_vport_context_in, in,
  571                  field_select.port_guid, 1);
  572         MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
  573 
  574         MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
  575 
  576         nic_vport_context = MLX5_ADDR_OF(modify_nic_vport_context_in,
  577                                          in, nic_vport_context);
  578         MLX5_SET64(nic_vport_context, nic_vport_context, port_guid, port_guid);
  579 
  580         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
  581 
  582         kvfree(in);
  583 
  584         return err;
  585 }
  586 EXPORT_SYMBOL(mlx5_modify_nic_vport_port_guid);
  587 
  588 int mlx5_set_nic_vport_vlan_list(struct mlx5_core_dev *dev, u16 vport,
  589                                  u16 *vlan_list, int list_len)
  590 {
  591         void *in, *ctx;
  592         int i, err;
  593         int  inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in)
  594                 + MLX5_ST_SZ_BYTES(vlan_layout) * (int)list_len;
  595 
  596         int max_list_size = 1 << MLX5_CAP_GEN_MAX(dev, log_max_vlan_list);
  597 
  598         if (list_len > max_list_size) {
  599                 mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
  600                                list_len, max_list_size);
  601                 return -ENOSPC;
  602         }
  603 
  604         in = mlx5_vzalloc(inlen);
  605         if (!in) {
  606                 mlx5_core_warn(dev, "failed to allocate inbox\n");
  607                 return -ENOMEM;
  608         }
  609 
  610         MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
  611         if (vport)
  612                 MLX5_SET(modify_nic_vport_context_in, in,
  613                          other_vport, 1);
  614         MLX5_SET(modify_nic_vport_context_in, in,
  615                  field_select.addresses_list, 1);
  616 
  617         ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in, nic_vport_context);
  618 
  619         MLX5_SET(nic_vport_context, ctx, allowed_list_type,
  620                  MLX5_NIC_VPORT_LIST_TYPE_VLAN);
  621         MLX5_SET(nic_vport_context, ctx, allowed_list_size, list_len);
  622 
  623         for (i = 0; i < list_len; i++) {
  624                 u8 *vlan_lout = MLX5_ADDR_OF(nic_vport_context, ctx,
  625                                          current_uc_mac_address[i]);
  626                 MLX5_SET(vlan_layout, vlan_lout, vlan, vlan_list[i]);
  627         }
  628 
  629         err = mlx5_modify_nic_vport_context(dev, in, inlen);
  630 
  631         kvfree(in);
  632         return err;
  633 }
  634 EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_vlan_list);
  635 
  636 int mlx5_set_nic_vport_mc_list(struct mlx5_core_dev *mdev, int vport,
  637                                u64 *addr_list, size_t addr_list_len)
  638 {
  639         void *in, *ctx;
  640         int  inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in)
  641                   + MLX5_ST_SZ_BYTES(mac_address_layout) * (int)addr_list_len;
  642         int err;
  643         size_t i;
  644         int max_list_sz = 1 << MLX5_CAP_GEN_MAX(mdev, log_max_current_mc_list);
  645 
  646         if ((int)addr_list_len > max_list_sz) {
  647                 mlx5_core_warn(mdev, "Requested list size (%d) > (%d) max_list_size\n",
  648                                (int)addr_list_len, max_list_sz);
  649                 return -ENOSPC;
  650         }
  651 
  652         in = mlx5_vzalloc(inlen);
  653         if (!in) {
  654                 mlx5_core_warn(mdev, "failed to allocate inbox\n");
  655                 return -ENOMEM;
  656         }
  657 
  658         MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
  659         if (vport)
  660                 MLX5_SET(modify_nic_vport_context_in, in,
  661                          other_vport, 1);
  662         MLX5_SET(modify_nic_vport_context_in, in,
  663                  field_select.addresses_list, 1);
  664 
  665         ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in, nic_vport_context);
  666 
  667         MLX5_SET(nic_vport_context, ctx, allowed_list_type,
  668                  MLX5_NIC_VPORT_LIST_TYPE_MC);
  669         MLX5_SET(nic_vport_context, ctx, allowed_list_size, addr_list_len);
  670 
  671         for (i = 0; i < addr_list_len; i++) {
  672                 u8 *mac_lout = (u8 *)MLX5_ADDR_OF(nic_vport_context, ctx,
  673                                                   current_uc_mac_address[i]);
  674                 u8 *mac_ptr = (u8 *)MLX5_ADDR_OF(mac_address_layout, mac_lout,
  675                                                  mac_addr_47_32);
  676                 ether_addr_copy(mac_ptr, (u8 *)&addr_list[i]);
  677         }
  678 
  679         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
  680 
  681         kvfree(in);
  682 
  683         return err;
  684 }
  685 EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_mc_list);
  686 
  687 int mlx5_set_nic_vport_promisc(struct mlx5_core_dev *mdev, int vport,
  688                                bool promisc_mc, bool promisc_uc,
  689                                bool promisc_all)
  690 {
  691         u8  in[MLX5_ST_SZ_BYTES(modify_nic_vport_context_in)];
  692         u8 *ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in,
  693                                nic_vport_context);
  694 
  695         memset(in, 0, MLX5_ST_SZ_BYTES(modify_nic_vport_context_in));
  696 
  697         MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
  698         if (vport)
  699                 MLX5_SET(modify_nic_vport_context_in, in,
  700                          other_vport, 1);
  701         MLX5_SET(modify_nic_vport_context_in, in, field_select.promisc, 1);
  702         if (promisc_mc)
  703                 MLX5_SET(nic_vport_context, ctx, promisc_mc, 1);
  704         if (promisc_uc)
  705                 MLX5_SET(nic_vport_context, ctx, promisc_uc, 1);
  706         if (promisc_all)
  707                 MLX5_SET(nic_vport_context, ctx, promisc_all, 1);
  708 
  709         return mlx5_modify_nic_vport_context(mdev, in, sizeof(in));
  710 }
  711 EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_promisc);
  712 
  713 int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
  714                                   u16 vport,
  715                                   enum mlx5_list_type list_type,
  716                                   u8 addr_list[][ETH_ALEN],
  717                                   int *list_size)
  718 {
  719         u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
  720         void *nic_vport_ctx;
  721         int max_list_size;
  722         int req_list_size;
  723         int out_sz;
  724         void *out;
  725         int err;
  726         int i;
  727 
  728         req_list_size = *list_size;
  729 
  730         max_list_size = (list_type == MLX5_NIC_VPORT_LIST_TYPE_UC) ?
  731                         1 << MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list) :
  732                         1 << MLX5_CAP_GEN_MAX(dev, log_max_current_mc_list);
  733 
  734         if (req_list_size > max_list_size) {
  735                 mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
  736                                req_list_size, max_list_size);
  737                 req_list_size = max_list_size;
  738         }
  739 
  740         out_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
  741                  req_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
  742 
  743         out = kzalloc(out_sz, GFP_KERNEL);
  744         if (!out)
  745                 return -ENOMEM;
  746 
  747         MLX5_SET(query_nic_vport_context_in, in, opcode,
  748                  MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
  749         MLX5_SET(query_nic_vport_context_in, in, allowed_list_type, list_type);
  750         MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
  751 
  752         if (vport)
  753                 MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);
  754 
  755         err = mlx5_cmd_exec(dev, in, sizeof(in), out, out_sz);
  756         if (err)
  757                 goto out;
  758 
  759         nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
  760                                      nic_vport_context);
  761         req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
  762                                  allowed_list_size);
  763 
  764         *list_size = req_list_size;
  765         for (i = 0; i < req_list_size; i++) {
  766                 u8 *mac_addr = MLX5_ADDR_OF(nic_vport_context,
  767                                         nic_vport_ctx,
  768                                         current_uc_mac_address[i]) + 2;
  769                 ether_addr_copy(addr_list[i], mac_addr);
  770         }
  771 out:
  772         kfree(out);
  773         return err;
  774 }
  775 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_mac_list);
  776 
  777 int mlx5_modify_nic_vport_mac_list(struct mlx5_core_dev *dev,
  778                                    enum mlx5_list_type list_type,
  779                                    u8 addr_list[][ETH_ALEN],
  780                                    int list_size)
  781 {
  782         u32 out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)] = {0};
  783         void *nic_vport_ctx;
  784         int max_list_size;
  785         int in_sz;
  786         void *in;
  787         int err;
  788         int i;
  789 
  790         max_list_size = list_type == MLX5_NIC_VPORT_LIST_TYPE_UC ?
  791                  1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
  792                  1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
  793 
  794         if (list_size > max_list_size)
  795                 return -ENOSPC;
  796 
  797         in_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
  798                 list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
  799 
  800         in = kzalloc(in_sz, GFP_KERNEL);
  801         if (!in)
  802                 return -ENOMEM;
  803 
  804         MLX5_SET(modify_nic_vport_context_in, in, opcode,
  805                  MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
  806         MLX5_SET(modify_nic_vport_context_in, in,
  807                  field_select.addresses_list, 1);
  808 
  809         nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in,
  810                                      nic_vport_context);
  811 
  812         MLX5_SET(nic_vport_context, nic_vport_ctx,
  813                  allowed_list_type, list_type);
  814         MLX5_SET(nic_vport_context, nic_vport_ctx,
  815                  allowed_list_size, list_size);
  816 
  817         for (i = 0; i < list_size; i++) {
  818                 u8 *curr_mac = MLX5_ADDR_OF(nic_vport_context,
  819                                             nic_vport_ctx,
  820                                             current_uc_mac_address[i]) + 2;
  821                 ether_addr_copy(curr_mac, addr_list[i]);
  822         }
  823 
  824         err = mlx5_cmd_exec(dev, in, in_sz, out, sizeof(out));
  825         kfree(in);
  826         return err;
  827 }
  828 EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mac_list);
  829 
  830 int mlx5_query_nic_vport_vlans(struct mlx5_core_dev *dev,
  831                                u16 vport,
  832                                u16 vlans[],
  833                                int *size)
  834 {
  835         u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
  836         void *nic_vport_ctx;
  837         int req_list_size;
  838         int max_list_size;
  839         int out_sz;
  840         void *out;
  841         int err;
  842         int i;
  843 
  844         req_list_size = *size;
  845         max_list_size = 1 << MLX5_CAP_GEN(dev, log_max_vlan_list);
  846         if (req_list_size > max_list_size) {
  847                 mlx5_core_warn(dev, "Requested list size (%d) > (%d) max list size\n",
  848                                req_list_size, max_list_size);
  849                 req_list_size = max_list_size;
  850         }
  851 
  852         out_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
  853                  req_list_size * MLX5_ST_SZ_BYTES(vlan_layout);
  854 
  855         out = kzalloc(out_sz, GFP_KERNEL);
  856         if (!out)
  857                 return -ENOMEM;
  858 
  859         MLX5_SET(query_nic_vport_context_in, in, opcode,
  860                  MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
  861         MLX5_SET(query_nic_vport_context_in, in, allowed_list_type,
  862                  MLX5_NIC_VPORT_CONTEXT_ALLOWED_LIST_TYPE_VLAN_LIST);
  863         MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
  864 
  865         if (vport)
  866                 MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);
  867 
  868         err = mlx5_cmd_exec(dev, in, sizeof(in), out, out_sz);
  869         if (err)
  870                 goto out;
  871 
  872         nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
  873                                      nic_vport_context);
  874         req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
  875                                  allowed_list_size);
  876 
  877         *size = req_list_size;
  878         for (i = 0; i < req_list_size; i++) {
  879                 void *vlan_addr = MLX5_ADDR_OF(nic_vport_context,
  880                                                nic_vport_ctx,
  881                                          current_uc_mac_address[i]);
  882                 vlans[i] = MLX5_GET(vlan_layout, vlan_addr, vlan);
  883         }
  884 out:
  885         kfree(out);
  886         return err;
  887 }
  888 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_vlans);
  889 
  890 int mlx5_modify_nic_vport_vlans(struct mlx5_core_dev *dev,
  891                                 u16 vlans[],
  892                                 int list_size)
  893 {
  894         u32 out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)] = {0};
  895         void *nic_vport_ctx;
  896         int max_list_size;
  897         int in_sz;
  898         void *in;
  899         int err;
  900         int i;
  901 
  902         max_list_size = 1 << MLX5_CAP_GEN(dev, log_max_vlan_list);
  903 
  904         if (list_size > max_list_size)
  905                 return -ENOSPC;
  906 
  907         in_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
  908                 list_size * MLX5_ST_SZ_BYTES(vlan_layout);
  909 
  910         in = kzalloc(in_sz, GFP_KERNEL);
  911         if (!in)
  912                 return -ENOMEM;
  913 
  914         MLX5_SET(modify_nic_vport_context_in, in, opcode,
  915                  MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
  916         MLX5_SET(modify_nic_vport_context_in, in,
  917                  field_select.addresses_list, 1);
  918 
  919         nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in,
  920                                      nic_vport_context);
  921 
  922         MLX5_SET(nic_vport_context, nic_vport_ctx,
  923                  allowed_list_type, MLX5_NIC_VPORT_LIST_TYPE_VLAN);
  924         MLX5_SET(nic_vport_context, nic_vport_ctx,
  925                  allowed_list_size, list_size);
  926 
  927         for (i = 0; i < list_size; i++) {
  928                 void *vlan_addr = MLX5_ADDR_OF(nic_vport_context,
  929                                                nic_vport_ctx,
  930                                                current_uc_mac_address[i]);
  931                 MLX5_SET(vlan_layout, vlan_addr, vlan, vlans[i]);
  932         }
  933 
  934         err = mlx5_cmd_exec(dev, in, in_sz, out, sizeof(out));
  935         kfree(in);
  936         return err;
  937 }
  938 EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_vlans);
  939 
  940 int mlx5_query_nic_vport_roce_en(struct mlx5_core_dev *mdev, u8 *enable)
  941 {
  942         u32 *out;
  943         int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
  944         int err;
  945 
  946         out = kzalloc(outlen, GFP_KERNEL);
  947         if (!out)
  948                 return -ENOMEM;
  949 
  950         err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
  951         if (err)
  952                 goto out;
  953 
  954         *enable = MLX5_GET(query_nic_vport_context_out, out,
  955                                 nic_vport_context.roce_en);
  956 
  957 out:
  958         kfree(out);
  959         return err;
  960 }
  961 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_roce_en);
  962 
  963 int mlx5_set_nic_vport_permanent_mac(struct mlx5_core_dev *mdev, int vport,
  964                                      u8 *addr)
  965 {
  966         void *in;
  967         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
  968         u8  *mac_ptr;
  969         int err;
  970 
  971         in = mlx5_vzalloc(inlen);
  972         if (!in) {
  973                 mlx5_core_warn(mdev, "failed to allocate inbox\n");
  974                 return -ENOMEM;
  975         }
  976 
  977         MLX5_SET(modify_nic_vport_context_in, in,
  978                  opcode, MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
  979         MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
  980         MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
  981         MLX5_SET(modify_nic_vport_context_in, in,
  982                  field_select.permanent_address, 1);
  983         mac_ptr = (u8 *)MLX5_ADDR_OF(modify_nic_vport_context_in, in,
  984                 nic_vport_context.permanent_address.mac_addr_47_32);
  985         ether_addr_copy(mac_ptr, addr);
  986 
  987         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
  988 
  989         kvfree(in);
  990 
  991         return err;
  992 }
  993 EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_permanent_mac);
  994 
  995 int mlx5_nic_vport_enable_roce(struct mlx5_core_dev *mdev)
  996 {
  997         return mlx5_nic_vport_enable_disable_roce(mdev, 1);
  998 }
  999 EXPORT_SYMBOL_GPL(mlx5_nic_vport_enable_roce);
 1000 
 1001 int mlx5_nic_vport_disable_roce(struct mlx5_core_dev *mdev)
 1002 {
 1003         return mlx5_nic_vport_enable_disable_roce(mdev, 0);
 1004 }
 1005 EXPORT_SYMBOL_GPL(mlx5_nic_vport_disable_roce);
 1006 
 1007 int mlx5_core_query_vport_counter(struct mlx5_core_dev *dev, u8 other_vport,
 1008                                   int vf, u8 port_num, void *out,
 1009                                   size_t out_sz)
 1010 {
 1011         int     in_sz = MLX5_ST_SZ_BYTES(query_vport_counter_in);
 1012         int     is_group_manager;
 1013         void   *in;
 1014         int     err;
 1015 
 1016         is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
 1017         in = mlx5_vzalloc(in_sz);
 1018         if (!in) {
 1019                 err = -ENOMEM;
 1020                 return err;
 1021         }
 1022 
 1023         MLX5_SET(query_vport_counter_in, in, opcode,
 1024                  MLX5_CMD_OP_QUERY_VPORT_COUNTER);
 1025         if (other_vport) {
 1026                 if (is_group_manager) {
 1027                         MLX5_SET(query_vport_counter_in, in, other_vport, 1);
 1028                         MLX5_SET(query_vport_counter_in, in, vport_number, vf + 1);
 1029                 } else {
 1030                         err = -EPERM;
 1031                         goto free;
 1032                 }
 1033         }
 1034         if (MLX5_CAP_GEN(dev, num_ports) == 2)
 1035                 MLX5_SET(query_vport_counter_in, in, port_num, port_num);
 1036 
 1037         err = mlx5_cmd_exec(dev, in, in_sz, out,  out_sz);
 1038 free:
 1039         kvfree(in);
 1040         return err;
 1041 }
 1042 EXPORT_SYMBOL_GPL(mlx5_core_query_vport_counter);
 1043 
 1044 int mlx5_query_hca_vport_context(struct mlx5_core_dev *mdev,
 1045                                  u8 port_num, u8 vport_num, u32 *out,
 1046                                  int outlen)
 1047 {
 1048         u32 in[MLX5_ST_SZ_DW(query_hca_vport_context_in)] = {0};
 1049         int is_group_manager;
 1050 
 1051         is_group_manager = MLX5_CAP_GEN(mdev, vport_group_manager);
 1052 
 1053         MLX5_SET(query_hca_vport_context_in, in, opcode,
 1054                  MLX5_CMD_OP_QUERY_HCA_VPORT_CONTEXT);
 1055 
 1056         if (vport_num) {
 1057                 if (is_group_manager) {
 1058                         MLX5_SET(query_hca_vport_context_in, in, other_vport,
 1059                                  1);
 1060                         MLX5_SET(query_hca_vport_context_in, in, vport_number,
 1061                                  vport_num);
 1062                 } else {
 1063                         return -EPERM;
 1064                 }
 1065         }
 1066 
 1067         if (MLX5_CAP_GEN(mdev, num_ports) == 2)
 1068                 MLX5_SET(query_hca_vport_context_in, in, port_num, port_num);
 1069 
 1070         return mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen);
 1071 }
 1072 
 1073 int mlx5_query_hca_vport_system_image_guid(struct mlx5_core_dev *mdev,
 1074                                            u64 *system_image_guid)
 1075 {
 1076         u32 *out;
 1077         int outlen = MLX5_ST_SZ_BYTES(query_hca_vport_context_out);
 1078         int err;
 1079 
 1080         out = mlx5_vzalloc(outlen);
 1081         if (!out)
 1082                 return -ENOMEM;
 1083 
 1084         err = mlx5_query_hca_vport_context(mdev, 1, 0, out, outlen);
 1085         if (err)
 1086                 goto out;
 1087 
 1088         *system_image_guid = MLX5_GET64(query_hca_vport_context_out, out,
 1089                                         hca_vport_context.system_image_guid);
 1090 
 1091 out:
 1092         kvfree(out);
 1093         return err;
 1094 }
 1095 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_system_image_guid);
 1096 
 1097 int mlx5_query_hca_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid)
 1098 {
 1099         u32 *out;
 1100         int outlen = MLX5_ST_SZ_BYTES(query_hca_vport_context_out);
 1101         int err;
 1102 
 1103         out = mlx5_vzalloc(outlen);
 1104         if (!out)
 1105                 return -ENOMEM;
 1106 
 1107         err = mlx5_query_hca_vport_context(mdev, 1, 0, out, outlen);
 1108         if (err)
 1109                 goto out;
 1110 
 1111         *node_guid = MLX5_GET64(query_hca_vport_context_out, out,
 1112                                 hca_vport_context.node_guid);
 1113 
 1114 out:
 1115         kvfree(out);
 1116         return err;
 1117 }
 1118 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_node_guid);
 1119 
 1120 static int mlx5_query_hca_vport_port_guid(struct mlx5_core_dev *mdev,
 1121                                           u64 *port_guid)
 1122 {
 1123         u32 *out;
 1124         int outlen = MLX5_ST_SZ_BYTES(query_hca_vport_context_out);
 1125         int err;
 1126 
 1127         out = mlx5_vzalloc(outlen);
 1128         if (!out)
 1129                 return -ENOMEM;
 1130 
 1131         err = mlx5_query_hca_vport_context(mdev, 1, 0, out, outlen);
 1132         if (err)
 1133                 goto out;
 1134 
 1135         *port_guid = MLX5_GET64(query_hca_vport_context_out, out,
 1136                                 hca_vport_context.port_guid);
 1137 
 1138 out:
 1139         kvfree(out);
 1140         return err;
 1141 }
 1142 
 1143 int mlx5_query_hca_vport_gid(struct mlx5_core_dev *dev, u8 port_num,
 1144                              u16 vport_num, u16 gid_index, union ib_gid *gid)
 1145 {
 1146         int in_sz = MLX5_ST_SZ_BYTES(query_hca_vport_gid_in);
 1147         int out_sz = MLX5_ST_SZ_BYTES(query_hca_vport_gid_out);
 1148         int is_group_manager;
 1149         void *out = NULL;
 1150         void *in = NULL;
 1151         union ib_gid *tmp;
 1152         int tbsz;
 1153         int nout;
 1154         int err;
 1155 
 1156         is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
 1157         tbsz = mlx5_get_gid_table_len(MLX5_CAP_GEN(dev, gid_table_size));
 1158 
 1159         if (gid_index > tbsz && gid_index != 0xffff)
 1160                 return -EINVAL;
 1161 
 1162         if (gid_index == 0xffff)
 1163                 nout = tbsz;
 1164         else
 1165                 nout = 1;
 1166 
 1167         out_sz += nout * sizeof(*gid);
 1168 
 1169         in = mlx5_vzalloc(in_sz);
 1170         out = mlx5_vzalloc(out_sz);
 1171         if (!in || !out) {
 1172                 err = -ENOMEM;
 1173                 goto out;
 1174         }
 1175 
 1176         MLX5_SET(query_hca_vport_gid_in, in, opcode,
 1177                  MLX5_CMD_OP_QUERY_HCA_VPORT_GID);
 1178         if (vport_num) {
 1179                 if (is_group_manager) {
 1180                         MLX5_SET(query_hca_vport_gid_in, in, vport_number,
 1181                                  vport_num);
 1182                         MLX5_SET(query_hca_vport_gid_in, in, other_vport, 1);
 1183                 } else {
 1184                         err = -EPERM;
 1185                         goto out;
 1186                 }
 1187         }
 1188 
 1189         MLX5_SET(query_hca_vport_gid_in, in, gid_index, gid_index);
 1190 
 1191         if (MLX5_CAP_GEN(dev, num_ports) == 2)
 1192                 MLX5_SET(query_hca_vport_gid_in, in, port_num, port_num);
 1193 
 1194         err = mlx5_cmd_exec(dev, in, in_sz, out, out_sz);
 1195         if (err)
 1196                 goto out;
 1197 
 1198         tmp = (union ib_gid *)MLX5_ADDR_OF(query_hca_vport_gid_out, out, gid);
 1199         gid->global.subnet_prefix = tmp->global.subnet_prefix;
 1200         gid->global.interface_id = tmp->global.interface_id;
 1201 
 1202 out:
 1203         kvfree(in);
 1204         kvfree(out);
 1205         return err;
 1206 }
 1207 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_gid);
 1208 
 1209 int mlx5_query_hca_vport_pkey(struct mlx5_core_dev *dev, u8 other_vport,
 1210                               u8 port_num, u16 vf_num, u16 pkey_index,
 1211                               u16 *pkey)
 1212 {
 1213         int in_sz = MLX5_ST_SZ_BYTES(query_hca_vport_pkey_in);
 1214         int out_sz = MLX5_ST_SZ_BYTES(query_hca_vport_pkey_out);
 1215         int is_group_manager;
 1216         void *out = NULL;
 1217         void *in = NULL;
 1218         void *pkarr;
 1219         int nout;
 1220         int tbsz;
 1221         int err;
 1222         int i;
 1223 
 1224         is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
 1225 
 1226         tbsz = mlx5_to_sw_pkey_sz(MLX5_CAP_GEN(dev, pkey_table_size));
 1227         if (pkey_index > tbsz && pkey_index != 0xffff)
 1228                 return -EINVAL;
 1229 
 1230         if (pkey_index == 0xffff)
 1231                 nout = tbsz;
 1232         else
 1233                 nout = 1;
 1234 
 1235         out_sz += nout * MLX5_ST_SZ_BYTES(pkey);
 1236 
 1237         in = kzalloc(in_sz, GFP_KERNEL);
 1238         out = kzalloc(out_sz, GFP_KERNEL);
 1239 
 1240         MLX5_SET(query_hca_vport_pkey_in, in, opcode,
 1241                  MLX5_CMD_OP_QUERY_HCA_VPORT_PKEY);
 1242         if (other_vport) {
 1243                 if (is_group_manager) {
 1244                         MLX5_SET(query_hca_vport_pkey_in, in, vport_number,
 1245                                  vf_num);
 1246                         MLX5_SET(query_hca_vport_pkey_in, in, other_vport, 1);
 1247                 } else {
 1248                         err = -EPERM;
 1249                         goto out;
 1250                 }
 1251         }
 1252         MLX5_SET(query_hca_vport_pkey_in, in, pkey_index, pkey_index);
 1253 
 1254         if (MLX5_CAP_GEN(dev, num_ports) == 2)
 1255                 MLX5_SET(query_hca_vport_pkey_in, in, port_num, port_num);
 1256 
 1257         err = mlx5_cmd_exec(dev, in, in_sz, out, out_sz);
 1258         if (err)
 1259                 goto out;
 1260 
 1261         pkarr = MLX5_ADDR_OF(query_hca_vport_pkey_out, out, pkey);
 1262         for (i = 0; i < nout; i++, pkey++,
 1263              pkarr += MLX5_ST_SZ_BYTES(pkey))
 1264                 *pkey = MLX5_GET_PR(pkey, pkarr, pkey);
 1265 
 1266 out:
 1267         kfree(in);
 1268         kfree(out);
 1269         return err;
 1270 }
 1271 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_pkey);
 1272 
 1273 static int mlx5_query_hca_min_wqe_header(struct mlx5_core_dev *mdev,
 1274                                          int *min_header)
 1275 {
 1276         u32 *out;
 1277         u32 outlen = MLX5_ST_SZ_BYTES(query_hca_vport_context_out);
 1278         int err;
 1279 
 1280         out = mlx5_vzalloc(outlen);
 1281         if (!out)
 1282                 return -ENOMEM;
 1283 
 1284         err = mlx5_query_hca_vport_context(mdev, 1, 0, out, outlen);
 1285         if (err)
 1286                 goto out;
 1287 
 1288         *min_header = MLX5_GET(query_hca_vport_context_out, out,
 1289                                hca_vport_context.min_wqe_inline_mode);
 1290 
 1291 out:
 1292         kvfree(out);
 1293         return err;
 1294 }
 1295 
 1296 static int mlx5_modify_eswitch_vport_context(struct mlx5_core_dev *mdev,
 1297                                              u16 vport, void *in, int inlen)
 1298 {
 1299         u32 out[MLX5_ST_SZ_DW(modify_esw_vport_context_out)] = {0};
 1300         int err;
 1301 
 1302         MLX5_SET(modify_esw_vport_context_in, in, vport_number, vport);
 1303         if (vport)
 1304                 MLX5_SET(modify_esw_vport_context_in, in, other_vport, 1);
 1305 
 1306         MLX5_SET(modify_esw_vport_context_in, in, opcode,
 1307                  MLX5_CMD_OP_MODIFY_ESW_VPORT_CONTEXT);
 1308 
 1309         err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
 1310         if (err)
 1311                 mlx5_core_warn(mdev, "MLX5_CMD_OP_MODIFY_ESW_VPORT_CONTEXT failed\n");
 1312 
 1313         return err;
 1314 }
 1315 
 1316 int mlx5_set_eswitch_cvlan_info(struct mlx5_core_dev *mdev, u8 vport,
 1317                                 u8 insert_mode, u8 strip_mode,
 1318                                 u16 vlan, u8 cfi, u8 pcp)
 1319 {
 1320         u32 in[MLX5_ST_SZ_DW(modify_esw_vport_context_in)];
 1321 
 1322         memset(in, 0, sizeof(in));
 1323 
 1324         if (insert_mode != MLX5_MODIFY_ESW_VPORT_CONTEXT_CVLAN_INSERT_NONE) {
 1325                 MLX5_SET(modify_esw_vport_context_in, in,
 1326                          esw_vport_context.cvlan_cfi, cfi);
 1327                 MLX5_SET(modify_esw_vport_context_in, in,
 1328                          esw_vport_context.cvlan_pcp, pcp);
 1329                 MLX5_SET(modify_esw_vport_context_in, in,
 1330                          esw_vport_context.cvlan_id, vlan);
 1331         }
 1332 
 1333         MLX5_SET(modify_esw_vport_context_in, in,
 1334                  esw_vport_context.vport_cvlan_insert, insert_mode);
 1335 
 1336         MLX5_SET(modify_esw_vport_context_in, in,
 1337                  esw_vport_context.vport_cvlan_strip, strip_mode);
 1338 
 1339         MLX5_SET(modify_esw_vport_context_in, in, field_select,
 1340                  MLX5_MODIFY_ESW_VPORT_CONTEXT_FIELD_SELECT_CVLAN_STRIP |
 1341                  MLX5_MODIFY_ESW_VPORT_CONTEXT_FIELD_SELECT_CVLAN_INSERT);
 1342 
 1343         return mlx5_modify_eswitch_vport_context(mdev, vport, in, sizeof(in));
 1344 }
 1345 EXPORT_SYMBOL_GPL(mlx5_set_eswitch_cvlan_info);
 1346 
 1347 int mlx5_query_vport_mtu(struct mlx5_core_dev *mdev, int *mtu)
 1348 {
 1349         u32 *out;
 1350         u32 outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
 1351         int err;
 1352 
 1353         out = mlx5_vzalloc(outlen);
 1354         if (!out)
 1355                 return -ENOMEM;
 1356 
 1357         err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
 1358         if (err)
 1359                 goto out;
 1360 
 1361         *mtu = MLX5_GET(query_nic_vport_context_out, out,
 1362                         nic_vport_context.mtu);
 1363 
 1364 out:
 1365         kvfree(out);
 1366         return err;
 1367 }
 1368 EXPORT_SYMBOL_GPL(mlx5_query_vport_mtu);
 1369 
 1370 int mlx5_set_vport_mtu(struct mlx5_core_dev *mdev, int mtu)
 1371 {
 1372         u32 *in;
 1373         u32 inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
 1374         int err;
 1375 
 1376         in = mlx5_vzalloc(inlen);
 1377         if (!in)
 1378                 return -ENOMEM;
 1379 
 1380         MLX5_SET(modify_nic_vport_context_in, in, field_select.mtu, 1);
 1381         MLX5_SET(modify_nic_vport_context_in, in, nic_vport_context.mtu, mtu);
 1382 
 1383         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
 1384 
 1385         kvfree(in);
 1386         return err;
 1387 }
 1388 EXPORT_SYMBOL_GPL(mlx5_set_vport_mtu);
 1389 
 1390 static int mlx5_query_vport_min_wqe_header(struct mlx5_core_dev *mdev,
 1391                                            int *min_header)
 1392 {
 1393         u32 *out;
 1394         u32 outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
 1395         int err;
 1396 
 1397         out = mlx5_vzalloc(outlen);
 1398         if (!out)
 1399                 return -ENOMEM;
 1400 
 1401         err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
 1402         if (err)
 1403                 goto out;
 1404 
 1405         *min_header = MLX5_GET(query_nic_vport_context_out, out,
 1406                                nic_vport_context.min_wqe_inline_mode);
 1407 
 1408 out:
 1409         kvfree(out);
 1410         return err;
 1411 }
 1412 
 1413 int mlx5_set_vport_min_wqe_header(struct mlx5_core_dev *mdev,
 1414                                   u8 vport, int min_header)
 1415 {
 1416         u32 *in;
 1417         u32 inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
 1418         int err;
 1419 
 1420         in = mlx5_vzalloc(inlen);
 1421         if (!in)
 1422                 return -ENOMEM;
 1423 
 1424         MLX5_SET(modify_nic_vport_context_in, in,
 1425                  field_select.min_wqe_inline_mode, 1);
 1426         MLX5_SET(modify_nic_vport_context_in, in,
 1427                  nic_vport_context.min_wqe_inline_mode, min_header);
 1428         MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
 1429         MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
 1430 
 1431         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
 1432 
 1433         kvfree(in);
 1434         return err;
 1435 }
 1436 EXPORT_SYMBOL_GPL(mlx5_set_vport_min_wqe_header);
 1437 
 1438 int mlx5_query_min_wqe_header(struct mlx5_core_dev *dev, int *min_header)
 1439 {
 1440         switch (MLX5_CAP_GEN(dev, port_type)) {
 1441         case MLX5_CMD_HCA_CAP_PORT_TYPE_IB:
 1442                 return mlx5_query_hca_min_wqe_header(dev, min_header);
 1443 
 1444         case MLX5_CMD_HCA_CAP_PORT_TYPE_ETHERNET:
 1445                 return mlx5_query_vport_min_wqe_header(dev, min_header);
 1446 
 1447         default:
 1448                 return -EINVAL;
 1449         }
 1450 }
 1451 EXPORT_SYMBOL_GPL(mlx5_query_min_wqe_header);
 1452 
 1453 int mlx5_query_nic_vport_promisc(struct mlx5_core_dev *mdev,
 1454                                  u16 vport,
 1455                                  int *promisc_uc,
 1456                                  int *promisc_mc,
 1457                                  int *promisc_all)
 1458 {
 1459         u32 *out;
 1460         int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
 1461         int err;
 1462 
 1463         out = kzalloc(outlen, GFP_KERNEL);
 1464         if (!out)
 1465                 return -ENOMEM;
 1466 
 1467         err = mlx5_query_nic_vport_context(mdev, vport, out, outlen);
 1468         if (err)
 1469                 goto out;
 1470 
 1471         *promisc_uc = MLX5_GET(query_nic_vport_context_out, out,
 1472                                nic_vport_context.promisc_uc);
 1473         *promisc_mc = MLX5_GET(query_nic_vport_context_out, out,
 1474                                nic_vport_context.promisc_mc);
 1475         *promisc_all = MLX5_GET(query_nic_vport_context_out, out,
 1476                                 nic_vport_context.promisc_all);
 1477 
 1478 out:
 1479         kfree(out);
 1480         return err;
 1481 }
 1482 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_promisc);
 1483 
 1484 int mlx5_modify_nic_vport_promisc(struct mlx5_core_dev *mdev,
 1485                                   int promisc_uc,
 1486                                   int promisc_mc,
 1487                                   int promisc_all)
 1488 {
 1489         void *in;
 1490         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
 1491         int err;
 1492 
 1493         in = mlx5_vzalloc(inlen);
 1494         if (!in) {
 1495                 mlx5_core_err(mdev, "failed to allocate inbox\n");
 1496                 return -ENOMEM;
 1497         }
 1498 
 1499         MLX5_SET(modify_nic_vport_context_in, in, field_select.promisc, 1);
 1500         MLX5_SET(modify_nic_vport_context_in, in,
 1501                  nic_vport_context.promisc_uc, promisc_uc);
 1502         MLX5_SET(modify_nic_vport_context_in, in,
 1503                  nic_vport_context.promisc_mc, promisc_mc);
 1504         MLX5_SET(modify_nic_vport_context_in, in,
 1505                  nic_vport_context.promisc_all, promisc_all);
 1506 
 1507         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
 1508         kvfree(in);
 1509         return err;
 1510 }
 1511 EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_promisc);
 1512 
 1513 int mlx5_nic_vport_update_local_lb(struct mlx5_core_dev *mdev, bool enable)
 1514 {
 1515         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
 1516         void *in;
 1517         int err;
 1518 
 1519         if (!MLX5_CAP_GEN(mdev, disable_local_lb_mc) &&
 1520             !MLX5_CAP_GEN(mdev, disable_local_lb_uc))
 1521                 return 0;
 1522 
 1523         in = kvzalloc(inlen, GFP_KERNEL);
 1524         if (!in)
 1525                 return -ENOMEM;
 1526 
 1527         MLX5_SET(modify_nic_vport_context_in, in,
 1528                  nic_vport_context.disable_mc_local_lb, !enable);
 1529         MLX5_SET(modify_nic_vport_context_in, in,
 1530                  nic_vport_context.disable_uc_local_lb, !enable);
 1531 
 1532         if (MLX5_CAP_GEN(mdev, disable_local_lb_mc))
 1533                 MLX5_SET(modify_nic_vport_context_in, in,
 1534                          field_select.disable_mc_local_lb, 1);
 1535 
 1536         if (MLX5_CAP_GEN(mdev, disable_local_lb_uc))
 1537                 MLX5_SET(modify_nic_vport_context_in, in,
 1538                          field_select.disable_uc_local_lb, 1);
 1539 
 1540         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
 1541 
 1542         if (!err)
 1543                 mlx5_core_dbg(mdev, "%s local_lb\n",
 1544                               enable ? "enable" : "disable");
 1545 
 1546         kvfree(in);
 1547         return err;
 1548 }
 1549 EXPORT_SYMBOL_GPL(mlx5_nic_vport_update_local_lb);
 1550 
 1551 int mlx5_nic_vport_modify_local_lb(struct mlx5_core_dev *mdev,
 1552                                    enum mlx5_local_lb_selection selection,
 1553                                    u8 value)
 1554 {
 1555         void *in;
 1556         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
 1557         int err;
 1558 
 1559         in = mlx5_vzalloc(inlen);
 1560         if (!in) {
 1561                 mlx5_core_warn(mdev, "failed to allocate inbox\n");
 1562                 return -ENOMEM;
 1563         }
 1564 
 1565         MLX5_SET(modify_nic_vport_context_in, in, vport_number, 0);
 1566 
 1567         if (selection == MLX5_LOCAL_MC_LB) {
 1568                 MLX5_SET(modify_nic_vport_context_in, in,
 1569                          field_select.disable_mc_local_lb, 1);
 1570                 MLX5_SET(modify_nic_vport_context_in, in,
 1571                          nic_vport_context.disable_mc_local_lb,
 1572                          value);
 1573         } else {
 1574                 MLX5_SET(modify_nic_vport_context_in, in,
 1575                          field_select.disable_uc_local_lb, 1);
 1576                 MLX5_SET(modify_nic_vport_context_in, in,
 1577                          nic_vport_context.disable_uc_local_lb,
 1578                          value);
 1579         }
 1580 
 1581         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
 1582 
 1583         kvfree(in);
 1584         return err;
 1585 }
 1586 EXPORT_SYMBOL_GPL(mlx5_nic_vport_modify_local_lb);
 1587 
 1588 int mlx5_nic_vport_query_local_lb(struct mlx5_core_dev *mdev,
 1589                                   enum mlx5_local_lb_selection selection,
 1590                                   u8 *value)
 1591 {
 1592         void *out;
 1593         int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
 1594         int err;
 1595 
 1596         out = kzalloc(outlen, GFP_KERNEL);
 1597         if (!out)
 1598                 return -ENOMEM;
 1599 
 1600         err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
 1601         if (err)
 1602                 goto done;
 1603 
 1604         if (selection == MLX5_LOCAL_MC_LB)
 1605                 *value = MLX5_GET(query_nic_vport_context_out, out,
 1606                                   nic_vport_context.disable_mc_local_lb);
 1607         else
 1608                 *value = MLX5_GET(query_nic_vport_context_out, out,
 1609                                   nic_vport_context.disable_uc_local_lb);
 1610 
 1611 done:
 1612         kfree(out);
 1613         return err;
 1614 }
 1615 EXPORT_SYMBOL_GPL(mlx5_nic_vport_query_local_lb);
 1616 
 1617 int mlx5_query_vport_counter(struct mlx5_core_dev *dev,
 1618                              u8 port_num, u16 vport_num,
 1619                              void *out, int out_size)
 1620 {
 1621         int in_sz = MLX5_ST_SZ_BYTES(query_vport_counter_in);
 1622         int is_group_manager;
 1623         void *in;
 1624         int err;
 1625 
 1626         is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
 1627 
 1628         in = mlx5_vzalloc(in_sz);
 1629         if (!in)
 1630                 return -ENOMEM;
 1631 
 1632         MLX5_SET(query_vport_counter_in, in, opcode,
 1633                  MLX5_CMD_OP_QUERY_VPORT_COUNTER);
 1634         if (vport_num) {
 1635                 if (is_group_manager) {
 1636                         MLX5_SET(query_vport_counter_in, in, other_vport, 1);
 1637                         MLX5_SET(query_vport_counter_in, in, vport_number,
 1638                                  vport_num);
 1639                 } else {
 1640                         err = -EPERM;
 1641                         goto ex;
 1642                 }
 1643         }
 1644         if (MLX5_CAP_GEN(dev, num_ports) == 2)
 1645                 MLX5_SET(query_vport_counter_in, in, port_num, port_num);
 1646 
 1647         err = mlx5_cmd_exec(dev, in, in_sz, out,  out_size);
 1648 
 1649 ex:
 1650         kvfree(in);
 1651         return err;
 1652 }
 1653 EXPORT_SYMBOL_GPL(mlx5_query_vport_counter);
 1654 
 1655 int mlx5_get_vport_counters(struct mlx5_core_dev *dev, u8 port_num,
 1656                             struct mlx5_vport_counters *vc)
 1657 {
 1658         int out_sz = MLX5_ST_SZ_BYTES(query_vport_counter_out);
 1659         void *out;
 1660         int err;
 1661 
 1662         out = mlx5_vzalloc(out_sz);
 1663         if (!out)
 1664                 return -ENOMEM;
 1665 
 1666         err = mlx5_query_vport_counter(dev, port_num, 0, out, out_sz);
 1667         if (err)
 1668                 goto ex;
 1669 
 1670         vc->received_errors.packets =
 1671                 MLX5_GET64(query_vport_counter_out,
 1672                            out, received_errors.packets);
 1673         vc->received_errors.octets =
 1674                 MLX5_GET64(query_vport_counter_out,
 1675                            out, received_errors.octets);
 1676         vc->transmit_errors.packets =
 1677                 MLX5_GET64(query_vport_counter_out,
 1678                            out, transmit_errors.packets);
 1679         vc->transmit_errors.octets =
 1680                 MLX5_GET64(query_vport_counter_out,
 1681                            out, transmit_errors.octets);
 1682         vc->received_ib_unicast.packets =
 1683                 MLX5_GET64(query_vport_counter_out,
 1684                            out, received_ib_unicast.packets);
 1685         vc->received_ib_unicast.octets =
 1686                 MLX5_GET64(query_vport_counter_out,
 1687                            out, received_ib_unicast.octets);
 1688         vc->transmitted_ib_unicast.packets =
 1689                 MLX5_GET64(query_vport_counter_out,
 1690                            out, transmitted_ib_unicast.packets);
 1691         vc->transmitted_ib_unicast.octets =
 1692                 MLX5_GET64(query_vport_counter_out,
 1693                            out, transmitted_ib_unicast.octets);
 1694         vc->received_ib_multicast.packets =
 1695                 MLX5_GET64(query_vport_counter_out,
 1696                            out, received_ib_multicast.packets);
 1697         vc->received_ib_multicast.octets =
 1698                 MLX5_GET64(query_vport_counter_out,
 1699                            out, received_ib_multicast.octets);
 1700         vc->transmitted_ib_multicast.packets =
 1701                 MLX5_GET64(query_vport_counter_out,
 1702                            out, transmitted_ib_multicast.packets);
 1703         vc->transmitted_ib_multicast.octets =
 1704                 MLX5_GET64(query_vport_counter_out,
 1705                            out, transmitted_ib_multicast.octets);
 1706         vc->received_eth_broadcast.packets =
 1707                 MLX5_GET64(query_vport_counter_out,
 1708                            out, received_eth_broadcast.packets);
 1709         vc->received_eth_broadcast.octets =
 1710                 MLX5_GET64(query_vport_counter_out,
 1711                            out, received_eth_broadcast.octets);
 1712         vc->transmitted_eth_broadcast.packets =
 1713                 MLX5_GET64(query_vport_counter_out,
 1714                            out, transmitted_eth_broadcast.packets);
 1715         vc->transmitted_eth_broadcast.octets =
 1716                 MLX5_GET64(query_vport_counter_out,
 1717                            out, transmitted_eth_broadcast.octets);
 1718         vc->received_eth_unicast.octets =
 1719                 MLX5_GET64(query_vport_counter_out,
 1720                            out, received_eth_unicast.octets);
 1721         vc->received_eth_unicast.packets =
 1722                 MLX5_GET64(query_vport_counter_out,
 1723                            out, received_eth_unicast.packets);
 1724         vc->transmitted_eth_unicast.octets =
 1725                 MLX5_GET64(query_vport_counter_out,
 1726                            out, transmitted_eth_unicast.octets);
 1727         vc->transmitted_eth_unicast.packets =
 1728                 MLX5_GET64(query_vport_counter_out,
 1729                            out, transmitted_eth_unicast.packets);
 1730         vc->received_eth_multicast.octets =
 1731                 MLX5_GET64(query_vport_counter_out,
 1732                            out, received_eth_multicast.octets);
 1733         vc->received_eth_multicast.packets =
 1734                 MLX5_GET64(query_vport_counter_out,
 1735                            out, received_eth_multicast.packets);
 1736         vc->transmitted_eth_multicast.octets =
 1737                 MLX5_GET64(query_vport_counter_out,
 1738                            out, transmitted_eth_multicast.octets);
 1739         vc->transmitted_eth_multicast.packets =
 1740                 MLX5_GET64(query_vport_counter_out,
 1741                            out, transmitted_eth_multicast.packets);
 1742 
 1743 ex:
 1744         kvfree(out);
 1745         return err;
 1746 }
 1747 
 1748 int mlx5_query_vport_system_image_guid(struct mlx5_core_dev *dev,
 1749                                        u64 *sys_image_guid)
 1750 {
 1751         switch (MLX5_CAP_GEN(dev, port_type)) {
 1752         case MLX5_CMD_HCA_CAP_PORT_TYPE_IB:
 1753                 return mlx5_query_hca_vport_system_image_guid(dev,
 1754                                                               sys_image_guid);
 1755 
 1756         case MLX5_CMD_HCA_CAP_PORT_TYPE_ETHERNET:
 1757                 return mlx5_query_nic_vport_system_image_guid(dev,
 1758                                                               sys_image_guid);
 1759 
 1760         default:
 1761                 return -EINVAL;
 1762         }
 1763 }
 1764 EXPORT_SYMBOL_GPL(mlx5_query_vport_system_image_guid);
 1765 
 1766 int mlx5_query_vport_node_guid(struct mlx5_core_dev *dev, u64 *node_guid)
 1767 {
 1768         switch (MLX5_CAP_GEN(dev, port_type)) {
 1769         case MLX5_CMD_HCA_CAP_PORT_TYPE_IB:
 1770                 return mlx5_query_hca_vport_node_guid(dev, node_guid);
 1771 
 1772         case MLX5_CMD_HCA_CAP_PORT_TYPE_ETHERNET:
 1773                 return mlx5_query_nic_vport_node_guid(dev, node_guid);
 1774 
 1775         default:
 1776                 return -EINVAL;
 1777         }
 1778 }
 1779 EXPORT_SYMBOL_GPL(mlx5_query_vport_node_guid);
 1780 
 1781 int mlx5_query_vport_port_guid(struct mlx5_core_dev *dev, u64 *port_guid)
 1782 {
 1783         switch (MLX5_CAP_GEN(dev, port_type)) {
 1784         case MLX5_CMD_HCA_CAP_PORT_TYPE_IB:
 1785                 return mlx5_query_hca_vport_port_guid(dev, port_guid);
 1786 
 1787         case MLX5_CMD_HCA_CAP_PORT_TYPE_ETHERNET:
 1788                 return mlx5_query_nic_vport_port_guid(dev, port_guid);
 1789 
 1790         default:
 1791                 return -EINVAL;
 1792         }
 1793 }
 1794 EXPORT_SYMBOL_GPL(mlx5_query_vport_port_guid);
 1795 
 1796 int mlx5_query_hca_vport_state(struct mlx5_core_dev *dev, u8 *vport_state)
 1797 {
 1798         u32 *out;
 1799         int outlen = MLX5_ST_SZ_BYTES(query_hca_vport_context_out);
 1800         int err;
 1801 
 1802         out = mlx5_vzalloc(outlen);
 1803         if (!out)
 1804                 return -ENOMEM;
 1805 
 1806         err = mlx5_query_hca_vport_context(dev, 1, 0, out, outlen);
 1807         if (err)
 1808                 goto out;
 1809 
 1810         *vport_state = MLX5_GET(query_hca_vport_context_out, out,
 1811                                 hca_vport_context.vport_state);
 1812 
 1813 out:
 1814         kvfree(out);
 1815         return err;
 1816 }
 1817 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_state);
 1818 
 1819 int mlx5_core_query_ib_ppcnt(struct mlx5_core_dev *dev,
 1820                              u8 port_num, void *out, size_t sz)
 1821 {
 1822         u32 *in;
 1823         int err;
 1824 
 1825         in  = mlx5_vzalloc(sz);
 1826         if (!in) {
 1827                 err = -ENOMEM;
 1828                 return err;
 1829         }
 1830 
 1831         MLX5_SET(ppcnt_reg, in, local_port, port_num);
 1832 
 1833         MLX5_SET(ppcnt_reg, in, grp, MLX5_INFINIBAND_PORT_COUNTERS_GROUP);
 1834         err = mlx5_core_access_reg(dev, in, sz, out,
 1835                                    sz, MLX5_REG_PPCNT, 0, 0);
 1836 
 1837         kvfree(in);
 1838         return err;
 1839 }

Cache object: 0b9c4704a31e3c536207120540bfed81


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.