root/drivers/net/ethernet/mellanox/mlx5/core/vport.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _mlx5_query_vport_state
  2. mlx5_query_vport_state
  3. mlx5_modify_vport_admin_state
  4. mlx5_query_nic_vport_context
  5. mlx5_modify_nic_vport_context
  6. mlx5_query_nic_vport_min_inline
  7. mlx5_query_min_inline
  8. mlx5_modify_nic_vport_min_inline
  9. mlx5_query_nic_vport_mac_address
  10. mlx5_query_mac_address
  11. mlx5_modify_nic_vport_mac_address
  12. mlx5_query_nic_vport_mtu
  13. mlx5_modify_nic_vport_mtu
  14. mlx5_query_nic_vport_mac_list
  15. mlx5_modify_nic_vport_mac_list
  16. mlx5_modify_nic_vport_vlans
  17. mlx5_query_nic_vport_system_image_guid
  18. mlx5_query_nic_vport_node_guid
  19. mlx5_modify_nic_vport_node_guid
  20. mlx5_query_nic_vport_qkey_viol_cntr
  21. mlx5_query_hca_vport_gid
  22. mlx5_query_hca_vport_pkey
  23. mlx5_query_hca_vport_context
  24. mlx5_query_hca_vport_system_image_guid
  25. mlx5_query_hca_vport_node_guid
  26. mlx5_query_nic_vport_promisc
  27. mlx5_modify_nic_vport_promisc
  28. mlx5_nic_vport_update_local_lb
  29. mlx5_nic_vport_query_local_lb
  30. mlx5_nic_vport_update_roce_state
  31. mlx5_nic_vport_enable_roce
  32. mlx5_nic_vport_disable_roce
  33. mlx5_core_query_vport_counter
  34. mlx5_query_vport_down_stats
  35. mlx5_core_modify_hca_vport_context
  36. mlx5_nic_vport_affiliate_multiport
  37. mlx5_nic_vport_unaffiliate_multiport
  38. mlx5_query_nic_system_image_guid
  39. mlx5_eswitch_get_total_vports

   1 /*
   2  * Copyright (c) 2013-2015, Mellanox Technologies, Ltd.  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/export.h>
  34 #include <linux/etherdevice.h>
  35 #include <linux/mlx5/driver.h>
  36 #include <linux/mlx5/vport.h>
  37 #include <linux/mlx5/eswitch.h>
  38 #include "mlx5_core.h"
  39 
  40 /* Mutex to hold while enabling or disabling RoCE */
  41 static DEFINE_MUTEX(mlx5_roce_en_lock);
  42 
  43 static int _mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod,
  44                                    u16 vport, u32 *out, int outlen)
  45 {
  46         u32 in[MLX5_ST_SZ_DW(query_vport_state_in)] = {0};
  47 
  48         MLX5_SET(query_vport_state_in, in, opcode,
  49                  MLX5_CMD_OP_QUERY_VPORT_STATE);
  50         MLX5_SET(query_vport_state_in, in, op_mod, opmod);
  51         MLX5_SET(query_vport_state_in, in, vport_number, vport);
  52         if (vport)
  53                 MLX5_SET(query_vport_state_in, in, other_vport, 1);
  54 
  55         return mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen);
  56 }
  57 
  58 u8 mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod, u16 vport)
  59 {
  60         u32 out[MLX5_ST_SZ_DW(query_vport_state_out)] = {0};
  61 
  62         _mlx5_query_vport_state(mdev, opmod, vport, out, sizeof(out));
  63 
  64         return MLX5_GET(query_vport_state_out, out, state);
  65 }
  66 
  67 int mlx5_modify_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod,
  68                                   u16 vport, u8 other_vport, u8 state)
  69 {
  70         u32 in[MLX5_ST_SZ_DW(modify_vport_state_in)]   = {0};
  71         u32 out[MLX5_ST_SZ_DW(modify_vport_state_out)] = {0};
  72 
  73         MLX5_SET(modify_vport_state_in, in, opcode,
  74                  MLX5_CMD_OP_MODIFY_VPORT_STATE);
  75         MLX5_SET(modify_vport_state_in, in, op_mod, opmod);
  76         MLX5_SET(modify_vport_state_in, in, vport_number, vport);
  77         MLX5_SET(modify_vport_state_in, in, other_vport, other_vport);
  78         MLX5_SET(modify_vport_state_in, in, admin_state, state);
  79 
  80         return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
  81 }
  82 
  83 static int mlx5_query_nic_vport_context(struct mlx5_core_dev *mdev, u16 vport,
  84                                         u32 *out, int outlen)
  85 {
  86         u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
  87 
  88         MLX5_SET(query_nic_vport_context_in, in, opcode,
  89                  MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
  90         MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
  91         if (vport)
  92                 MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);
  93 
  94         return mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen);
  95 }
  96 
  97 static int mlx5_modify_nic_vport_context(struct mlx5_core_dev *mdev, void *in,
  98                                          int inlen)
  99 {
 100         u32 out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)] = {0};
 101 
 102         MLX5_SET(modify_nic_vport_context_in, in, opcode,
 103                  MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
 104         return mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out));
 105 }
 106 
 107 int mlx5_query_nic_vport_min_inline(struct mlx5_core_dev *mdev,
 108                                     u16 vport, u8 *min_inline)
 109 {
 110         u32 out[MLX5_ST_SZ_DW(query_nic_vport_context_out)] = {0};
 111         int err;
 112 
 113         err = mlx5_query_nic_vport_context(mdev, vport, out, sizeof(out));
 114         if (!err)
 115                 *min_inline = MLX5_GET(query_nic_vport_context_out, out,
 116                                        nic_vport_context.min_wqe_inline_mode);
 117         return err;
 118 }
 119 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_min_inline);
 120 
 121 void mlx5_query_min_inline(struct mlx5_core_dev *mdev,
 122                            u8 *min_inline_mode)
 123 {
 124         switch (MLX5_CAP_ETH(mdev, wqe_inline_mode)) {
 125         case MLX5_CAP_INLINE_MODE_VPORT_CONTEXT:
 126                 if (!mlx5_query_nic_vport_min_inline(mdev, 0, min_inline_mode))
 127                         break;
 128                 /* fall through */
 129         case MLX5_CAP_INLINE_MODE_L2:
 130                 *min_inline_mode = MLX5_INLINE_MODE_L2;
 131                 break;
 132         case MLX5_CAP_INLINE_MODE_NOT_REQUIRED:
 133                 *min_inline_mode = MLX5_INLINE_MODE_NONE;
 134                 break;
 135         }
 136 }
 137 EXPORT_SYMBOL_GPL(mlx5_query_min_inline);
 138 
 139 int mlx5_modify_nic_vport_min_inline(struct mlx5_core_dev *mdev,
 140                                      u16 vport, u8 min_inline)
 141 {
 142         u32 in[MLX5_ST_SZ_DW(modify_nic_vport_context_in)] = {0};
 143         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
 144         void *nic_vport_ctx;
 145 
 146         MLX5_SET(modify_nic_vport_context_in, in,
 147                  field_select.min_inline, 1);
 148         MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
 149         MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
 150 
 151         nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in,
 152                                      in, nic_vport_context);
 153         MLX5_SET(nic_vport_context, nic_vport_ctx,
 154                  min_wqe_inline_mode, min_inline);
 155 
 156         return mlx5_modify_nic_vport_context(mdev, in, inlen);
 157 }
 158 
 159 int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev,
 160                                      u16 vport, bool other, u8 *addr)
 161 {
 162         int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
 163         u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {};
 164         u8 *out_addr;
 165         u32 *out;
 166         int err;
 167 
 168         out = kvzalloc(outlen, GFP_KERNEL);
 169         if (!out)
 170                 return -ENOMEM;
 171 
 172         out_addr = MLX5_ADDR_OF(query_nic_vport_context_out, out,
 173                                 nic_vport_context.permanent_address);
 174 
 175         MLX5_SET(query_nic_vport_context_in, in, opcode,
 176                  MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
 177         MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
 178         MLX5_SET(query_nic_vport_context_in, in, other_vport, other);
 179 
 180         err = mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen);
 181         if (!err)
 182                 ether_addr_copy(addr, &out_addr[2]);
 183 
 184         kvfree(out);
 185         return err;
 186 }
 187 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_mac_address);
 188 
 189 int mlx5_query_mac_address(struct mlx5_core_dev *mdev, u8 *addr)
 190 {
 191         return mlx5_query_nic_vport_mac_address(mdev, 0, false, addr);
 192 }
 193 EXPORT_SYMBOL_GPL(mlx5_query_mac_address);
 194 
 195 int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *mdev,
 196                                       u16 vport, u8 *addr)
 197 {
 198         void *in;
 199         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
 200         int err;
 201         void *nic_vport_ctx;
 202         u8 *perm_mac;
 203 
 204         in = kvzalloc(inlen, GFP_KERNEL);
 205         if (!in)
 206                 return -ENOMEM;
 207 
 208         MLX5_SET(modify_nic_vport_context_in, in,
 209                  field_select.permanent_address, 1);
 210         MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
 211         MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
 212 
 213         nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in,
 214                                      in, nic_vport_context);
 215         perm_mac = MLX5_ADDR_OF(nic_vport_context, nic_vport_ctx,
 216                                 permanent_address);
 217 
 218         ether_addr_copy(&perm_mac[2], addr);
 219 
 220         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
 221 
 222         kvfree(in);
 223 
 224         return err;
 225 }
 226 EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mac_address);
 227 
 228 int mlx5_query_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 *mtu)
 229 {
 230         int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
 231         u32 *out;
 232         int err;
 233 
 234         out = kvzalloc(outlen, GFP_KERNEL);
 235         if (!out)
 236                 return -ENOMEM;
 237 
 238         err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
 239         if (!err)
 240                 *mtu = MLX5_GET(query_nic_vport_context_out, out,
 241                                 nic_vport_context.mtu);
 242 
 243         kvfree(out);
 244         return err;
 245 }
 246 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_mtu);
 247 
 248 int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu)
 249 {
 250         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
 251         void *in;
 252         int err;
 253 
 254         in = kvzalloc(inlen, GFP_KERNEL);
 255         if (!in)
 256                 return -ENOMEM;
 257 
 258         MLX5_SET(modify_nic_vport_context_in, in, field_select.mtu, 1);
 259         MLX5_SET(modify_nic_vport_context_in, in, nic_vport_context.mtu, mtu);
 260 
 261         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
 262 
 263         kvfree(in);
 264         return err;
 265 }
 266 EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mtu);
 267 
 268 int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
 269                                   u16 vport,
 270                                   enum mlx5_list_type list_type,
 271                                   u8 addr_list[][ETH_ALEN],
 272                                   int *list_size)
 273 {
 274         u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
 275         void *nic_vport_ctx;
 276         int max_list_size;
 277         int req_list_size;
 278         int out_sz;
 279         void *out;
 280         int err;
 281         int i;
 282 
 283         req_list_size = *list_size;
 284 
 285         max_list_size = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
 286                 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
 287                 1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
 288 
 289         if (req_list_size > max_list_size) {
 290                 mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
 291                                req_list_size, max_list_size);
 292                 req_list_size = max_list_size;
 293         }
 294 
 295         out_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
 296                         req_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
 297 
 298         out = kzalloc(out_sz, GFP_KERNEL);
 299         if (!out)
 300                 return -ENOMEM;
 301 
 302         MLX5_SET(query_nic_vport_context_in, in, opcode,
 303                  MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
 304         MLX5_SET(query_nic_vport_context_in, in, allowed_list_type, list_type);
 305         MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
 306         MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);
 307 
 308         err = mlx5_cmd_exec(dev, in, sizeof(in), out, out_sz);
 309         if (err)
 310                 goto out;
 311 
 312         nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
 313                                      nic_vport_context);
 314         req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
 315                                  allowed_list_size);
 316 
 317         *list_size = req_list_size;
 318         for (i = 0; i < req_list_size; i++) {
 319                 u8 *mac_addr = MLX5_ADDR_OF(nic_vport_context,
 320                                         nic_vport_ctx,
 321                                         current_uc_mac_address[i]) + 2;
 322                 ether_addr_copy(addr_list[i], mac_addr);
 323         }
 324 out:
 325         kfree(out);
 326         return err;
 327 }
 328 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_mac_list);
 329 
 330 int mlx5_modify_nic_vport_mac_list(struct mlx5_core_dev *dev,
 331                                    enum mlx5_list_type list_type,
 332                                    u8 addr_list[][ETH_ALEN],
 333                                    int list_size)
 334 {
 335         u32 out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)];
 336         void *nic_vport_ctx;
 337         int max_list_size;
 338         int in_sz;
 339         void *in;
 340         int err;
 341         int i;
 342 
 343         max_list_size = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
 344                  1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
 345                  1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
 346 
 347         if (list_size > max_list_size)
 348                 return -ENOSPC;
 349 
 350         in_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
 351                 list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
 352 
 353         memset(out, 0, sizeof(out));
 354         in = kzalloc(in_sz, GFP_KERNEL);
 355         if (!in)
 356                 return -ENOMEM;
 357 
 358         MLX5_SET(modify_nic_vport_context_in, in, opcode,
 359                  MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
 360         MLX5_SET(modify_nic_vport_context_in, in,
 361                  field_select.addresses_list, 1);
 362 
 363         nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in,
 364                                      nic_vport_context);
 365 
 366         MLX5_SET(nic_vport_context, nic_vport_ctx,
 367                  allowed_list_type, list_type);
 368         MLX5_SET(nic_vport_context, nic_vport_ctx,
 369                  allowed_list_size, list_size);
 370 
 371         for (i = 0; i < list_size; i++) {
 372                 u8 *curr_mac = MLX5_ADDR_OF(nic_vport_context,
 373                                             nic_vport_ctx,
 374                                             current_uc_mac_address[i]) + 2;
 375                 ether_addr_copy(curr_mac, addr_list[i]);
 376         }
 377 
 378         err = mlx5_cmd_exec(dev, in, in_sz, out, sizeof(out));
 379         kfree(in);
 380         return err;
 381 }
 382 EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mac_list);
 383 
 384 int mlx5_modify_nic_vport_vlans(struct mlx5_core_dev *dev,
 385                                 u16 vlans[],
 386                                 int list_size)
 387 {
 388         u32 out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)];
 389         void *nic_vport_ctx;
 390         int max_list_size;
 391         int in_sz;
 392         void *in;
 393         int err;
 394         int i;
 395 
 396         max_list_size = 1 << MLX5_CAP_GEN(dev, log_max_vlan_list);
 397 
 398         if (list_size > max_list_size)
 399                 return -ENOSPC;
 400 
 401         in_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
 402                 list_size * MLX5_ST_SZ_BYTES(vlan_layout);
 403 
 404         memset(out, 0, sizeof(out));
 405         in = kzalloc(in_sz, GFP_KERNEL);
 406         if (!in)
 407                 return -ENOMEM;
 408 
 409         MLX5_SET(modify_nic_vport_context_in, in, opcode,
 410                  MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
 411         MLX5_SET(modify_nic_vport_context_in, in,
 412                  field_select.addresses_list, 1);
 413 
 414         nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in,
 415                                      nic_vport_context);
 416 
 417         MLX5_SET(nic_vport_context, nic_vport_ctx,
 418                  allowed_list_type, MLX5_NVPRT_LIST_TYPE_VLAN);
 419         MLX5_SET(nic_vport_context, nic_vport_ctx,
 420                  allowed_list_size, list_size);
 421 
 422         for (i = 0; i < list_size; i++) {
 423                 void *vlan_addr = MLX5_ADDR_OF(nic_vport_context,
 424                                                nic_vport_ctx,
 425                                                current_uc_mac_address[i]);
 426                 MLX5_SET(vlan_layout, vlan_addr, vlan, vlans[i]);
 427         }
 428 
 429         err = mlx5_cmd_exec(dev, in, in_sz, out, sizeof(out));
 430         kfree(in);
 431         return err;
 432 }
 433 EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_vlans);
 434 
 435 int mlx5_query_nic_vport_system_image_guid(struct mlx5_core_dev *mdev,
 436                                            u64 *system_image_guid)
 437 {
 438         u32 *out;
 439         int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
 440 
 441         out = kvzalloc(outlen, GFP_KERNEL);
 442         if (!out)
 443                 return -ENOMEM;
 444 
 445         mlx5_query_nic_vport_context(mdev, 0, out, outlen);
 446 
 447         *system_image_guid = MLX5_GET64(query_nic_vport_context_out, out,
 448                                         nic_vport_context.system_image_guid);
 449 
 450         kvfree(out);
 451 
 452         return 0;
 453 }
 454 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_system_image_guid);
 455 
 456 int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid)
 457 {
 458         u32 *out;
 459         int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
 460 
 461         out = kvzalloc(outlen, GFP_KERNEL);
 462         if (!out)
 463                 return -ENOMEM;
 464 
 465         mlx5_query_nic_vport_context(mdev, 0, out, outlen);
 466 
 467         *node_guid = MLX5_GET64(query_nic_vport_context_out, out,
 468                                 nic_vport_context.node_guid);
 469 
 470         kvfree(out);
 471 
 472         return 0;
 473 }
 474 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_node_guid);
 475 
 476 int mlx5_modify_nic_vport_node_guid(struct mlx5_core_dev *mdev,
 477                                     u16 vport, u64 node_guid)
 478 {
 479         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
 480         void *nic_vport_context;
 481         void *in;
 482         int err;
 483 
 484         if (!vport)
 485                 return -EINVAL;
 486         if (!MLX5_CAP_GEN(mdev, vport_group_manager))
 487                 return -EACCES;
 488 
 489         in = kvzalloc(inlen, GFP_KERNEL);
 490         if (!in)
 491                 return -ENOMEM;
 492 
 493         MLX5_SET(modify_nic_vport_context_in, in,
 494                  field_select.node_guid, 1);
 495         MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
 496         MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
 497 
 498         nic_vport_context = MLX5_ADDR_OF(modify_nic_vport_context_in,
 499                                          in, nic_vport_context);
 500         MLX5_SET64(nic_vport_context, nic_vport_context, node_guid, node_guid);
 501 
 502         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
 503 
 504         kvfree(in);
 505 
 506         return err;
 507 }
 508 
 509 int mlx5_query_nic_vport_qkey_viol_cntr(struct mlx5_core_dev *mdev,
 510                                         u16 *qkey_viol_cntr)
 511 {
 512         u32 *out;
 513         int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
 514 
 515         out = kvzalloc(outlen, GFP_KERNEL);
 516         if (!out)
 517                 return -ENOMEM;
 518 
 519         mlx5_query_nic_vport_context(mdev, 0, out, outlen);
 520 
 521         *qkey_viol_cntr = MLX5_GET(query_nic_vport_context_out, out,
 522                                    nic_vport_context.qkey_violation_counter);
 523 
 524         kvfree(out);
 525 
 526         return 0;
 527 }
 528 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_qkey_viol_cntr);
 529 
 530 int mlx5_query_hca_vport_gid(struct mlx5_core_dev *dev, u8 other_vport,
 531                              u8 port_num, u16  vf_num, u16 gid_index,
 532                              union ib_gid *gid)
 533 {
 534         int in_sz = MLX5_ST_SZ_BYTES(query_hca_vport_gid_in);
 535         int out_sz = MLX5_ST_SZ_BYTES(query_hca_vport_gid_out);
 536         int is_group_manager;
 537         void *out = NULL;
 538         void *in = NULL;
 539         union ib_gid *tmp;
 540         int tbsz;
 541         int nout;
 542         int err;
 543 
 544         is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
 545         tbsz = mlx5_get_gid_table_len(MLX5_CAP_GEN(dev, gid_table_size));
 546         mlx5_core_dbg(dev, "vf_num %d, index %d, gid_table_size %d\n",
 547                       vf_num, gid_index, tbsz);
 548 
 549         if (gid_index > tbsz && gid_index != 0xffff)
 550                 return -EINVAL;
 551 
 552         if (gid_index == 0xffff)
 553                 nout = tbsz;
 554         else
 555                 nout = 1;
 556 
 557         out_sz += nout * sizeof(*gid);
 558 
 559         in = kzalloc(in_sz, GFP_KERNEL);
 560         out = kzalloc(out_sz, GFP_KERNEL);
 561         if (!in || !out) {
 562                 err = -ENOMEM;
 563                 goto out;
 564         }
 565 
 566         MLX5_SET(query_hca_vport_gid_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_VPORT_GID);
 567         if (other_vport) {
 568                 if (is_group_manager) {
 569                         MLX5_SET(query_hca_vport_gid_in, in, vport_number, vf_num);
 570                         MLX5_SET(query_hca_vport_gid_in, in, other_vport, 1);
 571                 } else {
 572                         err = -EPERM;
 573                         goto out;
 574                 }
 575         }
 576         MLX5_SET(query_hca_vport_gid_in, in, gid_index, gid_index);
 577 
 578         if (MLX5_CAP_GEN(dev, num_ports) == 2)
 579                 MLX5_SET(query_hca_vport_gid_in, in, port_num, port_num);
 580 
 581         err = mlx5_cmd_exec(dev, in, in_sz, out, out_sz);
 582         if (err)
 583                 goto out;
 584 
 585         tmp = out + MLX5_ST_SZ_BYTES(query_hca_vport_gid_out);
 586         gid->global.subnet_prefix = tmp->global.subnet_prefix;
 587         gid->global.interface_id = tmp->global.interface_id;
 588 
 589 out:
 590         kfree(in);
 591         kfree(out);
 592         return err;
 593 }
 594 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_gid);
 595 
 596 int mlx5_query_hca_vport_pkey(struct mlx5_core_dev *dev, u8 other_vport,
 597                               u8 port_num, u16 vf_num, u16 pkey_index,
 598                               u16 *pkey)
 599 {
 600         int in_sz = MLX5_ST_SZ_BYTES(query_hca_vport_pkey_in);
 601         int out_sz = MLX5_ST_SZ_BYTES(query_hca_vport_pkey_out);
 602         int is_group_manager;
 603         void *out = NULL;
 604         void *in = NULL;
 605         void *pkarr;
 606         int nout;
 607         int tbsz;
 608         int err;
 609         int i;
 610 
 611         is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
 612 
 613         tbsz = mlx5_to_sw_pkey_sz(MLX5_CAP_GEN(dev, pkey_table_size));
 614         if (pkey_index > tbsz && pkey_index != 0xffff)
 615                 return -EINVAL;
 616 
 617         if (pkey_index == 0xffff)
 618                 nout = tbsz;
 619         else
 620                 nout = 1;
 621 
 622         out_sz += nout * MLX5_ST_SZ_BYTES(pkey);
 623 
 624         in = kzalloc(in_sz, GFP_KERNEL);
 625         out = kzalloc(out_sz, GFP_KERNEL);
 626         if (!in || !out) {
 627                 err = -ENOMEM;
 628                 goto out;
 629         }
 630 
 631         MLX5_SET(query_hca_vport_pkey_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_VPORT_PKEY);
 632         if (other_vport) {
 633                 if (is_group_manager) {
 634                         MLX5_SET(query_hca_vport_pkey_in, in, vport_number, vf_num);
 635                         MLX5_SET(query_hca_vport_pkey_in, in, other_vport, 1);
 636                 } else {
 637                         err = -EPERM;
 638                         goto out;
 639                 }
 640         }
 641         MLX5_SET(query_hca_vport_pkey_in, in, pkey_index, pkey_index);
 642 
 643         if (MLX5_CAP_GEN(dev, num_ports) == 2)
 644                 MLX5_SET(query_hca_vport_pkey_in, in, port_num, port_num);
 645 
 646         err = mlx5_cmd_exec(dev, in, in_sz, out, out_sz);
 647         if (err)
 648                 goto out;
 649 
 650         pkarr = MLX5_ADDR_OF(query_hca_vport_pkey_out, out, pkey);
 651         for (i = 0; i < nout; i++, pkey++, pkarr += MLX5_ST_SZ_BYTES(pkey))
 652                 *pkey = MLX5_GET_PR(pkey, pkarr, pkey);
 653 
 654 out:
 655         kfree(in);
 656         kfree(out);
 657         return err;
 658 }
 659 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_pkey);
 660 
 661 int mlx5_query_hca_vport_context(struct mlx5_core_dev *dev,
 662                                  u8 other_vport, u8 port_num,
 663                                  u16 vf_num,
 664                                  struct mlx5_hca_vport_context *rep)
 665 {
 666         int out_sz = MLX5_ST_SZ_BYTES(query_hca_vport_context_out);
 667         int in[MLX5_ST_SZ_DW(query_hca_vport_context_in)] = {0};
 668         int is_group_manager;
 669         void *out;
 670         void *ctx;
 671         int err;
 672 
 673         is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
 674 
 675         out = kzalloc(out_sz, GFP_KERNEL);
 676         if (!out)
 677                 return -ENOMEM;
 678 
 679         MLX5_SET(query_hca_vport_context_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_VPORT_CONTEXT);
 680 
 681         if (other_vport) {
 682                 if (is_group_manager) {
 683                         MLX5_SET(query_hca_vport_context_in, in, other_vport, 1);
 684                         MLX5_SET(query_hca_vport_context_in, in, vport_number, vf_num);
 685                 } else {
 686                         err = -EPERM;
 687                         goto ex;
 688                 }
 689         }
 690 
 691         if (MLX5_CAP_GEN(dev, num_ports) == 2)
 692                 MLX5_SET(query_hca_vport_context_in, in, port_num, port_num);
 693 
 694         err = mlx5_cmd_exec(dev, in, sizeof(in), out,  out_sz);
 695         if (err)
 696                 goto ex;
 697 
 698         ctx = MLX5_ADDR_OF(query_hca_vport_context_out, out, hca_vport_context);
 699         rep->field_select = MLX5_GET_PR(hca_vport_context, ctx, field_select);
 700         rep->sm_virt_aware = MLX5_GET_PR(hca_vport_context, ctx, sm_virt_aware);
 701         rep->has_smi = MLX5_GET_PR(hca_vport_context, ctx, has_smi);
 702         rep->has_raw = MLX5_GET_PR(hca_vport_context, ctx, has_raw);
 703         rep->policy = MLX5_GET_PR(hca_vport_context, ctx, vport_state_policy);
 704         rep->phys_state = MLX5_GET_PR(hca_vport_context, ctx,
 705                                       port_physical_state);
 706         rep->vport_state = MLX5_GET_PR(hca_vport_context, ctx, vport_state);
 707         rep->port_physical_state = MLX5_GET_PR(hca_vport_context, ctx,
 708                                                port_physical_state);
 709         rep->port_guid = MLX5_GET64_PR(hca_vport_context, ctx, port_guid);
 710         rep->node_guid = MLX5_GET64_PR(hca_vport_context, ctx, node_guid);
 711         rep->cap_mask1 = MLX5_GET_PR(hca_vport_context, ctx, cap_mask1);
 712         rep->cap_mask1_perm = MLX5_GET_PR(hca_vport_context, ctx,
 713                                           cap_mask1_field_select);
 714         rep->cap_mask2 = MLX5_GET_PR(hca_vport_context, ctx, cap_mask2);
 715         rep->cap_mask2_perm = MLX5_GET_PR(hca_vport_context, ctx,
 716                                           cap_mask2_field_select);
 717         rep->lid = MLX5_GET_PR(hca_vport_context, ctx, lid);
 718         rep->init_type_reply = MLX5_GET_PR(hca_vport_context, ctx,
 719                                            init_type_reply);
 720         rep->lmc = MLX5_GET_PR(hca_vport_context, ctx, lmc);
 721         rep->subnet_timeout = MLX5_GET_PR(hca_vport_context, ctx,
 722                                           subnet_timeout);
 723         rep->sm_lid = MLX5_GET_PR(hca_vport_context, ctx, sm_lid);
 724         rep->sm_sl = MLX5_GET_PR(hca_vport_context, ctx, sm_sl);
 725         rep->qkey_violation_counter = MLX5_GET_PR(hca_vport_context, ctx,
 726                                                   qkey_violation_counter);
 727         rep->pkey_violation_counter = MLX5_GET_PR(hca_vport_context, ctx,
 728                                                   pkey_violation_counter);
 729         rep->grh_required = MLX5_GET_PR(hca_vport_context, ctx, grh_required);
 730         rep->sys_image_guid = MLX5_GET64_PR(hca_vport_context, ctx,
 731                                             system_image_guid);
 732 
 733 ex:
 734         kfree(out);
 735         return err;
 736 }
 737 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_context);
 738 
 739 int mlx5_query_hca_vport_system_image_guid(struct mlx5_core_dev *dev,
 740                                            u64 *sys_image_guid)
 741 {
 742         struct mlx5_hca_vport_context *rep;
 743         int err;
 744 
 745         rep = kzalloc(sizeof(*rep), GFP_KERNEL);
 746         if (!rep)
 747                 return -ENOMEM;
 748 
 749         err = mlx5_query_hca_vport_context(dev, 0, 1, 0, rep);
 750         if (!err)
 751                 *sys_image_guid = rep->sys_image_guid;
 752 
 753         kfree(rep);
 754         return err;
 755 }
 756 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_system_image_guid);
 757 
 758 int mlx5_query_hca_vport_node_guid(struct mlx5_core_dev *dev,
 759                                    u64 *node_guid)
 760 {
 761         struct mlx5_hca_vport_context *rep;
 762         int err;
 763 
 764         rep = kzalloc(sizeof(*rep), GFP_KERNEL);
 765         if (!rep)
 766                 return -ENOMEM;
 767 
 768         err = mlx5_query_hca_vport_context(dev, 0, 1, 0, rep);
 769         if (!err)
 770                 *node_guid = rep->node_guid;
 771 
 772         kfree(rep);
 773         return err;
 774 }
 775 EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_node_guid);
 776 
 777 int mlx5_query_nic_vport_promisc(struct mlx5_core_dev *mdev,
 778                                  u16 vport,
 779                                  int *promisc_uc,
 780                                  int *promisc_mc,
 781                                  int *promisc_all)
 782 {
 783         u32 *out;
 784         int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
 785         int err;
 786 
 787         out = kzalloc(outlen, GFP_KERNEL);
 788         if (!out)
 789                 return -ENOMEM;
 790 
 791         err = mlx5_query_nic_vport_context(mdev, vport, out, outlen);
 792         if (err)
 793                 goto out;
 794 
 795         *promisc_uc = MLX5_GET(query_nic_vport_context_out, out,
 796                                nic_vport_context.promisc_uc);
 797         *promisc_mc = MLX5_GET(query_nic_vport_context_out, out,
 798                                nic_vport_context.promisc_mc);
 799         *promisc_all = MLX5_GET(query_nic_vport_context_out, out,
 800                                 nic_vport_context.promisc_all);
 801 
 802 out:
 803         kfree(out);
 804         return err;
 805 }
 806 EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_promisc);
 807 
 808 int mlx5_modify_nic_vport_promisc(struct mlx5_core_dev *mdev,
 809                                   int promisc_uc,
 810                                   int promisc_mc,
 811                                   int promisc_all)
 812 {
 813         void *in;
 814         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
 815         int err;
 816 
 817         in = kvzalloc(inlen, GFP_KERNEL);
 818         if (!in)
 819                 return -ENOMEM;
 820 
 821         MLX5_SET(modify_nic_vport_context_in, in, field_select.promisc, 1);
 822         MLX5_SET(modify_nic_vport_context_in, in,
 823                  nic_vport_context.promisc_uc, promisc_uc);
 824         MLX5_SET(modify_nic_vport_context_in, in,
 825                  nic_vport_context.promisc_mc, promisc_mc);
 826         MLX5_SET(modify_nic_vport_context_in, in,
 827                  nic_vport_context.promisc_all, promisc_all);
 828 
 829         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
 830 
 831         kvfree(in);
 832 
 833         return err;
 834 }
 835 EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_promisc);
 836 
 837 enum {
 838         UC_LOCAL_LB,
 839         MC_LOCAL_LB
 840 };
 841 
 842 int mlx5_nic_vport_update_local_lb(struct mlx5_core_dev *mdev, bool enable)
 843 {
 844         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
 845         void *in;
 846         int err;
 847 
 848         if (!MLX5_CAP_GEN(mdev, disable_local_lb_mc) &&
 849             !MLX5_CAP_GEN(mdev, disable_local_lb_uc))
 850                 return 0;
 851 
 852         in = kvzalloc(inlen, GFP_KERNEL);
 853         if (!in)
 854                 return -ENOMEM;
 855 
 856         MLX5_SET(modify_nic_vport_context_in, in,
 857                  nic_vport_context.disable_mc_local_lb, !enable);
 858         MLX5_SET(modify_nic_vport_context_in, in,
 859                  nic_vport_context.disable_uc_local_lb, !enable);
 860 
 861         if (MLX5_CAP_GEN(mdev, disable_local_lb_mc))
 862                 MLX5_SET(modify_nic_vport_context_in, in,
 863                          field_select.disable_mc_local_lb, 1);
 864 
 865         if (MLX5_CAP_GEN(mdev, disable_local_lb_uc))
 866                 MLX5_SET(modify_nic_vport_context_in, in,
 867                          field_select.disable_uc_local_lb, 1);
 868 
 869         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
 870 
 871         if (!err)
 872                 mlx5_core_dbg(mdev, "%s local_lb\n",
 873                               enable ? "enable" : "disable");
 874 
 875         kvfree(in);
 876         return err;
 877 }
 878 EXPORT_SYMBOL_GPL(mlx5_nic_vport_update_local_lb);
 879 
 880 int mlx5_nic_vport_query_local_lb(struct mlx5_core_dev *mdev, bool *status)
 881 {
 882         int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
 883         u32 *out;
 884         int value;
 885         int err;
 886 
 887         out = kzalloc(outlen, GFP_KERNEL);
 888         if (!out)
 889                 return -ENOMEM;
 890 
 891         err = mlx5_query_nic_vport_context(mdev, 0, out, outlen);
 892         if (err)
 893                 goto out;
 894 
 895         value = MLX5_GET(query_nic_vport_context_out, out,
 896                          nic_vport_context.disable_mc_local_lb) << MC_LOCAL_LB;
 897 
 898         value |= MLX5_GET(query_nic_vport_context_out, out,
 899                           nic_vport_context.disable_uc_local_lb) << UC_LOCAL_LB;
 900 
 901         *status = !value;
 902 
 903 out:
 904         kfree(out);
 905         return err;
 906 }
 907 EXPORT_SYMBOL_GPL(mlx5_nic_vport_query_local_lb);
 908 
 909 enum mlx5_vport_roce_state {
 910         MLX5_VPORT_ROCE_DISABLED = 0,
 911         MLX5_VPORT_ROCE_ENABLED  = 1,
 912 };
 913 
 914 static int mlx5_nic_vport_update_roce_state(struct mlx5_core_dev *mdev,
 915                                             enum mlx5_vport_roce_state state)
 916 {
 917         void *in;
 918         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
 919         int err;
 920 
 921         in = kvzalloc(inlen, GFP_KERNEL);
 922         if (!in)
 923                 return -ENOMEM;
 924 
 925         MLX5_SET(modify_nic_vport_context_in, in, field_select.roce_en, 1);
 926         MLX5_SET(modify_nic_vport_context_in, in, nic_vport_context.roce_en,
 927                  state);
 928 
 929         err = mlx5_modify_nic_vport_context(mdev, in, inlen);
 930 
 931         kvfree(in);
 932 
 933         return err;
 934 }
 935 
 936 int mlx5_nic_vport_enable_roce(struct mlx5_core_dev *mdev)
 937 {
 938         int err = 0;
 939 
 940         mutex_lock(&mlx5_roce_en_lock);
 941         if (!mdev->roce.roce_en)
 942                 err = mlx5_nic_vport_update_roce_state(mdev, MLX5_VPORT_ROCE_ENABLED);
 943 
 944         if (!err)
 945                 mdev->roce.roce_en++;
 946         mutex_unlock(&mlx5_roce_en_lock);
 947 
 948         return err;
 949 }
 950 EXPORT_SYMBOL_GPL(mlx5_nic_vport_enable_roce);
 951 
 952 int mlx5_nic_vport_disable_roce(struct mlx5_core_dev *mdev)
 953 {
 954         int err = 0;
 955 
 956         mutex_lock(&mlx5_roce_en_lock);
 957         if (mdev->roce.roce_en) {
 958                 mdev->roce.roce_en--;
 959                 if (mdev->roce.roce_en == 0)
 960                         err = mlx5_nic_vport_update_roce_state(mdev, MLX5_VPORT_ROCE_DISABLED);
 961 
 962                 if (err)
 963                         mdev->roce.roce_en++;
 964         }
 965         mutex_unlock(&mlx5_roce_en_lock);
 966         return err;
 967 }
 968 EXPORT_SYMBOL_GPL(mlx5_nic_vport_disable_roce);
 969 
 970 int mlx5_core_query_vport_counter(struct mlx5_core_dev *dev, u8 other_vport,
 971                                   int vf, u8 port_num, void *out,
 972                                   size_t out_sz)
 973 {
 974         int     in_sz = MLX5_ST_SZ_BYTES(query_vport_counter_in);
 975         int     is_group_manager;
 976         void   *in;
 977         int     err;
 978 
 979         is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
 980         in = kvzalloc(in_sz, GFP_KERNEL);
 981         if (!in) {
 982                 err = -ENOMEM;
 983                 return err;
 984         }
 985 
 986         MLX5_SET(query_vport_counter_in, in, opcode,
 987                  MLX5_CMD_OP_QUERY_VPORT_COUNTER);
 988         if (other_vport) {
 989                 if (is_group_manager) {
 990                         MLX5_SET(query_vport_counter_in, in, other_vport, 1);
 991                         MLX5_SET(query_vport_counter_in, in, vport_number, vf + 1);
 992                 } else {
 993                         err = -EPERM;
 994                         goto free;
 995                 }
 996         }
 997         if (MLX5_CAP_GEN(dev, num_ports) == 2)
 998                 MLX5_SET(query_vport_counter_in, in, port_num, port_num);
 999 
1000         err = mlx5_cmd_exec(dev, in, in_sz, out,  out_sz);
1001 free:
1002         kvfree(in);
1003         return err;
1004 }
1005 EXPORT_SYMBOL_GPL(mlx5_core_query_vport_counter);
1006 
1007 int mlx5_query_vport_down_stats(struct mlx5_core_dev *mdev, u16 vport,
1008                                 u8 other_vport, u64 *rx_discard_vport_down,
1009                                 u64 *tx_discard_vport_down)
1010 {
1011         u32 out[MLX5_ST_SZ_DW(query_vnic_env_out)] = {0};
1012         u32 in[MLX5_ST_SZ_DW(query_vnic_env_in)] = {0};
1013         int err;
1014 
1015         MLX5_SET(query_vnic_env_in, in, opcode,
1016                  MLX5_CMD_OP_QUERY_VNIC_ENV);
1017         MLX5_SET(query_vnic_env_in, in, op_mod, 0);
1018         MLX5_SET(query_vnic_env_in, in, vport_number, vport);
1019         MLX5_SET(query_vnic_env_in, in, other_vport, other_vport);
1020 
1021         err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
1022         if (err)
1023                 return err;
1024 
1025         *rx_discard_vport_down = MLX5_GET64(query_vnic_env_out, out,
1026                                             vport_env.receive_discard_vport_down);
1027         *tx_discard_vport_down = MLX5_GET64(query_vnic_env_out, out,
1028                                             vport_env.transmit_discard_vport_down);
1029         return 0;
1030 }
1031 
1032 int mlx5_core_modify_hca_vport_context(struct mlx5_core_dev *dev,
1033                                        u8 other_vport, u8 port_num,
1034                                        int vf,
1035                                        struct mlx5_hca_vport_context *req)
1036 {
1037         int in_sz = MLX5_ST_SZ_BYTES(modify_hca_vport_context_in);
1038         u8 out[MLX5_ST_SZ_BYTES(modify_hca_vport_context_out)];
1039         int is_group_manager;
1040         void *in;
1041         int err;
1042         void *ctx;
1043 
1044         mlx5_core_dbg(dev, "vf %d\n", vf);
1045         is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
1046         in = kzalloc(in_sz, GFP_KERNEL);
1047         if (!in)
1048                 return -ENOMEM;
1049 
1050         memset(out, 0, sizeof(out));
1051         MLX5_SET(modify_hca_vport_context_in, in, opcode, MLX5_CMD_OP_MODIFY_HCA_VPORT_CONTEXT);
1052         if (other_vport) {
1053                 if (is_group_manager) {
1054                         MLX5_SET(modify_hca_vport_context_in, in, other_vport, 1);
1055                         MLX5_SET(modify_hca_vport_context_in, in, vport_number, vf);
1056                 } else {
1057                         err = -EPERM;
1058                         goto ex;
1059                 }
1060         }
1061 
1062         if (MLX5_CAP_GEN(dev, num_ports) > 1)
1063                 MLX5_SET(modify_hca_vport_context_in, in, port_num, port_num);
1064 
1065         ctx = MLX5_ADDR_OF(modify_hca_vport_context_in, in, hca_vport_context);
1066         MLX5_SET(hca_vport_context, ctx, field_select, req->field_select);
1067         MLX5_SET(hca_vport_context, ctx, sm_virt_aware, req->sm_virt_aware);
1068         MLX5_SET(hca_vport_context, ctx, has_smi, req->has_smi);
1069         MLX5_SET(hca_vport_context, ctx, has_raw, req->has_raw);
1070         MLX5_SET(hca_vport_context, ctx, vport_state_policy, req->policy);
1071         MLX5_SET(hca_vport_context, ctx, port_physical_state, req->phys_state);
1072         MLX5_SET(hca_vport_context, ctx, vport_state, req->vport_state);
1073         MLX5_SET64(hca_vport_context, ctx, port_guid, req->port_guid);
1074         MLX5_SET64(hca_vport_context, ctx, node_guid, req->node_guid);
1075         MLX5_SET(hca_vport_context, ctx, cap_mask1, req->cap_mask1);
1076         MLX5_SET(hca_vport_context, ctx, cap_mask1_field_select, req->cap_mask1_perm);
1077         MLX5_SET(hca_vport_context, ctx, cap_mask2, req->cap_mask2);
1078         MLX5_SET(hca_vport_context, ctx, cap_mask2_field_select, req->cap_mask2_perm);
1079         MLX5_SET(hca_vport_context, ctx, lid, req->lid);
1080         MLX5_SET(hca_vport_context, ctx, init_type_reply, req->init_type_reply);
1081         MLX5_SET(hca_vport_context, ctx, lmc, req->lmc);
1082         MLX5_SET(hca_vport_context, ctx, subnet_timeout, req->subnet_timeout);
1083         MLX5_SET(hca_vport_context, ctx, sm_lid, req->sm_lid);
1084         MLX5_SET(hca_vport_context, ctx, sm_sl, req->sm_sl);
1085         MLX5_SET(hca_vport_context, ctx, qkey_violation_counter, req->qkey_violation_counter);
1086         MLX5_SET(hca_vport_context, ctx, pkey_violation_counter, req->pkey_violation_counter);
1087         err = mlx5_cmd_exec(dev, in, in_sz, out, sizeof(out));
1088 ex:
1089         kfree(in);
1090         return err;
1091 }
1092 EXPORT_SYMBOL_GPL(mlx5_core_modify_hca_vport_context);
1093 
1094 int mlx5_nic_vport_affiliate_multiport(struct mlx5_core_dev *master_mdev,
1095                                        struct mlx5_core_dev *port_mdev)
1096 {
1097         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
1098         void *in;
1099         int err;
1100 
1101         in = kvzalloc(inlen, GFP_KERNEL);
1102         if (!in)
1103                 return -ENOMEM;
1104 
1105         err = mlx5_nic_vport_enable_roce(port_mdev);
1106         if (err)
1107                 goto free;
1108 
1109         MLX5_SET(modify_nic_vport_context_in, in, field_select.affiliation, 1);
1110         MLX5_SET(modify_nic_vport_context_in, in,
1111                  nic_vport_context.affiliated_vhca_id,
1112                  MLX5_CAP_GEN(master_mdev, vhca_id));
1113         MLX5_SET(modify_nic_vport_context_in, in,
1114                  nic_vport_context.affiliation_criteria,
1115                  MLX5_CAP_GEN(port_mdev, affiliate_nic_vport_criteria));
1116 
1117         err = mlx5_modify_nic_vport_context(port_mdev, in, inlen);
1118         if (err)
1119                 mlx5_nic_vport_disable_roce(port_mdev);
1120 
1121 free:
1122         kvfree(in);
1123         return err;
1124 }
1125 EXPORT_SYMBOL_GPL(mlx5_nic_vport_affiliate_multiport);
1126 
1127 int mlx5_nic_vport_unaffiliate_multiport(struct mlx5_core_dev *port_mdev)
1128 {
1129         int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
1130         void *in;
1131         int err;
1132 
1133         in = kvzalloc(inlen, GFP_KERNEL);
1134         if (!in)
1135                 return -ENOMEM;
1136 
1137         MLX5_SET(modify_nic_vport_context_in, in, field_select.affiliation, 1);
1138         MLX5_SET(modify_nic_vport_context_in, in,
1139                  nic_vport_context.affiliated_vhca_id, 0);
1140         MLX5_SET(modify_nic_vport_context_in, in,
1141                  nic_vport_context.affiliation_criteria, 0);
1142 
1143         err = mlx5_modify_nic_vport_context(port_mdev, in, inlen);
1144         if (!err)
1145                 mlx5_nic_vport_disable_roce(port_mdev);
1146 
1147         kvfree(in);
1148         return err;
1149 }
1150 EXPORT_SYMBOL_GPL(mlx5_nic_vport_unaffiliate_multiport);
1151 
1152 u64 mlx5_query_nic_system_image_guid(struct mlx5_core_dev *mdev)
1153 {
1154         int port_type_cap = MLX5_CAP_GEN(mdev, port_type);
1155         u64 tmp = 0;
1156 
1157         if (mdev->sys_image_guid)
1158                 return mdev->sys_image_guid;
1159 
1160         if (port_type_cap == MLX5_CAP_PORT_TYPE_ETH)
1161                 mlx5_query_nic_vport_system_image_guid(mdev, &tmp);
1162         else
1163                 mlx5_query_hca_vport_system_image_guid(mdev, &tmp);
1164 
1165         mdev->sys_image_guid = tmp;
1166 
1167         return tmp;
1168 }
1169 EXPORT_SYMBOL_GPL(mlx5_query_nic_system_image_guid);
1170 
1171 /**
1172  * mlx5_eswitch_get_total_vports - Get total vports of the eswitch
1173  *
1174  * @dev:        Pointer to core device
1175  *
1176  * mlx5_eswitch_get_total_vports returns total number of vports for
1177  * the eswitch.
1178  */
1179 u16 mlx5_eswitch_get_total_vports(const struct mlx5_core_dev *dev)
1180 {
1181         return MLX5_SPECIAL_VPORTS(dev) + mlx5_core_max_vfs(dev);
1182 }
1183 EXPORT_SYMBOL(mlx5_eswitch_get_total_vports);

/* [<][>][^][v][top][bottom][index][help] */