fw.c (102959B)
1/* 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 3 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved. 4 * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved. 5 * 6 * This software is available to you under a choice of one of two 7 * licenses. You may choose to be licensed under the terms of the GNU 8 * General Public License (GPL) Version 2, available from the file 9 * COPYING in the main directory of this source tree, or the 10 * OpenIB.org BSD license below: 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above 17 * copyright notice, this list of conditions and the following 18 * disclaimer. 19 * 20 * - Redistributions in binary form must reproduce the above 21 * copyright notice, this list of conditions and the following 22 * disclaimer in the documentation and/or other materials 23 * provided with the distribution. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 * SOFTWARE. 33 */ 34 35#include <linux/etherdevice.h> 36#include <linux/mlx4/cmd.h> 37#include <linux/module.h> 38#include <linux/cache.h> 39#include <linux/kernel.h> 40#include <uapi/rdma/mlx4-abi.h> 41 42#include "fw.h" 43#include "icm.h" 44 45enum { 46 MLX4_COMMAND_INTERFACE_MIN_REV = 2, 47 MLX4_COMMAND_INTERFACE_MAX_REV = 3, 48 MLX4_COMMAND_INTERFACE_NEW_PORT_CMDS = 3, 49}; 50 51extern void __buggy_use_of_MLX4_GET(void); 52extern void __buggy_use_of_MLX4_PUT(void); 53 54static bool enable_qos; 55module_param(enable_qos, bool, 0444); 56MODULE_PARM_DESC(enable_qos, "Enable Enhanced QoS support (default: off)"); 57 58#define MLX4_GET(dest, source, offset) \ 59 do { \ 60 void *__p = (char *) (source) + (offset); \ 61 __be64 val; \ 62 switch (sizeof(dest)) { \ 63 case 1: (dest) = *(u8 *) __p; break; \ 64 case 2: (dest) = be16_to_cpup(__p); break; \ 65 case 4: (dest) = be32_to_cpup(__p); break; \ 66 case 8: val = get_unaligned((__be64 *)__p); \ 67 (dest) = be64_to_cpu(val); break; \ 68 default: __buggy_use_of_MLX4_GET(); \ 69 } \ 70 } while (0) 71 72#define MLX4_PUT(dest, source, offset) \ 73 do { \ 74 void *__d = ((char *) (dest) + (offset)); \ 75 switch (sizeof(source)) { \ 76 case 1: *(u8 *) __d = (source); break; \ 77 case 2: *(__be16 *) __d = cpu_to_be16(source); break; \ 78 case 4: *(__be32 *) __d = cpu_to_be32(source); break; \ 79 case 8: *(__be64 *) __d = cpu_to_be64(source); break; \ 80 default: __buggy_use_of_MLX4_PUT(); \ 81 } \ 82 } while (0) 83 84static void dump_dev_cap_flags(struct mlx4_dev *dev, u64 flags) 85{ 86 static const char *fname[] = { 87 [ 0] = "RC transport", 88 [ 1] = "UC transport", 89 [ 2] = "UD transport", 90 [ 3] = "XRC transport", 91 [ 6] = "SRQ support", 92 [ 7] = "IPoIB checksum offload", 93 [ 8] = "P_Key violation counter", 94 [ 9] = "Q_Key violation counter", 95 [12] = "Dual Port Different Protocol (DPDP) support", 96 [15] = "Big LSO headers", 97 [16] = "MW support", 98 [17] = "APM support", 99 [18] = "Atomic ops support", 100 [19] = "Raw multicast support", 101 [20] = "Address vector port checking support", 102 [21] = "UD multicast support", 103 [30] = "IBoE support", 104 [32] = "Unicast loopback support", 105 [34] = "FCS header control", 106 [37] = "Wake On LAN (port1) support", 107 [38] = "Wake On LAN (port2) support", 108 [40] = "UDP RSS support", 109 [41] = "Unicast VEP steering support", 110 [42] = "Multicast VEP steering support", 111 [48] = "Counters support", 112 [52] = "RSS IP fragments support", 113 [53] = "Port ETS Scheduler support", 114 [55] = "Port link type sensing support", 115 [59] = "Port management change event support", 116 [61] = "64 byte EQE support", 117 [62] = "64 byte CQE support", 118 }; 119 int i; 120 121 mlx4_dbg(dev, "DEV_CAP flags:\n"); 122 for (i = 0; i < ARRAY_SIZE(fname); ++i) 123 if (fname[i] && (flags & (1LL << i))) 124 mlx4_dbg(dev, " %s\n", fname[i]); 125} 126 127static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) 128{ 129 static const char * const fname[] = { 130 [0] = "RSS support", 131 [1] = "RSS Toeplitz Hash Function support", 132 [2] = "RSS XOR Hash Function support", 133 [3] = "Device managed flow steering support", 134 [4] = "Automatic MAC reassignment support", 135 [5] = "Time stamping support", 136 [6] = "VST (control vlan insertion/stripping) support", 137 [7] = "FSM (MAC anti-spoofing) support", 138 [8] = "Dynamic QP updates support", 139 [9] = "Device managed flow steering IPoIB support", 140 [10] = "TCP/IP offloads/flow-steering for VXLAN support", 141 [11] = "MAD DEMUX (Secure-Host) support", 142 [12] = "Large cache line (>64B) CQE stride support", 143 [13] = "Large cache line (>64B) EQE stride support", 144 [14] = "Ethernet protocol control support", 145 [15] = "Ethernet Backplane autoneg support", 146 [16] = "CONFIG DEV support", 147 [17] = "Asymmetric EQs support", 148 [18] = "More than 80 VFs support", 149 [19] = "Performance optimized for limited rule configuration flow steering support", 150 [20] = "Recoverable error events support", 151 [21] = "Port Remap support", 152 [22] = "QCN support", 153 [23] = "QP rate limiting support", 154 [24] = "Ethernet Flow control statistics support", 155 [25] = "Granular QoS per VF support", 156 [26] = "Port ETS Scheduler support", 157 [27] = "Port beacon support", 158 [28] = "RX-ALL support", 159 [29] = "802.1ad offload support", 160 [31] = "Modifying loopback source checks using UPDATE_QP support", 161 [32] = "Loopback source checks support", 162 [33] = "RoCEv2 support", 163 [34] = "DMFS Sniffer support (UC & MC)", 164 [35] = "Diag counters per port", 165 [36] = "QinQ VST mode support", 166 [37] = "sl to vl mapping table change event support", 167 [38] = "user MAC support", 168 [39] = "Report driver version to FW support", 169 [40] = "SW CQ initialization support", 170 }; 171 int i; 172 173 for (i = 0; i < ARRAY_SIZE(fname); ++i) 174 if (fname[i] && (flags & (1LL << i))) 175 mlx4_dbg(dev, " %s\n", fname[i]); 176} 177 178int mlx4_MOD_STAT_CFG(struct mlx4_dev *dev, struct mlx4_mod_stat_cfg *cfg) 179{ 180 struct mlx4_cmd_mailbox *mailbox; 181 u32 *inbox; 182 int err = 0; 183 184#define MOD_STAT_CFG_IN_SIZE 0x100 185 186#define MOD_STAT_CFG_PG_SZ_M_OFFSET 0x002 187#define MOD_STAT_CFG_PG_SZ_OFFSET 0x003 188 189 mailbox = mlx4_alloc_cmd_mailbox(dev); 190 if (IS_ERR(mailbox)) 191 return PTR_ERR(mailbox); 192 inbox = mailbox->buf; 193 194 MLX4_PUT(inbox, cfg->log_pg_sz, MOD_STAT_CFG_PG_SZ_OFFSET); 195 MLX4_PUT(inbox, cfg->log_pg_sz_m, MOD_STAT_CFG_PG_SZ_M_OFFSET); 196 197 err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_MOD_STAT_CFG, 198 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 199 200 mlx4_free_cmd_mailbox(dev, mailbox); 201 return err; 202} 203 204int mlx4_QUERY_FUNC(struct mlx4_dev *dev, struct mlx4_func *func, int slave) 205{ 206 struct mlx4_cmd_mailbox *mailbox; 207 u32 *outbox; 208 u8 in_modifier; 209 u8 field; 210 u16 field16; 211 int err; 212 213#define QUERY_FUNC_BUS_OFFSET 0x00 214#define QUERY_FUNC_DEVICE_OFFSET 0x01 215#define QUERY_FUNC_FUNCTION_OFFSET 0x01 216#define QUERY_FUNC_PHYSICAL_FUNCTION_OFFSET 0x03 217#define QUERY_FUNC_RSVD_EQS_OFFSET 0x04 218#define QUERY_FUNC_MAX_EQ_OFFSET 0x06 219#define QUERY_FUNC_RSVD_UARS_OFFSET 0x0b 220 221 mailbox = mlx4_alloc_cmd_mailbox(dev); 222 if (IS_ERR(mailbox)) 223 return PTR_ERR(mailbox); 224 outbox = mailbox->buf; 225 226 in_modifier = slave; 227 228 err = mlx4_cmd_box(dev, 0, mailbox->dma, in_modifier, 0, 229 MLX4_CMD_QUERY_FUNC, 230 MLX4_CMD_TIME_CLASS_A, 231 MLX4_CMD_NATIVE); 232 if (err) 233 goto out; 234 235 MLX4_GET(field, outbox, QUERY_FUNC_BUS_OFFSET); 236 func->bus = field & 0xf; 237 MLX4_GET(field, outbox, QUERY_FUNC_DEVICE_OFFSET); 238 func->device = field & 0xf1; 239 MLX4_GET(field, outbox, QUERY_FUNC_FUNCTION_OFFSET); 240 func->function = field & 0x7; 241 MLX4_GET(field, outbox, QUERY_FUNC_PHYSICAL_FUNCTION_OFFSET); 242 func->physical_function = field & 0xf; 243 MLX4_GET(field16, outbox, QUERY_FUNC_RSVD_EQS_OFFSET); 244 func->rsvd_eqs = field16 & 0xffff; 245 MLX4_GET(field16, outbox, QUERY_FUNC_MAX_EQ_OFFSET); 246 func->max_eq = field16 & 0xffff; 247 MLX4_GET(field, outbox, QUERY_FUNC_RSVD_UARS_OFFSET); 248 func->rsvd_uars = field & 0x0f; 249 250 mlx4_dbg(dev, "Bus: %d, Device: %d, Function: %d, Physical function: %d, Max EQs: %d, Reserved EQs: %d, Reserved UARs: %d\n", 251 func->bus, func->device, func->function, func->physical_function, 252 func->max_eq, func->rsvd_eqs, func->rsvd_uars); 253 254out: 255 mlx4_free_cmd_mailbox(dev, mailbox); 256 return err; 257} 258 259static int mlx4_activate_vst_qinq(struct mlx4_priv *priv, int slave, int port) 260{ 261 struct mlx4_vport_oper_state *vp_oper; 262 struct mlx4_vport_state *vp_admin; 263 int err; 264 265 vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; 266 vp_admin = &priv->mfunc.master.vf_admin[slave].vport[port]; 267 268 if (vp_admin->default_vlan != vp_oper->state.default_vlan) { 269 err = __mlx4_register_vlan(&priv->dev, port, 270 vp_admin->default_vlan, 271 &vp_oper->vlan_idx); 272 if (err) { 273 vp_oper->vlan_idx = NO_INDX; 274 mlx4_warn(&priv->dev, 275 "No vlan resources slave %d, port %d\n", 276 slave, port); 277 return err; 278 } 279 mlx4_dbg(&priv->dev, "alloc vlan %d idx %d slave %d port %d\n", 280 (int)(vp_oper->state.default_vlan), 281 vp_oper->vlan_idx, slave, port); 282 } 283 vp_oper->state.vlan_proto = vp_admin->vlan_proto; 284 vp_oper->state.default_vlan = vp_admin->default_vlan; 285 vp_oper->state.default_qos = vp_admin->default_qos; 286 287 return 0; 288} 289 290static int mlx4_handle_vst_qinq(struct mlx4_priv *priv, int slave, int port) 291{ 292 struct mlx4_vport_oper_state *vp_oper; 293 struct mlx4_slave_state *slave_state; 294 struct mlx4_vport_state *vp_admin; 295 int err; 296 297 vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; 298 vp_admin = &priv->mfunc.master.vf_admin[slave].vport[port]; 299 slave_state = &priv->mfunc.master.slave_state[slave]; 300 301 if ((vp_admin->vlan_proto != htons(ETH_P_8021AD)) || 302 (!slave_state->active)) 303 return 0; 304 305 if (vp_oper->state.vlan_proto == vp_admin->vlan_proto && 306 vp_oper->state.default_vlan == vp_admin->default_vlan && 307 vp_oper->state.default_qos == vp_admin->default_qos) 308 return 0; 309 310 if (!slave_state->vst_qinq_supported) { 311 /* Warn and revert the request to set vst QinQ mode */ 312 vp_admin->vlan_proto = vp_oper->state.vlan_proto; 313 vp_admin->default_vlan = vp_oper->state.default_vlan; 314 vp_admin->default_qos = vp_oper->state.default_qos; 315 316 mlx4_warn(&priv->dev, 317 "Slave %d does not support VST QinQ mode\n", slave); 318 return 0; 319 } 320 321 err = mlx4_activate_vst_qinq(priv, slave, port); 322 return err; 323} 324 325int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, 326 struct mlx4_vhcr *vhcr, 327 struct mlx4_cmd_mailbox *inbox, 328 struct mlx4_cmd_mailbox *outbox, 329 struct mlx4_cmd_info *cmd) 330{ 331 struct mlx4_priv *priv = mlx4_priv(dev); 332 u8 field, port; 333 u32 size, proxy_qp, qkey; 334 int err = 0; 335 struct mlx4_func func; 336 337#define QUERY_FUNC_CAP_FLAGS_OFFSET 0x0 338#define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1 339#define QUERY_FUNC_CAP_PF_BHVR_OFFSET 0x4 340#define QUERY_FUNC_CAP_FMR_OFFSET 0x8 341#define QUERY_FUNC_CAP_QP_QUOTA_OFFSET_DEP 0x10 342#define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP 0x14 343#define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET_DEP 0x18 344#define QUERY_FUNC_CAP_MPT_QUOTA_OFFSET_DEP 0x20 345#define QUERY_FUNC_CAP_MTT_QUOTA_OFFSET_DEP 0x24 346#define QUERY_FUNC_CAP_MCG_QUOTA_OFFSET_DEP 0x28 347#define QUERY_FUNC_CAP_MAX_EQ_OFFSET 0x2c 348#define QUERY_FUNC_CAP_RESERVED_EQ_OFFSET 0x30 349#define QUERY_FUNC_CAP_QP_RESD_LKEY_OFFSET 0x48 350 351#define QUERY_FUNC_CAP_QP_QUOTA_OFFSET 0x50 352#define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET 0x54 353#define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET 0x58 354#define QUERY_FUNC_CAP_MPT_QUOTA_OFFSET 0x60 355#define QUERY_FUNC_CAP_MTT_QUOTA_OFFSET 0x64 356#define QUERY_FUNC_CAP_MCG_QUOTA_OFFSET 0x68 357 358#define QUERY_FUNC_CAP_EXTRA_FLAGS_OFFSET 0x6c 359 360#define QUERY_FUNC_CAP_FMR_FLAG 0x80 361#define QUERY_FUNC_CAP_FLAG_RDMA 0x40 362#define QUERY_FUNC_CAP_FLAG_ETH 0x80 363#define QUERY_FUNC_CAP_FLAG_QUOTAS 0x10 364#define QUERY_FUNC_CAP_FLAG_RESD_LKEY 0x08 365#define QUERY_FUNC_CAP_FLAG_VALID_MAILBOX 0x04 366 367#define QUERY_FUNC_CAP_EXTRA_FLAGS_BF_QP_ALLOC_FLAG (1UL << 31) 368#define QUERY_FUNC_CAP_EXTRA_FLAGS_A0_QP_ALLOC_FLAG (1UL << 30) 369 370/* when opcode modifier = 1 */ 371#define QUERY_FUNC_CAP_PHYS_PORT_OFFSET 0x3 372#define QUERY_FUNC_CAP_PRIV_VF_QKEY_OFFSET 0x4 373#define QUERY_FUNC_CAP_FLAGS0_OFFSET 0x8 374#define QUERY_FUNC_CAP_FLAGS1_OFFSET 0xc 375 376#define QUERY_FUNC_CAP_QP0_TUNNEL 0x10 377#define QUERY_FUNC_CAP_QP0_PROXY 0x14 378#define QUERY_FUNC_CAP_QP1_TUNNEL 0x18 379#define QUERY_FUNC_CAP_QP1_PROXY 0x1c 380#define QUERY_FUNC_CAP_PHYS_PORT_ID 0x28 381 382#define QUERY_FUNC_CAP_FLAGS1_FORCE_MAC 0x40 383#define QUERY_FUNC_CAP_FLAGS1_FORCE_VLAN 0x80 384#define QUERY_FUNC_CAP_FLAGS1_NIC_INFO 0x10 385#define QUERY_FUNC_CAP_VF_ENABLE_QP0 0x08 386 387#define QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID 0x80 388#define QUERY_FUNC_CAP_PHV_BIT 0x40 389#define QUERY_FUNC_CAP_VLAN_OFFLOAD_DISABLE 0x20 390 391#define QUERY_FUNC_CAP_SUPPORTS_VST_QINQ BIT(30) 392#define QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS BIT(31) 393 394 if (vhcr->op_modifier == 1) { 395 struct mlx4_active_ports actv_ports = 396 mlx4_get_active_ports(dev, slave); 397 int converted_port = mlx4_slave_convert_port( 398 dev, slave, vhcr->in_modifier); 399 struct mlx4_vport_oper_state *vp_oper; 400 401 if (converted_port < 0) 402 return -EINVAL; 403 404 vhcr->in_modifier = converted_port; 405 /* phys-port = logical-port */ 406 field = vhcr->in_modifier - 407 find_first_bit(actv_ports.ports, dev->caps.num_ports); 408 MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); 409 410 port = vhcr->in_modifier; 411 proxy_qp = dev->phys_caps.base_proxy_sqpn + 8 * slave + port - 1; 412 413 /* Set nic_info bit to mark new fields support */ 414 field = QUERY_FUNC_CAP_FLAGS1_NIC_INFO; 415 416 if (mlx4_vf_smi_enabled(dev, slave, port) && 417 !mlx4_get_parav_qkey(dev, proxy_qp, &qkey)) { 418 field |= QUERY_FUNC_CAP_VF_ENABLE_QP0; 419 MLX4_PUT(outbox->buf, qkey, 420 QUERY_FUNC_CAP_PRIV_VF_QKEY_OFFSET); 421 } 422 MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS1_OFFSET); 423 424 /* size is now the QP number */ 425 size = dev->phys_caps.base_tunnel_sqpn + 8 * slave + port - 1; 426 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP0_TUNNEL); 427 428 size += 2; 429 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP1_TUNNEL); 430 431 MLX4_PUT(outbox->buf, proxy_qp, QUERY_FUNC_CAP_QP0_PROXY); 432 proxy_qp += 2; 433 MLX4_PUT(outbox->buf, proxy_qp, QUERY_FUNC_CAP_QP1_PROXY); 434 435 MLX4_PUT(outbox->buf, dev->caps.phys_port_id[vhcr->in_modifier], 436 QUERY_FUNC_CAP_PHYS_PORT_ID); 437 438 vp_oper = &priv->mfunc.master.vf_oper[slave].vport[port]; 439 err = mlx4_handle_vst_qinq(priv, slave, port); 440 if (err) 441 return err; 442 443 field = 0; 444 if (dev->caps.phv_bit[port]) 445 field |= QUERY_FUNC_CAP_PHV_BIT; 446 if (vp_oper->state.vlan_proto == htons(ETH_P_8021AD)) 447 field |= QUERY_FUNC_CAP_VLAN_OFFLOAD_DISABLE; 448 MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS0_OFFSET); 449 450 } else if (vhcr->op_modifier == 0) { 451 struct mlx4_active_ports actv_ports = 452 mlx4_get_active_ports(dev, slave); 453 struct mlx4_slave_state *slave_state = 454 &priv->mfunc.master.slave_state[slave]; 455 456 /* enable rdma and ethernet interfaces, new quota locations, 457 * and reserved lkey 458 */ 459 field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA | 460 QUERY_FUNC_CAP_FLAG_QUOTAS | QUERY_FUNC_CAP_FLAG_VALID_MAILBOX | 461 QUERY_FUNC_CAP_FLAG_RESD_LKEY); 462 MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET); 463 464 field = min( 465 bitmap_weight(actv_ports.ports, dev->caps.num_ports), 466 dev->caps.num_ports); 467 MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); 468 469 size = dev->caps.function_caps; /* set PF behaviours */ 470 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_PF_BHVR_OFFSET); 471 472 field = 0; /* protected FMR support not available as yet */ 473 MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FMR_OFFSET); 474 475 size = priv->mfunc.master.res_tracker.res_alloc[RES_QP].quota[slave]; 476 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); 477 size = dev->caps.num_qps; 478 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET_DEP); 479 480 size = priv->mfunc.master.res_tracker.res_alloc[RES_SRQ].quota[slave]; 481 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET); 482 size = dev->caps.num_srqs; 483 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET_DEP); 484 485 size = priv->mfunc.master.res_tracker.res_alloc[RES_CQ].quota[slave]; 486 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET); 487 size = dev->caps.num_cqs; 488 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP); 489 490 if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS) || 491 mlx4_QUERY_FUNC(dev, &func, slave)) { 492 size = vhcr->in_modifier & 493 QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS ? 494 dev->caps.num_eqs : 495 rounddown_pow_of_two(dev->caps.num_eqs); 496 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MAX_EQ_OFFSET); 497 size = dev->caps.reserved_eqs; 498 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); 499 } else { 500 size = vhcr->in_modifier & 501 QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS ? 502 func.max_eq : 503 rounddown_pow_of_two(func.max_eq); 504 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MAX_EQ_OFFSET); 505 size = func.rsvd_eqs; 506 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); 507 } 508 509 size = priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[slave]; 510 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET); 511 size = dev->caps.num_mpts; 512 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET_DEP); 513 514 size = priv->mfunc.master.res_tracker.res_alloc[RES_MTT].quota[slave]; 515 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET); 516 size = dev->caps.num_mtts; 517 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET_DEP); 518 519 size = dev->caps.num_mgms + dev->caps.num_amgms; 520 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET); 521 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET_DEP); 522 523 size = QUERY_FUNC_CAP_EXTRA_FLAGS_BF_QP_ALLOC_FLAG | 524 QUERY_FUNC_CAP_EXTRA_FLAGS_A0_QP_ALLOC_FLAG; 525 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_EXTRA_FLAGS_OFFSET); 526 527 size = dev->caps.reserved_lkey + ((slave << 8) & 0xFF00); 528 MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_RESD_LKEY_OFFSET); 529 530 if (vhcr->in_modifier & QUERY_FUNC_CAP_SUPPORTS_VST_QINQ) 531 slave_state->vst_qinq_supported = true; 532 533 } else 534 err = -EINVAL; 535 536 return err; 537} 538 539int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u8 gen_or_port, 540 struct mlx4_func_cap *func_cap) 541{ 542 struct mlx4_cmd_mailbox *mailbox; 543 u32 *outbox; 544 u8 field, op_modifier; 545 u32 size, qkey; 546 int err = 0, quotas = 0; 547 u32 in_modifier; 548 u32 slave_caps; 549 550 op_modifier = !!gen_or_port; /* 0 = general, 1 = logical port */ 551 slave_caps = QUERY_FUNC_CAP_SUPPORTS_VST_QINQ | 552 QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS; 553 in_modifier = op_modifier ? gen_or_port : slave_caps; 554 555 mailbox = mlx4_alloc_cmd_mailbox(dev); 556 if (IS_ERR(mailbox)) 557 return PTR_ERR(mailbox); 558 559 err = mlx4_cmd_box(dev, 0, mailbox->dma, in_modifier, op_modifier, 560 MLX4_CMD_QUERY_FUNC_CAP, 561 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); 562 if (err) 563 goto out; 564 565 outbox = mailbox->buf; 566 567 if (!op_modifier) { 568 MLX4_GET(field, outbox, QUERY_FUNC_CAP_FLAGS_OFFSET); 569 if (!(field & (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA))) { 570 mlx4_err(dev, "The host supports neither eth nor rdma interfaces\n"); 571 err = -EPROTONOSUPPORT; 572 goto out; 573 } 574 func_cap->flags = field; 575 quotas = !!(func_cap->flags & QUERY_FUNC_CAP_FLAG_QUOTAS); 576 577 MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); 578 func_cap->num_ports = field; 579 580 MLX4_GET(size, outbox, QUERY_FUNC_CAP_PF_BHVR_OFFSET); 581 func_cap->pf_context_behaviour = size; 582 583 if (quotas) { 584 MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); 585 func_cap->qp_quota = size & 0xFFFFFF; 586 587 MLX4_GET(size, outbox, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET); 588 func_cap->srq_quota = size & 0xFFFFFF; 589 590 MLX4_GET(size, outbox, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET); 591 func_cap->cq_quota = size & 0xFFFFFF; 592 593 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET); 594 func_cap->mpt_quota = size & 0xFFFFFF; 595 596 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET); 597 func_cap->mtt_quota = size & 0xFFFFFF; 598 599 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET); 600 func_cap->mcg_quota = size & 0xFFFFFF; 601 602 } else { 603 MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_QUOTA_OFFSET_DEP); 604 func_cap->qp_quota = size & 0xFFFFFF; 605 606 MLX4_GET(size, outbox, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET_DEP); 607 func_cap->srq_quota = size & 0xFFFFFF; 608 609 MLX4_GET(size, outbox, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP); 610 func_cap->cq_quota = size & 0xFFFFFF; 611 612 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET_DEP); 613 func_cap->mpt_quota = size & 0xFFFFFF; 614 615 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET_DEP); 616 func_cap->mtt_quota = size & 0xFFFFFF; 617 618 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET_DEP); 619 func_cap->mcg_quota = size & 0xFFFFFF; 620 } 621 MLX4_GET(size, outbox, QUERY_FUNC_CAP_MAX_EQ_OFFSET); 622 func_cap->max_eq = size & 0xFFFFFF; 623 624 MLX4_GET(size, outbox, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); 625 func_cap->reserved_eq = size & 0xFFFFFF; 626 627 if (func_cap->flags & QUERY_FUNC_CAP_FLAG_RESD_LKEY) { 628 MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_RESD_LKEY_OFFSET); 629 func_cap->reserved_lkey = size; 630 } else { 631 func_cap->reserved_lkey = 0; 632 } 633 634 func_cap->extra_flags = 0; 635 636 /* Mailbox data from 0x6c and onward should only be treated if 637 * QUERY_FUNC_CAP_FLAG_VALID_MAILBOX is set in func_cap->flags 638 */ 639 if (func_cap->flags & QUERY_FUNC_CAP_FLAG_VALID_MAILBOX) { 640 MLX4_GET(size, outbox, QUERY_FUNC_CAP_EXTRA_FLAGS_OFFSET); 641 if (size & QUERY_FUNC_CAP_EXTRA_FLAGS_BF_QP_ALLOC_FLAG) 642 func_cap->extra_flags |= MLX4_QUERY_FUNC_FLAGS_BF_RES_QP; 643 if (size & QUERY_FUNC_CAP_EXTRA_FLAGS_A0_QP_ALLOC_FLAG) 644 func_cap->extra_flags |= MLX4_QUERY_FUNC_FLAGS_A0_RES_QP; 645 } 646 647 goto out; 648 } 649 650 /* logical port query */ 651 if (gen_or_port > dev->caps.num_ports) { 652 err = -EINVAL; 653 goto out; 654 } 655 656 MLX4_GET(func_cap->flags1, outbox, QUERY_FUNC_CAP_FLAGS1_OFFSET); 657 if (dev->caps.port_type[gen_or_port] == MLX4_PORT_TYPE_ETH) { 658 if (func_cap->flags1 & QUERY_FUNC_CAP_FLAGS1_FORCE_VLAN) { 659 mlx4_err(dev, "VLAN is enforced on this port\n"); 660 err = -EPROTONOSUPPORT; 661 goto out; 662 } 663 664 if (func_cap->flags1 & QUERY_FUNC_CAP_FLAGS1_FORCE_MAC) { 665 mlx4_err(dev, "Force mac is enabled on this port\n"); 666 err = -EPROTONOSUPPORT; 667 goto out; 668 } 669 } else if (dev->caps.port_type[gen_or_port] == MLX4_PORT_TYPE_IB) { 670 MLX4_GET(field, outbox, QUERY_FUNC_CAP_FLAGS0_OFFSET); 671 if (field & QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID) { 672 mlx4_err(dev, "phy_wqe_gid is enforced on this ib port\n"); 673 err = -EPROTONOSUPPORT; 674 goto out; 675 } 676 } 677 678 MLX4_GET(field, outbox, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); 679 func_cap->physical_port = field; 680 if (func_cap->physical_port != gen_or_port) { 681 err = -EINVAL; 682 goto out; 683 } 684 685 if (func_cap->flags1 & QUERY_FUNC_CAP_VF_ENABLE_QP0) { 686 MLX4_GET(qkey, outbox, QUERY_FUNC_CAP_PRIV_VF_QKEY_OFFSET); 687 func_cap->spec_qps.qp0_qkey = qkey; 688 } else { 689 func_cap->spec_qps.qp0_qkey = 0; 690 } 691 692 MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP0_TUNNEL); 693 func_cap->spec_qps.qp0_tunnel = size & 0xFFFFFF; 694 695 MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP0_PROXY); 696 func_cap->spec_qps.qp0_proxy = size & 0xFFFFFF; 697 698 MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP1_TUNNEL); 699 func_cap->spec_qps.qp1_tunnel = size & 0xFFFFFF; 700 701 MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP1_PROXY); 702 func_cap->spec_qps.qp1_proxy = size & 0xFFFFFF; 703 704 if (func_cap->flags1 & QUERY_FUNC_CAP_FLAGS1_NIC_INFO) 705 MLX4_GET(func_cap->phys_port_id, outbox, 706 QUERY_FUNC_CAP_PHYS_PORT_ID); 707 708 MLX4_GET(func_cap->flags0, outbox, QUERY_FUNC_CAP_FLAGS0_OFFSET); 709 710 /* All other resources are allocated by the master, but we still report 711 * 'num' and 'reserved' capabilities as follows: 712 * - num remains the maximum resource index 713 * - 'num - reserved' is the total available objects of a resource, but 714 * resource indices may be less than 'reserved' 715 * TODO: set per-resource quotas */ 716 717out: 718 mlx4_free_cmd_mailbox(dev, mailbox); 719 720 return err; 721} 722 723static void disable_unsupported_roce_caps(void *buf); 724 725int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) 726{ 727 struct mlx4_cmd_mailbox *mailbox; 728 u32 *outbox; 729 u8 field; 730 u32 field32, flags, ext_flags; 731 u16 size; 732 u16 stat_rate; 733 int err; 734 int i; 735 736#define QUERY_DEV_CAP_OUT_SIZE 0x100 737#define QUERY_DEV_CAP_MAX_SRQ_SZ_OFFSET 0x10 738#define QUERY_DEV_CAP_MAX_QP_SZ_OFFSET 0x11 739#define QUERY_DEV_CAP_RSVD_QP_OFFSET 0x12 740#define QUERY_DEV_CAP_MAX_QP_OFFSET 0x13 741#define QUERY_DEV_CAP_RSVD_SRQ_OFFSET 0x14 742#define QUERY_DEV_CAP_MAX_SRQ_OFFSET 0x15 743#define QUERY_DEV_CAP_RSVD_EEC_OFFSET 0x16 744#define QUERY_DEV_CAP_MAX_EEC_OFFSET 0x17 745#define QUERY_DEV_CAP_MAX_CQ_SZ_OFFSET 0x19 746#define QUERY_DEV_CAP_RSVD_CQ_OFFSET 0x1a 747#define QUERY_DEV_CAP_MAX_CQ_OFFSET 0x1b 748#define QUERY_DEV_CAP_MAX_MPT_OFFSET 0x1d 749#define QUERY_DEV_CAP_RSVD_EQ_OFFSET 0x1e 750#define QUERY_DEV_CAP_MAX_EQ_OFFSET 0x1f 751#define QUERY_DEV_CAP_RSVD_MTT_OFFSET 0x20 752#define QUERY_DEV_CAP_MAX_MRW_SZ_OFFSET 0x21 753#define QUERY_DEV_CAP_RSVD_MRW_OFFSET 0x22 754#define QUERY_DEV_CAP_MAX_MTT_SEG_OFFSET 0x23 755#define QUERY_DEV_CAP_NUM_SYS_EQ_OFFSET 0x26 756#define QUERY_DEV_CAP_MAX_AV_OFFSET 0x27 757#define QUERY_DEV_CAP_MAX_REQ_QP_OFFSET 0x29 758#define QUERY_DEV_CAP_MAX_RES_QP_OFFSET 0x2b 759#define QUERY_DEV_CAP_MAX_GSO_OFFSET 0x2d 760#define QUERY_DEV_CAP_RSS_OFFSET 0x2e 761#define QUERY_DEV_CAP_MAX_RDMA_OFFSET 0x2f 762#define QUERY_DEV_CAP_RSZ_SRQ_OFFSET 0x33 763#define QUERY_DEV_CAP_PORT_BEACON_OFFSET 0x34 764#define QUERY_DEV_CAP_ACK_DELAY_OFFSET 0x35 765#define QUERY_DEV_CAP_MTU_WIDTH_OFFSET 0x36 766#define QUERY_DEV_CAP_VL_PORT_OFFSET 0x37 767#define QUERY_DEV_CAP_MAX_MSG_SZ_OFFSET 0x38 768#define QUERY_DEV_CAP_MAX_GID_OFFSET 0x3b 769#define QUERY_DEV_CAP_RATE_SUPPORT_OFFSET 0x3c 770#define QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET 0x3e 771#define QUERY_DEV_CAP_MAX_PKEY_OFFSET 0x3f 772#define QUERY_DEV_CAP_EXT_FLAGS_OFFSET 0x40 773#define QUERY_DEV_CAP_WOL_OFFSET 0x43 774#define QUERY_DEV_CAP_FLAGS_OFFSET 0x44 775#define QUERY_DEV_CAP_RSVD_UAR_OFFSET 0x48 776#define QUERY_DEV_CAP_UAR_SZ_OFFSET 0x49 777#define QUERY_DEV_CAP_PAGE_SZ_OFFSET 0x4b 778#define QUERY_DEV_CAP_BF_OFFSET 0x4c 779#define QUERY_DEV_CAP_LOG_BF_REG_SZ_OFFSET 0x4d 780#define QUERY_DEV_CAP_LOG_MAX_BF_REGS_PER_PAGE_OFFSET 0x4e 781#define QUERY_DEV_CAP_LOG_MAX_BF_PAGES_OFFSET 0x4f 782#define QUERY_DEV_CAP_MAX_SG_SQ_OFFSET 0x51 783#define QUERY_DEV_CAP_MAX_DESC_SZ_SQ_OFFSET 0x52 784#define QUERY_DEV_CAP_MAX_SG_RQ_OFFSET 0x55 785#define QUERY_DEV_CAP_MAX_DESC_SZ_RQ_OFFSET 0x56 786#define QUERY_DEV_CAP_USER_MAC_EN_OFFSET 0x5C 787#define QUERY_DEV_CAP_SVLAN_BY_QP_OFFSET 0x5D 788#define QUERY_DEV_CAP_MAX_QP_MCG_OFFSET 0x61 789#define QUERY_DEV_CAP_RSVD_MCG_OFFSET 0x62 790#define QUERY_DEV_CAP_MAX_MCG_OFFSET 0x63 791#define QUERY_DEV_CAP_RSVD_PD_OFFSET 0x64 792#define QUERY_DEV_CAP_MAX_PD_OFFSET 0x65 793#define QUERY_DEV_CAP_RSVD_XRC_OFFSET 0x66 794#define QUERY_DEV_CAP_MAX_XRC_OFFSET 0x67 795#define QUERY_DEV_CAP_MAX_COUNTERS_OFFSET 0x68 796#define QUERY_DEV_CAP_PORT_FLOWSTATS_COUNTERS_OFFSET 0x70 797#define QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET 0x70 798#define QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET 0x74 799#define QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET 0x76 800#define QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET 0x77 801#define QUERY_DEV_CAP_SL2VL_EVENT_OFFSET 0x78 802#define QUERY_DEV_CAP_CQ_EQ_CACHE_LINE_STRIDE 0x7a 803#define QUERY_DEV_CAP_ECN_QCN_VER_OFFSET 0x7b 804#define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80 805#define QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET 0x82 806#define QUERY_DEV_CAP_AUX_ENTRY_SZ_OFFSET 0x84 807#define QUERY_DEV_CAP_ALTC_ENTRY_SZ_OFFSET 0x86 808#define QUERY_DEV_CAP_EQC_ENTRY_SZ_OFFSET 0x88 809#define QUERY_DEV_CAP_CQC_ENTRY_SZ_OFFSET 0x8a 810#define QUERY_DEV_CAP_SRQ_ENTRY_SZ_OFFSET 0x8c 811#define QUERY_DEV_CAP_C_MPT_ENTRY_SZ_OFFSET 0x8e 812#define QUERY_DEV_CAP_MTT_ENTRY_SZ_OFFSET 0x90 813#define QUERY_DEV_CAP_D_MPT_ENTRY_SZ_OFFSET 0x92 814#define QUERY_DEV_CAP_BMME_FLAGS_OFFSET 0x94 815#define QUERY_DEV_CAP_CONFIG_DEV_OFFSET 0x94 816#define QUERY_DEV_CAP_PHV_EN_OFFSET 0x96 817#define QUERY_DEV_CAP_RSVD_LKEY_OFFSET 0x98 818#define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET 0xa0 819#define QUERY_DEV_CAP_ETH_BACKPL_OFFSET 0x9c 820#define QUERY_DEV_CAP_DIAG_RPRT_PER_PORT 0x9c 821#define QUERY_DEV_CAP_FW_REASSIGN_MAC 0x9d 822#define QUERY_DEV_CAP_VXLAN 0x9e 823#define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0 824#define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_BASE_OFFSET 0xa8 825#define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET 0xac 826#define QUERY_DEV_CAP_MAP_CLOCK_TO_USER 0xc1 827#define QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET 0xcc 828#define QUERY_DEV_CAP_QP_RATE_LIMIT_MAX_OFFSET 0xd0 829#define QUERY_DEV_CAP_QP_RATE_LIMIT_MIN_OFFSET 0xd2 830#define QUERY_DEV_CAP_HEALTH_BUFFER_ADDRESS_OFFSET 0xe4 831 832 dev_cap->flags2 = 0; 833 mailbox = mlx4_alloc_cmd_mailbox(dev); 834 if (IS_ERR(mailbox)) 835 return PTR_ERR(mailbox); 836 outbox = mailbox->buf; 837 838 err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP, 839 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 840 if (err) 841 goto out; 842 843 if (mlx4_is_mfunc(dev)) 844 disable_unsupported_roce_caps(outbox); 845 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAP_CLOCK_TO_USER); 846 dev_cap->map_clock_to_user = field & 0x80; 847 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_QP_OFFSET); 848 dev_cap->reserved_qps = 1 << (field & 0xf); 849 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_QP_OFFSET); 850 dev_cap->max_qps = 1 << (field & 0x1f); 851 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_SRQ_OFFSET); 852 dev_cap->reserved_srqs = 1 << (field >> 4); 853 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_SRQ_OFFSET); 854 dev_cap->max_srqs = 1 << (field & 0x1f); 855 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_CQ_SZ_OFFSET); 856 dev_cap->max_cq_sz = 1 << field; 857 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_CQ_OFFSET); 858 dev_cap->reserved_cqs = 1 << (field & 0xf); 859 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_CQ_OFFSET); 860 dev_cap->max_cqs = 1 << (field & 0x1f); 861 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MPT_OFFSET); 862 dev_cap->max_mpts = 1 << (field & 0x3f); 863 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_EQ_OFFSET); 864 dev_cap->reserved_eqs = 1 << (field & 0xf); 865 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_EQ_OFFSET); 866 dev_cap->max_eqs = 1 << (field & 0xf); 867 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_MTT_OFFSET); 868 dev_cap->reserved_mtts = 1 << (field >> 4); 869 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_MRW_OFFSET); 870 dev_cap->reserved_mrws = 1 << (field & 0xf); 871 MLX4_GET(size, outbox, QUERY_DEV_CAP_NUM_SYS_EQ_OFFSET); 872 dev_cap->num_sys_eqs = size & 0xfff; 873 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_REQ_QP_OFFSET); 874 dev_cap->max_requester_per_qp = 1 << (field & 0x3f); 875 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_RES_QP_OFFSET); 876 dev_cap->max_responder_per_qp = 1 << (field & 0x3f); 877 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_GSO_OFFSET); 878 field &= 0x1f; 879 if (!field) 880 dev_cap->max_gso_sz = 0; 881 else 882 dev_cap->max_gso_sz = 1 << field; 883 884 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSS_OFFSET); 885 if (field & 0x20) 886 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RSS_XOR; 887 if (field & 0x10) 888 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RSS_TOP; 889 field &= 0xf; 890 if (field) { 891 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RSS; 892 dev_cap->max_rss_tbl_sz = 1 << field; 893 } else 894 dev_cap->max_rss_tbl_sz = 0; 895 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_RDMA_OFFSET); 896 dev_cap->max_rdma_global = 1 << (field & 0x3f); 897 MLX4_GET(field, outbox, QUERY_DEV_CAP_ACK_DELAY_OFFSET); 898 dev_cap->local_ca_ack_delay = field & 0x1f; 899 MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET); 900 dev_cap->num_ports = field & 0xf; 901 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MSG_SZ_OFFSET); 902 dev_cap->max_msg_sz = 1 << (field & 0x1f); 903 MLX4_GET(field, outbox, QUERY_DEV_CAP_PORT_FLOWSTATS_COUNTERS_OFFSET); 904 if (field & 0x10) 905 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_FLOWSTATS_EN; 906 MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET); 907 if (field & 0x80) 908 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_FS_EN; 909 dev_cap->fs_log_max_ucast_qp_range_size = field & 0x1f; 910 if (field & 0x20) 911 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_DMFS_UC_MC_SNIFFER; 912 MLX4_GET(field, outbox, QUERY_DEV_CAP_PORT_BEACON_OFFSET); 913 if (field & 0x80) 914 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_PORT_BEACON; 915 MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET); 916 if (field & 0x80) 917 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_DMFS_IPOIB; 918 MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET); 919 dev_cap->fs_max_num_qp_per_entry = field; 920 MLX4_GET(field, outbox, QUERY_DEV_CAP_SL2VL_EVENT_OFFSET); 921 if (field & (1 << 5)) 922 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_SL_TO_VL_CHANGE_EVENT; 923 MLX4_GET(field, outbox, QUERY_DEV_CAP_ECN_QCN_VER_OFFSET); 924 if (field & 0x1) 925 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_QCN; 926 MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET); 927 dev_cap->stat_rate_support = stat_rate; 928 MLX4_GET(field, outbox, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET); 929 if (field & 0x80) 930 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_TS; 931 MLX4_GET(ext_flags, outbox, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); 932 MLX4_GET(flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET); 933 dev_cap->flags = flags | (u64)ext_flags << 32; 934 MLX4_GET(field, outbox, QUERY_DEV_CAP_WOL_OFFSET); 935 dev_cap->wol_port[1] = !!(field & 0x20); 936 dev_cap->wol_port[2] = !!(field & 0x40); 937 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET); 938 dev_cap->reserved_uars = field >> 4; 939 MLX4_GET(field, outbox, QUERY_DEV_CAP_UAR_SZ_OFFSET); 940 dev_cap->uar_size = 1 << ((field & 0x3f) + 20); 941 MLX4_GET(field, outbox, QUERY_DEV_CAP_PAGE_SZ_OFFSET); 942 dev_cap->min_page_sz = 1 << field; 943 944 MLX4_GET(field, outbox, QUERY_DEV_CAP_BF_OFFSET); 945 if (field & 0x80) { 946 MLX4_GET(field, outbox, QUERY_DEV_CAP_LOG_BF_REG_SZ_OFFSET); 947 dev_cap->bf_reg_size = 1 << (field & 0x1f); 948 MLX4_GET(field, outbox, QUERY_DEV_CAP_LOG_MAX_BF_REGS_PER_PAGE_OFFSET); 949 if ((1 << (field & 0x3f)) > (PAGE_SIZE / dev_cap->bf_reg_size)) 950 field = 3; 951 dev_cap->bf_regs_per_page = 1 << (field & 0x3f); 952 } else { 953 dev_cap->bf_reg_size = 0; 954 } 955 956 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_SG_SQ_OFFSET); 957 dev_cap->max_sq_sg = field; 958 MLX4_GET(size, outbox, QUERY_DEV_CAP_MAX_DESC_SZ_SQ_OFFSET); 959 dev_cap->max_sq_desc_sz = size; 960 961 MLX4_GET(field, outbox, QUERY_DEV_CAP_USER_MAC_EN_OFFSET); 962 if (field & (1 << 2)) 963 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_USER_MAC_EN; 964 MLX4_GET(field, outbox, QUERY_DEV_CAP_SVLAN_BY_QP_OFFSET); 965 if (field & 0x1) 966 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_SVLAN_BY_QP; 967 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_QP_MCG_OFFSET); 968 dev_cap->max_qp_per_mcg = 1 << field; 969 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_MCG_OFFSET); 970 dev_cap->reserved_mgms = field & 0xf; 971 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MCG_OFFSET); 972 dev_cap->max_mcgs = 1 << field; 973 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_PD_OFFSET); 974 dev_cap->reserved_pds = field >> 4; 975 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_PD_OFFSET); 976 dev_cap->max_pds = 1 << (field & 0x3f); 977 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_XRC_OFFSET); 978 dev_cap->reserved_xrcds = field >> 4; 979 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_XRC_OFFSET); 980 dev_cap->max_xrcds = 1 << (field & 0x1f); 981 982 MLX4_GET(size, outbox, QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET); 983 dev_cap->rdmarc_entry_sz = size; 984 MLX4_GET(size, outbox, QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET); 985 dev_cap->qpc_entry_sz = size; 986 MLX4_GET(size, outbox, QUERY_DEV_CAP_AUX_ENTRY_SZ_OFFSET); 987 dev_cap->aux_entry_sz = size; 988 MLX4_GET(size, outbox, QUERY_DEV_CAP_ALTC_ENTRY_SZ_OFFSET); 989 dev_cap->altc_entry_sz = size; 990 MLX4_GET(size, outbox, QUERY_DEV_CAP_EQC_ENTRY_SZ_OFFSET); 991 dev_cap->eqc_entry_sz = size; 992 MLX4_GET(size, outbox, QUERY_DEV_CAP_CQC_ENTRY_SZ_OFFSET); 993 dev_cap->cqc_entry_sz = size; 994 MLX4_GET(size, outbox, QUERY_DEV_CAP_SRQ_ENTRY_SZ_OFFSET); 995 dev_cap->srq_entry_sz = size; 996 MLX4_GET(size, outbox, QUERY_DEV_CAP_C_MPT_ENTRY_SZ_OFFSET); 997 dev_cap->cmpt_entry_sz = size; 998 MLX4_GET(size, outbox, QUERY_DEV_CAP_MTT_ENTRY_SZ_OFFSET); 999 dev_cap->mtt_entry_sz = size; 1000 MLX4_GET(size, outbox, QUERY_DEV_CAP_D_MPT_ENTRY_SZ_OFFSET); 1001 dev_cap->dmpt_entry_sz = size; 1002 1003 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_SRQ_SZ_OFFSET); 1004 dev_cap->max_srq_sz = 1 << field; 1005 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_QP_SZ_OFFSET); 1006 dev_cap->max_qp_sz = 1 << field; 1007 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSZ_SRQ_OFFSET); 1008 dev_cap->resize_srq = field & 1; 1009 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_SG_RQ_OFFSET); 1010 dev_cap->max_rq_sg = field; 1011 MLX4_GET(size, outbox, QUERY_DEV_CAP_MAX_DESC_SZ_RQ_OFFSET); 1012 dev_cap->max_rq_desc_sz = size; 1013 MLX4_GET(field, outbox, QUERY_DEV_CAP_CQ_EQ_CACHE_LINE_STRIDE); 1014 if (field & (1 << 4)) 1015 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_QOS_VPP; 1016 if (field & (1 << 5)) 1017 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL; 1018 if (field & (1 << 6)) 1019 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_CQE_STRIDE; 1020 if (field & (1 << 7)) 1021 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_EQE_STRIDE; 1022 MLX4_GET(dev_cap->bmme_flags, outbox, 1023 QUERY_DEV_CAP_BMME_FLAGS_OFFSET); 1024 if (dev_cap->bmme_flags & MLX4_FLAG_ROCE_V1_V2) 1025 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_ROCE_V1_V2; 1026 if (dev_cap->bmme_flags & MLX4_FLAG_PORT_REMAP) 1027 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_PORT_REMAP; 1028 MLX4_GET(field, outbox, QUERY_DEV_CAP_CONFIG_DEV_OFFSET); 1029 if (field & 0x20) 1030 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_CONFIG_DEV; 1031 if (field & (1 << 2)) 1032 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_IGNORE_FCS; 1033 MLX4_GET(field, outbox, QUERY_DEV_CAP_PHV_EN_OFFSET); 1034 if (field & 0x80) 1035 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_PHV_EN; 1036 if (field & 0x40) 1037 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_SKIP_OUTER_VLAN; 1038 1039 MLX4_GET(dev_cap->reserved_lkey, outbox, 1040 QUERY_DEV_CAP_RSVD_LKEY_OFFSET); 1041 MLX4_GET(field32, outbox, QUERY_DEV_CAP_ETH_BACKPL_OFFSET); 1042 if (field32 & (1 << 0)) 1043 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP; 1044 if (field32 & (1 << 7)) 1045 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RECOVERABLE_ERROR_EVENT; 1046 if (field32 & (1 << 8)) 1047 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_DRIVER_VERSION_TO_FW; 1048 MLX4_GET(field32, outbox, QUERY_DEV_CAP_DIAG_RPRT_PER_PORT); 1049 if (field32 & (1 << 17)) 1050 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_DIAG_PER_PORT; 1051 MLX4_GET(field, outbox, QUERY_DEV_CAP_FW_REASSIGN_MAC); 1052 if (field & 1<<6) 1053 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_REASSIGN_MAC_EN; 1054 MLX4_GET(field, outbox, QUERY_DEV_CAP_VXLAN); 1055 if (field & 1<<3) 1056 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS; 1057 if (field & (1 << 5)) 1058 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_ETS_CFG; 1059 MLX4_GET(dev_cap->max_icm_sz, outbox, 1060 QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET); 1061 if (dev_cap->flags & MLX4_DEV_CAP_FLAG_COUNTERS) 1062 MLX4_GET(dev_cap->max_counters, outbox, 1063 QUERY_DEV_CAP_MAX_COUNTERS_OFFSET); 1064 1065 MLX4_GET(field32, outbox, 1066 QUERY_DEV_CAP_MAD_DEMUX_OFFSET); 1067 if (field32 & (1 << 0)) 1068 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_MAD_DEMUX; 1069 1070 MLX4_GET(dev_cap->dmfs_high_rate_qpn_base, outbox, 1071 QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_BASE_OFFSET); 1072 dev_cap->dmfs_high_rate_qpn_base &= MGM_QPN_MASK; 1073 MLX4_GET(dev_cap->dmfs_high_rate_qpn_range, outbox, 1074 QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET); 1075 dev_cap->dmfs_high_rate_qpn_range &= MGM_QPN_MASK; 1076 1077 MLX4_GET(size, outbox, QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET); 1078 dev_cap->rl_caps.num_rates = size; 1079 if (dev_cap->rl_caps.num_rates) { 1080 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_QP_RATE_LIMIT; 1081 MLX4_GET(size, outbox, QUERY_DEV_CAP_QP_RATE_LIMIT_MAX_OFFSET); 1082 dev_cap->rl_caps.max_val = size & 0xfff; 1083 dev_cap->rl_caps.max_unit = size >> 14; 1084 MLX4_GET(size, outbox, QUERY_DEV_CAP_QP_RATE_LIMIT_MIN_OFFSET); 1085 dev_cap->rl_caps.min_val = size & 0xfff; 1086 dev_cap->rl_caps.min_unit = size >> 14; 1087 } 1088 1089 MLX4_GET(dev_cap->health_buffer_addrs, outbox, 1090 QUERY_DEV_CAP_HEALTH_BUFFER_ADDRESS_OFFSET); 1091 1092 MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); 1093 if (field32 & (1 << 16)) 1094 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP; 1095 if (field32 & (1 << 18)) 1096 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP_SRC_CHECK_LB; 1097 if (field32 & (1 << 19)) 1098 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_LB_SRC_CHK; 1099 if (field32 & (1 << 26)) 1100 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_VLAN_CONTROL; 1101 if (field32 & (1 << 20)) 1102 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_FSM; 1103 if (field32 & (1 << 21)) 1104 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_80_VFS; 1105 if (field32 & (1 << 23)) 1106 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_SW_CQ_INIT; 1107 1108 for (i = 1; i <= dev_cap->num_ports; i++) { 1109 err = mlx4_QUERY_PORT(dev, i, dev_cap->port_cap + i); 1110 if (err) 1111 goto out; 1112 } 1113 1114 /* 1115 * Each UAR has 4 EQ doorbells; so if a UAR is reserved, then 1116 * we can't use any EQs whose doorbell falls on that page, 1117 * even if the EQ itself isn't reserved. 1118 */ 1119 if (dev_cap->num_sys_eqs == 0) 1120 dev_cap->reserved_eqs = max(dev_cap->reserved_uars * 4, 1121 dev_cap->reserved_eqs); 1122 else 1123 dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_SYS_EQS; 1124 1125out: 1126 mlx4_free_cmd_mailbox(dev, mailbox); 1127 return err; 1128} 1129 1130void mlx4_dev_cap_dump(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) 1131{ 1132 if (dev_cap->bf_reg_size > 0) 1133 mlx4_dbg(dev, "BlueFlame available (reg size %d, regs/page %d)\n", 1134 dev_cap->bf_reg_size, dev_cap->bf_regs_per_page); 1135 else 1136 mlx4_dbg(dev, "BlueFlame not available\n"); 1137 1138 mlx4_dbg(dev, "Base MM extensions: flags %08x, rsvd L_Key %08x\n", 1139 dev_cap->bmme_flags, dev_cap->reserved_lkey); 1140 mlx4_dbg(dev, "Max ICM size %lld MB\n", 1141 (unsigned long long) dev_cap->max_icm_sz >> 20); 1142 mlx4_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n", 1143 dev_cap->max_qps, dev_cap->reserved_qps, dev_cap->qpc_entry_sz); 1144 mlx4_dbg(dev, "Max SRQs: %d, reserved SRQs: %d, entry size: %d\n", 1145 dev_cap->max_srqs, dev_cap->reserved_srqs, dev_cap->srq_entry_sz); 1146 mlx4_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n", 1147 dev_cap->max_cqs, dev_cap->reserved_cqs, dev_cap->cqc_entry_sz); 1148 mlx4_dbg(dev, "Num sys EQs: %d, max EQs: %d, reserved EQs: %d, entry size: %d\n", 1149 dev_cap->num_sys_eqs, dev_cap->max_eqs, dev_cap->reserved_eqs, 1150 dev_cap->eqc_entry_sz); 1151 mlx4_dbg(dev, "reserved MPTs: %d, reserved MTTs: %d\n", 1152 dev_cap->reserved_mrws, dev_cap->reserved_mtts); 1153 mlx4_dbg(dev, "Max PDs: %d, reserved PDs: %d, reserved UARs: %d\n", 1154 dev_cap->max_pds, dev_cap->reserved_pds, dev_cap->reserved_uars); 1155 mlx4_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n", 1156 dev_cap->max_pds, dev_cap->reserved_mgms); 1157 mlx4_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n", 1158 dev_cap->max_cq_sz, dev_cap->max_qp_sz, dev_cap->max_srq_sz); 1159 mlx4_dbg(dev, "Local CA ACK delay: %d, max MTU: %d, port width cap: %d\n", 1160 dev_cap->local_ca_ack_delay, 128 << dev_cap->port_cap[1].ib_mtu, 1161 dev_cap->port_cap[1].max_port_width); 1162 mlx4_dbg(dev, "Max SQ desc size: %d, max SQ S/G: %d\n", 1163 dev_cap->max_sq_desc_sz, dev_cap->max_sq_sg); 1164 mlx4_dbg(dev, "Max RQ desc size: %d, max RQ S/G: %d\n", 1165 dev_cap->max_rq_desc_sz, dev_cap->max_rq_sg); 1166 mlx4_dbg(dev, "Max GSO size: %d\n", dev_cap->max_gso_sz); 1167 mlx4_dbg(dev, "Max counters: %d\n", dev_cap->max_counters); 1168 mlx4_dbg(dev, "Max RSS Table size: %d\n", dev_cap->max_rss_tbl_sz); 1169 mlx4_dbg(dev, "DMFS high rate steer QPn base: %d\n", 1170 dev_cap->dmfs_high_rate_qpn_base); 1171 mlx4_dbg(dev, "DMFS high rate steer QPn range: %d\n", 1172 dev_cap->dmfs_high_rate_qpn_range); 1173 1174 if (dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_QP_RATE_LIMIT) { 1175 struct mlx4_rate_limit_caps *rl_caps = &dev_cap->rl_caps; 1176 1177 mlx4_dbg(dev, "QP Rate-Limit: #rates %d, unit/val max %d/%d, min %d/%d\n", 1178 rl_caps->num_rates, rl_caps->max_unit, rl_caps->max_val, 1179 rl_caps->min_unit, rl_caps->min_val); 1180 } 1181 1182 dump_dev_cap_flags(dev, dev_cap->flags); 1183 dump_dev_cap_flags2(dev, dev_cap->flags2); 1184} 1185 1186int mlx4_QUERY_PORT(struct mlx4_dev *dev, int port, struct mlx4_port_cap *port_cap) 1187{ 1188 struct mlx4_cmd_mailbox *mailbox; 1189 u32 *outbox; 1190 u8 field; 1191 u32 field32; 1192 int err; 1193 1194 mailbox = mlx4_alloc_cmd_mailbox(dev); 1195 if (IS_ERR(mailbox)) 1196 return PTR_ERR(mailbox); 1197 outbox = mailbox->buf; 1198 1199 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { 1200 err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP, 1201 MLX4_CMD_TIME_CLASS_A, 1202 MLX4_CMD_NATIVE); 1203 1204 if (err) 1205 goto out; 1206 1207 MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET); 1208 port_cap->max_vl = field >> 4; 1209 MLX4_GET(field, outbox, QUERY_DEV_CAP_MTU_WIDTH_OFFSET); 1210 port_cap->ib_mtu = field >> 4; 1211 port_cap->max_port_width = field & 0xf; 1212 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_GID_OFFSET); 1213 port_cap->max_gids = 1 << (field & 0xf); 1214 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_PKEY_OFFSET); 1215 port_cap->max_pkeys = 1 << (field & 0xf); 1216 } else { 1217#define QUERY_PORT_SUPPORTED_TYPE_OFFSET 0x00 1218#define QUERY_PORT_MTU_OFFSET 0x01 1219#define QUERY_PORT_ETH_MTU_OFFSET 0x02 1220#define QUERY_PORT_WIDTH_OFFSET 0x06 1221#define QUERY_PORT_MAX_GID_PKEY_OFFSET 0x07 1222#define QUERY_PORT_MAX_MACVLAN_OFFSET 0x0a 1223#define QUERY_PORT_MAX_VL_OFFSET 0x0b 1224#define QUERY_PORT_MAC_OFFSET 0x10 1225#define QUERY_PORT_TRANS_VENDOR_OFFSET 0x18 1226#define QUERY_PORT_WAVELENGTH_OFFSET 0x1c 1227#define QUERY_PORT_TRANS_CODE_OFFSET 0x20 1228 1229 err = mlx4_cmd_box(dev, 0, mailbox->dma, port, 0, MLX4_CMD_QUERY_PORT, 1230 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 1231 if (err) 1232 goto out; 1233 1234 MLX4_GET(field, outbox, QUERY_PORT_SUPPORTED_TYPE_OFFSET); 1235 port_cap->link_state = (field & 0x80) >> 7; 1236 port_cap->supported_port_types = field & 3; 1237 port_cap->suggested_type = (field >> 3) & 1; 1238 port_cap->default_sense = (field >> 4) & 1; 1239 port_cap->dmfs_optimized_state = (field >> 5) & 1; 1240 MLX4_GET(field, outbox, QUERY_PORT_MTU_OFFSET); 1241 port_cap->ib_mtu = field & 0xf; 1242 MLX4_GET(field, outbox, QUERY_PORT_WIDTH_OFFSET); 1243 port_cap->max_port_width = field & 0xf; 1244 MLX4_GET(field, outbox, QUERY_PORT_MAX_GID_PKEY_OFFSET); 1245 port_cap->max_gids = 1 << (field >> 4); 1246 port_cap->max_pkeys = 1 << (field & 0xf); 1247 MLX4_GET(field, outbox, QUERY_PORT_MAX_VL_OFFSET); 1248 port_cap->max_vl = field & 0xf; 1249 port_cap->max_tc_eth = field >> 4; 1250 MLX4_GET(field, outbox, QUERY_PORT_MAX_MACVLAN_OFFSET); 1251 port_cap->log_max_macs = field & 0xf; 1252 port_cap->log_max_vlans = field >> 4; 1253 MLX4_GET(port_cap->eth_mtu, outbox, QUERY_PORT_ETH_MTU_OFFSET); 1254 MLX4_GET(port_cap->def_mac, outbox, QUERY_PORT_MAC_OFFSET); 1255 MLX4_GET(field32, outbox, QUERY_PORT_TRANS_VENDOR_OFFSET); 1256 port_cap->trans_type = field32 >> 24; 1257 port_cap->vendor_oui = field32 & 0xffffff; 1258 MLX4_GET(port_cap->wavelength, outbox, QUERY_PORT_WAVELENGTH_OFFSET); 1259 MLX4_GET(port_cap->trans_code, outbox, QUERY_PORT_TRANS_CODE_OFFSET); 1260 } 1261 1262out: 1263 mlx4_free_cmd_mailbox(dev, mailbox); 1264 return err; 1265} 1266 1267#define DEV_CAP_EXT_2_FLAG_PFC_COUNTERS (1 << 28) 1268#define DEV_CAP_EXT_2_FLAG_VLAN_CONTROL (1 << 26) 1269#define DEV_CAP_EXT_2_FLAG_80_VFS (1 << 21) 1270#define DEV_CAP_EXT_2_FLAG_FSM (1 << 20) 1271 1272int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, 1273 struct mlx4_vhcr *vhcr, 1274 struct mlx4_cmd_mailbox *inbox, 1275 struct mlx4_cmd_mailbox *outbox, 1276 struct mlx4_cmd_info *cmd) 1277{ 1278 u64 flags; 1279 int err = 0; 1280 u8 field; 1281 u16 field16; 1282 u32 bmme_flags, field32; 1283 int real_port; 1284 int slave_port; 1285 int first_port; 1286 struct mlx4_active_ports actv_ports; 1287 1288 err = mlx4_cmd_box(dev, 0, outbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP, 1289 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 1290 if (err) 1291 return err; 1292 1293 disable_unsupported_roce_caps(outbox->buf); 1294 /* add port mng change event capability and disable mw type 1 1295 * unconditionally to slaves 1296 */ 1297 MLX4_GET(flags, outbox->buf, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); 1298 flags |= MLX4_DEV_CAP_FLAG_PORT_MNG_CHG_EV; 1299 flags &= ~MLX4_DEV_CAP_FLAG_MEM_WINDOW; 1300 actv_ports = mlx4_get_active_ports(dev, slave); 1301 first_port = find_first_bit(actv_ports.ports, dev->caps.num_ports); 1302 for (slave_port = 0, real_port = first_port; 1303 real_port < first_port + 1304 bitmap_weight(actv_ports.ports, dev->caps.num_ports); 1305 ++real_port, ++slave_port) { 1306 if (flags & (MLX4_DEV_CAP_FLAG_WOL_PORT1 << real_port)) 1307 flags |= MLX4_DEV_CAP_FLAG_WOL_PORT1 << slave_port; 1308 else 1309 flags &= ~(MLX4_DEV_CAP_FLAG_WOL_PORT1 << slave_port); 1310 } 1311 for (; slave_port < dev->caps.num_ports; ++slave_port) 1312 flags &= ~(MLX4_DEV_CAP_FLAG_WOL_PORT1 << slave_port); 1313 1314 /* Not exposing RSS IP fragments to guests */ 1315 flags &= ~MLX4_DEV_CAP_FLAG_RSS_IP_FRAG; 1316 MLX4_PUT(outbox->buf, flags, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); 1317 1318 MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_VL_PORT_OFFSET); 1319 field &= ~0x0F; 1320 field |= bitmap_weight(actv_ports.ports, dev->caps.num_ports) & 0x0F; 1321 MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_VL_PORT_OFFSET); 1322 1323 /* For guests, disable timestamp */ 1324 MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET); 1325 field &= 0x7f; 1326 MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET); 1327 1328 /* For guests, disable vxlan tunneling and QoS support */ 1329 MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_VXLAN); 1330 field &= 0xd7; 1331 MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_VXLAN); 1332 1333 /* For guests, disable port BEACON */ 1334 MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_PORT_BEACON_OFFSET); 1335 field &= 0x7f; 1336 MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_PORT_BEACON_OFFSET); 1337 1338 /* For guests, report Blueflame disabled */ 1339 MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_BF_OFFSET); 1340 field &= 0x7f; 1341 MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_BF_OFFSET); 1342 1343 /* For guests, disable mw type 2 and port remap*/ 1344 MLX4_GET(bmme_flags, outbox->buf, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); 1345 bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN; 1346 bmme_flags &= ~MLX4_FLAG_PORT_REMAP; 1347 MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); 1348 1349 /* turn off device-managed steering capability if not enabled */ 1350 if (dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) { 1351 MLX4_GET(field, outbox->buf, 1352 QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET); 1353 field &= 0x7f; 1354 MLX4_PUT(outbox->buf, field, 1355 QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET); 1356 } 1357 1358 /* turn off ipoib managed steering for guests */ 1359 MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET); 1360 field &= ~0x80; 1361 MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET); 1362 1363 /* turn off host side virt features (VST, FSM, etc) for guests */ 1364 MLX4_GET(field32, outbox->buf, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); 1365 field32 &= ~(DEV_CAP_EXT_2_FLAG_VLAN_CONTROL | DEV_CAP_EXT_2_FLAG_80_VFS | 1366 DEV_CAP_EXT_2_FLAG_FSM | DEV_CAP_EXT_2_FLAG_PFC_COUNTERS); 1367 MLX4_PUT(outbox->buf, field32, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); 1368 1369 /* turn off QCN for guests */ 1370 MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_ECN_QCN_VER_OFFSET); 1371 field &= 0xfe; 1372 MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_ECN_QCN_VER_OFFSET); 1373 1374 /* turn off QP max-rate limiting for guests */ 1375 field16 = 0; 1376 MLX4_PUT(outbox->buf, field16, QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET); 1377 1378 /* turn off QoS per VF support for guests */ 1379 MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_CQ_EQ_CACHE_LINE_STRIDE); 1380 field &= 0xef; 1381 MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_CQ_EQ_CACHE_LINE_STRIDE); 1382 1383 /* turn off ignore FCS feature for guests */ 1384 MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_CONFIG_DEV_OFFSET); 1385 field &= 0xfb; 1386 MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_CONFIG_DEV_OFFSET); 1387 1388 return 0; 1389} 1390 1391static void disable_unsupported_roce_caps(void *buf) 1392{ 1393 u32 flags; 1394 1395 MLX4_GET(flags, buf, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); 1396 flags &= ~(1UL << 31); 1397 MLX4_PUT(buf, flags, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); 1398 MLX4_GET(flags, buf, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); 1399 flags &= ~(1UL << 24); 1400 MLX4_PUT(buf, flags, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); 1401 MLX4_GET(flags, buf, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); 1402 flags &= ~(MLX4_FLAG_ROCE_V1_V2); 1403 MLX4_PUT(buf, flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); 1404} 1405 1406int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, 1407 struct mlx4_vhcr *vhcr, 1408 struct mlx4_cmd_mailbox *inbox, 1409 struct mlx4_cmd_mailbox *outbox, 1410 struct mlx4_cmd_info *cmd) 1411{ 1412 struct mlx4_priv *priv = mlx4_priv(dev); 1413 u64 def_mac; 1414 u8 port_type; 1415 u16 short_field; 1416 int err; 1417 int admin_link_state; 1418 int port = mlx4_slave_convert_port(dev, slave, 1419 vhcr->in_modifier & 0xFF); 1420 1421#define MLX4_VF_PORT_NO_LINK_SENSE_MASK 0xE0 1422#define MLX4_PORT_LINK_UP_MASK 0x80 1423#define QUERY_PORT_CUR_MAX_PKEY_OFFSET 0x0c 1424#define QUERY_PORT_CUR_MAX_GID_OFFSET 0x0e 1425 1426 if (port < 0) 1427 return -EINVAL; 1428 1429 /* Protect against untrusted guests: enforce that this is the 1430 * QUERY_PORT general query. 1431 */ 1432 if (vhcr->op_modifier || vhcr->in_modifier & ~0xFF) 1433 return -EINVAL; 1434 1435 vhcr->in_modifier = port; 1436 1437 err = mlx4_cmd_box(dev, 0, outbox->dma, vhcr->in_modifier, 0, 1438 MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B, 1439 MLX4_CMD_NATIVE); 1440 1441 if (!err && dev->caps.function != slave) { 1442 def_mac = priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.mac; 1443 MLX4_PUT(outbox->buf, def_mac, QUERY_PORT_MAC_OFFSET); 1444 1445 /* get port type - currently only eth is enabled */ 1446 MLX4_GET(port_type, outbox->buf, 1447 QUERY_PORT_SUPPORTED_TYPE_OFFSET); 1448 1449 /* No link sensing allowed */ 1450 port_type &= MLX4_VF_PORT_NO_LINK_SENSE_MASK; 1451 /* set port type to currently operating port type */ 1452 port_type |= (dev->caps.port_type[vhcr->in_modifier] & 0x3); 1453 1454 admin_link_state = priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.link_state; 1455 if (IFLA_VF_LINK_STATE_ENABLE == admin_link_state) 1456 port_type |= MLX4_PORT_LINK_UP_MASK; 1457 else if (IFLA_VF_LINK_STATE_DISABLE == admin_link_state) 1458 port_type &= ~MLX4_PORT_LINK_UP_MASK; 1459 else if (IFLA_VF_LINK_STATE_AUTO == admin_link_state && mlx4_is_bonded(dev)) { 1460 int other_port = (port == 1) ? 2 : 1; 1461 struct mlx4_port_cap port_cap; 1462 1463 err = mlx4_QUERY_PORT(dev, other_port, &port_cap); 1464 if (err) 1465 goto out; 1466 port_type |= (port_cap.link_state << 7); 1467 } 1468 1469 MLX4_PUT(outbox->buf, port_type, 1470 QUERY_PORT_SUPPORTED_TYPE_OFFSET); 1471 1472 if (dev->caps.port_type[vhcr->in_modifier] == MLX4_PORT_TYPE_ETH) 1473 short_field = mlx4_get_slave_num_gids(dev, slave, port); 1474 else 1475 short_field = 1; /* slave max gids */ 1476 MLX4_PUT(outbox->buf, short_field, 1477 QUERY_PORT_CUR_MAX_GID_OFFSET); 1478 1479 short_field = dev->caps.pkey_table_len[vhcr->in_modifier]; 1480 MLX4_PUT(outbox->buf, short_field, 1481 QUERY_PORT_CUR_MAX_PKEY_OFFSET); 1482 } 1483out: 1484 return err; 1485} 1486 1487int mlx4_get_slave_pkey_gid_tbl_len(struct mlx4_dev *dev, u8 port, 1488 int *gid_tbl_len, int *pkey_tbl_len) 1489{ 1490 struct mlx4_cmd_mailbox *mailbox; 1491 u32 *outbox; 1492 u16 field; 1493 int err; 1494 1495 mailbox = mlx4_alloc_cmd_mailbox(dev); 1496 if (IS_ERR(mailbox)) 1497 return PTR_ERR(mailbox); 1498 1499 err = mlx4_cmd_box(dev, 0, mailbox->dma, port, 0, 1500 MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B, 1501 MLX4_CMD_WRAPPED); 1502 if (err) 1503 goto out; 1504 1505 outbox = mailbox->buf; 1506 1507 MLX4_GET(field, outbox, QUERY_PORT_CUR_MAX_GID_OFFSET); 1508 *gid_tbl_len = field; 1509 1510 MLX4_GET(field, outbox, QUERY_PORT_CUR_MAX_PKEY_OFFSET); 1511 *pkey_tbl_len = field; 1512 1513out: 1514 mlx4_free_cmd_mailbox(dev, mailbox); 1515 return err; 1516} 1517EXPORT_SYMBOL(mlx4_get_slave_pkey_gid_tbl_len); 1518 1519int mlx4_map_cmd(struct mlx4_dev *dev, u16 op, struct mlx4_icm *icm, u64 virt) 1520{ 1521 struct mlx4_cmd_mailbox *mailbox; 1522 struct mlx4_icm_iter iter; 1523 __be64 *pages; 1524 int lg; 1525 int nent = 0; 1526 int i; 1527 int err = 0; 1528 int ts = 0, tc = 0; 1529 1530 mailbox = mlx4_alloc_cmd_mailbox(dev); 1531 if (IS_ERR(mailbox)) 1532 return PTR_ERR(mailbox); 1533 pages = mailbox->buf; 1534 1535 for (mlx4_icm_first(icm, &iter); 1536 !mlx4_icm_last(&iter); 1537 mlx4_icm_next(&iter)) { 1538 /* 1539 * We have to pass pages that are aligned to their 1540 * size, so find the least significant 1 in the 1541 * address or size and use that as our log2 size. 1542 */ 1543 lg = ffs(mlx4_icm_addr(&iter) | mlx4_icm_size(&iter)) - 1; 1544 if (lg < MLX4_ICM_PAGE_SHIFT) { 1545 mlx4_warn(dev, "Got FW area not aligned to %d (%llx/%lx)\n", 1546 MLX4_ICM_PAGE_SIZE, 1547 (unsigned long long) mlx4_icm_addr(&iter), 1548 mlx4_icm_size(&iter)); 1549 err = -EINVAL; 1550 goto out; 1551 } 1552 1553 for (i = 0; i < mlx4_icm_size(&iter) >> lg; ++i) { 1554 if (virt != -1) { 1555 pages[nent * 2] = cpu_to_be64(virt); 1556 virt += 1ULL << lg; 1557 } 1558 1559 pages[nent * 2 + 1] = 1560 cpu_to_be64((mlx4_icm_addr(&iter) + (i << lg)) | 1561 (lg - MLX4_ICM_PAGE_SHIFT)); 1562 ts += 1 << (lg - 10); 1563 ++tc; 1564 1565 if (++nent == MLX4_MAILBOX_SIZE / 16) { 1566 err = mlx4_cmd(dev, mailbox->dma, nent, 0, op, 1567 MLX4_CMD_TIME_CLASS_B, 1568 MLX4_CMD_NATIVE); 1569 if (err) 1570 goto out; 1571 nent = 0; 1572 } 1573 } 1574 } 1575 1576 if (nent) 1577 err = mlx4_cmd(dev, mailbox->dma, nent, 0, op, 1578 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 1579 if (err) 1580 goto out; 1581 1582 switch (op) { 1583 case MLX4_CMD_MAP_FA: 1584 mlx4_dbg(dev, "Mapped %d chunks/%d KB for FW\n", tc, ts); 1585 break; 1586 case MLX4_CMD_MAP_ICM_AUX: 1587 mlx4_dbg(dev, "Mapped %d chunks/%d KB for ICM aux\n", tc, ts); 1588 break; 1589 case MLX4_CMD_MAP_ICM: 1590 mlx4_dbg(dev, "Mapped %d chunks/%d KB at %llx for ICM\n", 1591 tc, ts, (unsigned long long) virt - (ts << 10)); 1592 break; 1593 } 1594 1595out: 1596 mlx4_free_cmd_mailbox(dev, mailbox); 1597 return err; 1598} 1599 1600int mlx4_MAP_FA(struct mlx4_dev *dev, struct mlx4_icm *icm) 1601{ 1602 return mlx4_map_cmd(dev, MLX4_CMD_MAP_FA, icm, -1); 1603} 1604 1605int mlx4_UNMAP_FA(struct mlx4_dev *dev) 1606{ 1607 return mlx4_cmd(dev, 0, 0, 0, MLX4_CMD_UNMAP_FA, 1608 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 1609} 1610 1611 1612int mlx4_RUN_FW(struct mlx4_dev *dev) 1613{ 1614 return mlx4_cmd(dev, 0, 0, 0, MLX4_CMD_RUN_FW, 1615 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 1616} 1617 1618int mlx4_QUERY_FW(struct mlx4_dev *dev) 1619{ 1620 struct mlx4_fw *fw = &mlx4_priv(dev)->fw; 1621 struct mlx4_cmd *cmd = &mlx4_priv(dev)->cmd; 1622 struct mlx4_cmd_mailbox *mailbox; 1623 u32 *outbox; 1624 int err = 0; 1625 u64 fw_ver; 1626 u16 cmd_if_rev; 1627 u8 lg; 1628 1629#define QUERY_FW_OUT_SIZE 0x100 1630#define QUERY_FW_VER_OFFSET 0x00 1631#define QUERY_FW_PPF_ID 0x09 1632#define QUERY_FW_CMD_IF_REV_OFFSET 0x0a 1633#define QUERY_FW_MAX_CMD_OFFSET 0x0f 1634#define QUERY_FW_ERR_START_OFFSET 0x30 1635#define QUERY_FW_ERR_SIZE_OFFSET 0x38 1636#define QUERY_FW_ERR_BAR_OFFSET 0x3c 1637 1638#define QUERY_FW_SIZE_OFFSET 0x00 1639#define QUERY_FW_CLR_INT_BASE_OFFSET 0x20 1640#define QUERY_FW_CLR_INT_BAR_OFFSET 0x28 1641 1642#define QUERY_FW_COMM_BASE_OFFSET 0x40 1643#define QUERY_FW_COMM_BAR_OFFSET 0x48 1644 1645#define QUERY_FW_CLOCK_OFFSET 0x50 1646#define QUERY_FW_CLOCK_BAR 0x58 1647 1648 mailbox = mlx4_alloc_cmd_mailbox(dev); 1649 if (IS_ERR(mailbox)) 1650 return PTR_ERR(mailbox); 1651 outbox = mailbox->buf; 1652 1653 err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, MLX4_CMD_QUERY_FW, 1654 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 1655 if (err) 1656 goto out; 1657 1658 MLX4_GET(fw_ver, outbox, QUERY_FW_VER_OFFSET); 1659 /* 1660 * FW subminor version is at more significant bits than minor 1661 * version, so swap here. 1662 */ 1663 dev->caps.fw_ver = (fw_ver & 0xffff00000000ull) | 1664 ((fw_ver & 0xffff0000ull) >> 16) | 1665 ((fw_ver & 0x0000ffffull) << 16); 1666 1667 MLX4_GET(lg, outbox, QUERY_FW_PPF_ID); 1668 dev->caps.function = lg; 1669 1670 if (mlx4_is_slave(dev)) 1671 goto out; 1672 1673 1674 MLX4_GET(cmd_if_rev, outbox, QUERY_FW_CMD_IF_REV_OFFSET); 1675 if (cmd_if_rev < MLX4_COMMAND_INTERFACE_MIN_REV || 1676 cmd_if_rev > MLX4_COMMAND_INTERFACE_MAX_REV) { 1677 mlx4_err(dev, "Installed FW has unsupported command interface revision %d\n", 1678 cmd_if_rev); 1679 mlx4_err(dev, "(Installed FW version is %d.%d.%03d)\n", 1680 (int) (dev->caps.fw_ver >> 32), 1681 (int) (dev->caps.fw_ver >> 16) & 0xffff, 1682 (int) dev->caps.fw_ver & 0xffff); 1683 mlx4_err(dev, "This driver version supports only revisions %d to %d\n", 1684 MLX4_COMMAND_INTERFACE_MIN_REV, MLX4_COMMAND_INTERFACE_MAX_REV); 1685 err = -ENODEV; 1686 goto out; 1687 } 1688 1689 if (cmd_if_rev < MLX4_COMMAND_INTERFACE_NEW_PORT_CMDS) 1690 dev->flags |= MLX4_FLAG_OLD_PORT_CMDS; 1691 1692 MLX4_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET); 1693 cmd->max_cmds = 1 << lg; 1694 1695 mlx4_dbg(dev, "FW version %d.%d.%03d (cmd intf rev %d), max commands %d\n", 1696 (int) (dev->caps.fw_ver >> 32), 1697 (int) (dev->caps.fw_ver >> 16) & 0xffff, 1698 (int) dev->caps.fw_ver & 0xffff, 1699 cmd_if_rev, cmd->max_cmds); 1700 1701 MLX4_GET(fw->catas_offset, outbox, QUERY_FW_ERR_START_OFFSET); 1702 MLX4_GET(fw->catas_size, outbox, QUERY_FW_ERR_SIZE_OFFSET); 1703 MLX4_GET(fw->catas_bar, outbox, QUERY_FW_ERR_BAR_OFFSET); 1704 fw->catas_bar = (fw->catas_bar >> 6) * 2; 1705 1706 mlx4_dbg(dev, "Catastrophic error buffer at 0x%llx, size 0x%x, BAR %d\n", 1707 (unsigned long long) fw->catas_offset, fw->catas_size, fw->catas_bar); 1708 1709 MLX4_GET(fw->fw_pages, outbox, QUERY_FW_SIZE_OFFSET); 1710 MLX4_GET(fw->clr_int_base, outbox, QUERY_FW_CLR_INT_BASE_OFFSET); 1711 MLX4_GET(fw->clr_int_bar, outbox, QUERY_FW_CLR_INT_BAR_OFFSET); 1712 fw->clr_int_bar = (fw->clr_int_bar >> 6) * 2; 1713 1714 MLX4_GET(fw->comm_base, outbox, QUERY_FW_COMM_BASE_OFFSET); 1715 MLX4_GET(fw->comm_bar, outbox, QUERY_FW_COMM_BAR_OFFSET); 1716 fw->comm_bar = (fw->comm_bar >> 6) * 2; 1717 mlx4_dbg(dev, "Communication vector bar:%d offset:0x%llx\n", 1718 fw->comm_bar, fw->comm_base); 1719 mlx4_dbg(dev, "FW size %d KB\n", fw->fw_pages >> 2); 1720 1721 MLX4_GET(fw->clock_offset, outbox, QUERY_FW_CLOCK_OFFSET); 1722 MLX4_GET(fw->clock_bar, outbox, QUERY_FW_CLOCK_BAR); 1723 fw->clock_bar = (fw->clock_bar >> 6) * 2; 1724 mlx4_dbg(dev, "Internal clock bar:%d offset:0x%llx\n", 1725 fw->clock_bar, fw->clock_offset); 1726 1727 /* 1728 * Round up number of system pages needed in case 1729 * MLX4_ICM_PAGE_SIZE < PAGE_SIZE. 1730 */ 1731 fw->fw_pages = 1732 ALIGN(fw->fw_pages, PAGE_SIZE / MLX4_ICM_PAGE_SIZE) >> 1733 (PAGE_SHIFT - MLX4_ICM_PAGE_SHIFT); 1734 1735 mlx4_dbg(dev, "Clear int @ %llx, BAR %d\n", 1736 (unsigned long long) fw->clr_int_base, fw->clr_int_bar); 1737 1738out: 1739 mlx4_free_cmd_mailbox(dev, mailbox); 1740 return err; 1741} 1742 1743int mlx4_QUERY_FW_wrapper(struct mlx4_dev *dev, int slave, 1744 struct mlx4_vhcr *vhcr, 1745 struct mlx4_cmd_mailbox *inbox, 1746 struct mlx4_cmd_mailbox *outbox, 1747 struct mlx4_cmd_info *cmd) 1748{ 1749 u8 *outbuf; 1750 int err; 1751 1752 outbuf = outbox->buf; 1753 err = mlx4_cmd_box(dev, 0, outbox->dma, 0, 0, MLX4_CMD_QUERY_FW, 1754 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 1755 if (err) 1756 return err; 1757 1758 /* for slaves, set pci PPF ID to invalid and zero out everything 1759 * else except FW version */ 1760 outbuf[0] = outbuf[1] = 0; 1761 memset(&outbuf[8], 0, QUERY_FW_OUT_SIZE - 8); 1762 outbuf[QUERY_FW_PPF_ID] = MLX4_INVALID_SLAVE_ID; 1763 1764 return 0; 1765} 1766 1767static void get_board_id(void *vsd, char *board_id) 1768{ 1769 int i; 1770 1771#define VSD_OFFSET_SIG1 0x00 1772#define VSD_OFFSET_SIG2 0xde 1773#define VSD_OFFSET_MLX_BOARD_ID 0xd0 1774#define VSD_OFFSET_TS_BOARD_ID 0x20 1775 1776#define VSD_SIGNATURE_TOPSPIN 0x5ad 1777 1778 memset(board_id, 0, MLX4_BOARD_ID_LEN); 1779 1780 if (be16_to_cpup(vsd + VSD_OFFSET_SIG1) == VSD_SIGNATURE_TOPSPIN && 1781 be16_to_cpup(vsd + VSD_OFFSET_SIG2) == VSD_SIGNATURE_TOPSPIN) { 1782 strlcpy(board_id, vsd + VSD_OFFSET_TS_BOARD_ID, MLX4_BOARD_ID_LEN); 1783 } else { 1784 /* 1785 * The board ID is a string but the firmware byte 1786 * swaps each 4-byte word before passing it back to 1787 * us. Therefore we need to swab it before printing. 1788 */ 1789 u32 *bid_u32 = (u32 *)board_id; 1790 1791 for (i = 0; i < 4; ++i) { 1792 u32 *addr; 1793 u32 val; 1794 1795 addr = (u32 *) (vsd + VSD_OFFSET_MLX_BOARD_ID + i * 4); 1796 val = get_unaligned(addr); 1797 val = swab32(val); 1798 put_unaligned(val, &bid_u32[i]); 1799 } 1800 } 1801} 1802 1803int mlx4_QUERY_ADAPTER(struct mlx4_dev *dev, struct mlx4_adapter *adapter) 1804{ 1805 struct mlx4_cmd_mailbox *mailbox; 1806 u32 *outbox; 1807 int err; 1808 1809#define QUERY_ADAPTER_OUT_SIZE 0x100 1810#define QUERY_ADAPTER_INTA_PIN_OFFSET 0x10 1811#define QUERY_ADAPTER_VSD_OFFSET 0x20 1812 1813 mailbox = mlx4_alloc_cmd_mailbox(dev); 1814 if (IS_ERR(mailbox)) 1815 return PTR_ERR(mailbox); 1816 outbox = mailbox->buf; 1817 1818 err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, MLX4_CMD_QUERY_ADAPTER, 1819 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 1820 if (err) 1821 goto out; 1822 1823 MLX4_GET(adapter->inta_pin, outbox, QUERY_ADAPTER_INTA_PIN_OFFSET); 1824 1825 get_board_id(outbox + QUERY_ADAPTER_VSD_OFFSET / 4, 1826 adapter->board_id); 1827 1828out: 1829 mlx4_free_cmd_mailbox(dev, mailbox); 1830 return err; 1831} 1832 1833int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) 1834{ 1835 struct mlx4_cmd_mailbox *mailbox; 1836 __be32 *inbox; 1837 int err; 1838 static const u8 a0_dmfs_hw_steering[] = { 1839 [MLX4_STEERING_DMFS_A0_DEFAULT] = 0, 1840 [MLX4_STEERING_DMFS_A0_DYNAMIC] = 1, 1841 [MLX4_STEERING_DMFS_A0_STATIC] = 2, 1842 [MLX4_STEERING_DMFS_A0_DISABLE] = 3 1843 }; 1844 1845#define INIT_HCA_IN_SIZE 0x200 1846#define INIT_HCA_VERSION_OFFSET 0x000 1847#define INIT_HCA_VERSION 2 1848#define INIT_HCA_VXLAN_OFFSET 0x0c 1849#define INIT_HCA_CACHELINE_SZ_OFFSET 0x0e 1850#define INIT_HCA_FLAGS_OFFSET 0x014 1851#define INIT_HCA_RECOVERABLE_ERROR_EVENT_OFFSET 0x018 1852#define INIT_HCA_QPC_OFFSET 0x020 1853#define INIT_HCA_QPC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x10) 1854#define INIT_HCA_LOG_QP_OFFSET (INIT_HCA_QPC_OFFSET + 0x17) 1855#define INIT_HCA_SRQC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x28) 1856#define INIT_HCA_LOG_SRQ_OFFSET (INIT_HCA_QPC_OFFSET + 0x2f) 1857#define INIT_HCA_CQC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x30) 1858#define INIT_HCA_LOG_CQ_OFFSET (INIT_HCA_QPC_OFFSET + 0x37) 1859#define INIT_HCA_EQE_CQE_OFFSETS (INIT_HCA_QPC_OFFSET + 0x38) 1860#define INIT_HCA_EQE_CQE_STRIDE_OFFSET (INIT_HCA_QPC_OFFSET + 0x3b) 1861#define INIT_HCA_ALTC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x40) 1862#define INIT_HCA_AUXC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x50) 1863#define INIT_HCA_EQC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x60) 1864#define INIT_HCA_LOG_EQ_OFFSET (INIT_HCA_QPC_OFFSET + 0x67) 1865#define INIT_HCA_NUM_SYS_EQS_OFFSET (INIT_HCA_QPC_OFFSET + 0x6a) 1866#define INIT_HCA_RDMARC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x70) 1867#define INIT_HCA_LOG_RD_OFFSET (INIT_HCA_QPC_OFFSET + 0x77) 1868#define INIT_HCA_MCAST_OFFSET 0x0c0 1869#define INIT_HCA_MC_BASE_OFFSET (INIT_HCA_MCAST_OFFSET + 0x00) 1870#define INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x13) 1871#define INIT_HCA_LOG_MC_HASH_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x17) 1872#define INIT_HCA_UC_STEERING_OFFSET (INIT_HCA_MCAST_OFFSET + 0x18) 1873#define INIT_HCA_LOG_MC_TABLE_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x1b) 1874#define INIT_HCA_DEVICE_MANAGED_FLOW_STEERING_EN 0x6 1875#define INIT_HCA_DRIVER_VERSION_OFFSET 0x140 1876#define INIT_HCA_DRIVER_VERSION_SZ 0x40 1877#define INIT_HCA_FS_PARAM_OFFSET 0x1d0 1878#define INIT_HCA_FS_BASE_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x00) 1879#define INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x13) 1880#define INIT_HCA_FS_A0_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x18) 1881#define INIT_HCA_FS_LOG_TABLE_SZ_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x1b) 1882#define INIT_HCA_FS_ETH_BITS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x21) 1883#define INIT_HCA_FS_ETH_NUM_ADDRS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x22) 1884#define INIT_HCA_FS_IB_BITS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x25) 1885#define INIT_HCA_FS_IB_NUM_ADDRS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x26) 1886#define INIT_HCA_TPT_OFFSET 0x0f0 1887#define INIT_HCA_DMPT_BASE_OFFSET (INIT_HCA_TPT_OFFSET + 0x00) 1888#define INIT_HCA_TPT_MW_OFFSET (INIT_HCA_TPT_OFFSET + 0x08) 1889#define INIT_HCA_LOG_MPT_SZ_OFFSET (INIT_HCA_TPT_OFFSET + 0x0b) 1890#define INIT_HCA_MTT_BASE_OFFSET (INIT_HCA_TPT_OFFSET + 0x10) 1891#define INIT_HCA_CMPT_BASE_OFFSET (INIT_HCA_TPT_OFFSET + 0x18) 1892#define INIT_HCA_UAR_OFFSET 0x120 1893#define INIT_HCA_LOG_UAR_SZ_OFFSET (INIT_HCA_UAR_OFFSET + 0x0a) 1894#define INIT_HCA_UAR_PAGE_SZ_OFFSET (INIT_HCA_UAR_OFFSET + 0x0b) 1895 1896 mailbox = mlx4_alloc_cmd_mailbox(dev); 1897 if (IS_ERR(mailbox)) 1898 return PTR_ERR(mailbox); 1899 inbox = mailbox->buf; 1900 1901 *((u8 *) mailbox->buf + INIT_HCA_VERSION_OFFSET) = INIT_HCA_VERSION; 1902 1903 *((u8 *) mailbox->buf + INIT_HCA_CACHELINE_SZ_OFFSET) = 1904 ((ilog2(cache_line_size()) - 4) << 5) | (1 << 4); 1905 1906#if defined(__LITTLE_ENDIAN) 1907 *(inbox + INIT_HCA_FLAGS_OFFSET / 4) &= ~cpu_to_be32(1 << 1); 1908#elif defined(__BIG_ENDIAN) 1909 *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 1); 1910#else 1911#error Host endianness not defined 1912#endif 1913 /* Check port for UD address vector: */ 1914 *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1); 1915 1916 /* Enable IPoIB checksumming if we can: */ 1917 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_IPOIB_CSUM) 1918 *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 3); 1919 1920 /* Enable QoS support if module parameter set */ 1921 if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ETS_CFG && enable_qos) 1922 *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 2); 1923 1924 /* enable counters */ 1925 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS) 1926 *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 4); 1927 1928 /* Enable RSS spread to fragmented IP packets when supported */ 1929 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_RSS_IP_FRAG) 1930 *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 13); 1931 1932 /* CX3 is capable of extending CQEs/EQEs from 32 to 64 bytes */ 1933 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_64B_EQE) { 1934 *(inbox + INIT_HCA_EQE_CQE_OFFSETS / 4) |= cpu_to_be32(1 << 29); 1935 dev->caps.eqe_size = 64; 1936 dev->caps.eqe_factor = 1; 1937 } else { 1938 dev->caps.eqe_size = 32; 1939 dev->caps.eqe_factor = 0; 1940 } 1941 1942 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_64B_CQE) { 1943 *(inbox + INIT_HCA_EQE_CQE_OFFSETS / 4) |= cpu_to_be32(1 << 30); 1944 dev->caps.cqe_size = 64; 1945 dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_LARGE_CQE; 1946 } else { 1947 dev->caps.cqe_size = 32; 1948 } 1949 1950 /* CX3 is capable of extending CQEs\EQEs to strides larger than 64B */ 1951 if ((dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_EQE_STRIDE) && 1952 (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_CQE_STRIDE)) { 1953 dev->caps.eqe_size = cache_line_size(); 1954 dev->caps.cqe_size = cache_line_size(); 1955 dev->caps.eqe_factor = 0; 1956 MLX4_PUT(inbox, (u8)((ilog2(dev->caps.eqe_size) - 5) << 4 | 1957 (ilog2(dev->caps.eqe_size) - 5)), 1958 INIT_HCA_EQE_CQE_STRIDE_OFFSET); 1959 1960 /* User still need to know to support CQE > 32B */ 1961 dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_LARGE_CQE; 1962 } 1963 1964 if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RECOVERABLE_ERROR_EVENT) 1965 *(inbox + INIT_HCA_RECOVERABLE_ERROR_EVENT_OFFSET / 4) |= cpu_to_be32(1 << 31); 1966 1967 if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_DRIVER_VERSION_TO_FW) { 1968 u8 *dst = (u8 *)(inbox + INIT_HCA_DRIVER_VERSION_OFFSET / 4); 1969 1970 strncpy(dst, DRV_NAME_FOR_FW, INIT_HCA_DRIVER_VERSION_SZ - 1); 1971 mlx4_dbg(dev, "Reporting Driver Version to FW: %s\n", dst); 1972 } 1973 1974 /* QPC/EEC/CQC/EQC/RDMARC attributes */ 1975 1976 MLX4_PUT(inbox, param->qpc_base, INIT_HCA_QPC_BASE_OFFSET); 1977 MLX4_PUT(inbox, param->log_num_qps, INIT_HCA_LOG_QP_OFFSET); 1978 MLX4_PUT(inbox, param->srqc_base, INIT_HCA_SRQC_BASE_OFFSET); 1979 MLX4_PUT(inbox, param->log_num_srqs, INIT_HCA_LOG_SRQ_OFFSET); 1980 MLX4_PUT(inbox, param->cqc_base, INIT_HCA_CQC_BASE_OFFSET); 1981 MLX4_PUT(inbox, param->log_num_cqs, INIT_HCA_LOG_CQ_OFFSET); 1982 MLX4_PUT(inbox, param->altc_base, INIT_HCA_ALTC_BASE_OFFSET); 1983 MLX4_PUT(inbox, param->auxc_base, INIT_HCA_AUXC_BASE_OFFSET); 1984 MLX4_PUT(inbox, param->eqc_base, INIT_HCA_EQC_BASE_OFFSET); 1985 MLX4_PUT(inbox, param->log_num_eqs, INIT_HCA_LOG_EQ_OFFSET); 1986 MLX4_PUT(inbox, param->num_sys_eqs, INIT_HCA_NUM_SYS_EQS_OFFSET); 1987 MLX4_PUT(inbox, param->rdmarc_base, INIT_HCA_RDMARC_BASE_OFFSET); 1988 MLX4_PUT(inbox, param->log_rd_per_qp, INIT_HCA_LOG_RD_OFFSET); 1989 1990 /* steering attributes */ 1991 if (dev->caps.steering_mode == 1992 MLX4_STEERING_MODE_DEVICE_MANAGED) { 1993 *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= 1994 cpu_to_be32(1 << 1995 INIT_HCA_DEVICE_MANAGED_FLOW_STEERING_EN); 1996 1997 MLX4_PUT(inbox, param->mc_base, INIT_HCA_FS_BASE_OFFSET); 1998 MLX4_PUT(inbox, param->log_mc_entry_sz, 1999 INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); 2000 MLX4_PUT(inbox, param->log_mc_table_sz, 2001 INIT_HCA_FS_LOG_TABLE_SZ_OFFSET); 2002 /* Enable Ethernet flow steering 2003 * with udp unicast and tcp unicast 2004 */ 2005 if (dev->caps.dmfs_high_steer_mode != 2006 MLX4_STEERING_DMFS_A0_STATIC) 2007 MLX4_PUT(inbox, 2008 (u8)(MLX4_FS_UDP_UC_EN | MLX4_FS_TCP_UC_EN), 2009 INIT_HCA_FS_ETH_BITS_OFFSET); 2010 MLX4_PUT(inbox, (u16) MLX4_FS_NUM_OF_L2_ADDR, 2011 INIT_HCA_FS_ETH_NUM_ADDRS_OFFSET); 2012 /* Enable IPoIB flow steering 2013 * with udp unicast and tcp unicast 2014 */ 2015 MLX4_PUT(inbox, (u8) (MLX4_FS_UDP_UC_EN | MLX4_FS_TCP_UC_EN), 2016 INIT_HCA_FS_IB_BITS_OFFSET); 2017 MLX4_PUT(inbox, (u16) MLX4_FS_NUM_OF_L2_ADDR, 2018 INIT_HCA_FS_IB_NUM_ADDRS_OFFSET); 2019 2020 if (dev->caps.dmfs_high_steer_mode != 2021 MLX4_STEERING_DMFS_A0_NOT_SUPPORTED) 2022 MLX4_PUT(inbox, 2023 ((u8)(a0_dmfs_hw_steering[dev->caps.dmfs_high_steer_mode] 2024 << 6)), 2025 INIT_HCA_FS_A0_OFFSET); 2026 } else { 2027 MLX4_PUT(inbox, param->mc_base, INIT_HCA_MC_BASE_OFFSET); 2028 MLX4_PUT(inbox, param->log_mc_entry_sz, 2029 INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); 2030 MLX4_PUT(inbox, param->log_mc_hash_sz, 2031 INIT_HCA_LOG_MC_HASH_SZ_OFFSET); 2032 MLX4_PUT(inbox, param->log_mc_table_sz, 2033 INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); 2034 if (dev->caps.steering_mode == MLX4_STEERING_MODE_B0) 2035 MLX4_PUT(inbox, (u8) (1 << 3), 2036 INIT_HCA_UC_STEERING_OFFSET); 2037 } 2038 2039 /* TPT attributes */ 2040 2041 MLX4_PUT(inbox, param->dmpt_base, INIT_HCA_DMPT_BASE_OFFSET); 2042 MLX4_PUT(inbox, param->mw_enabled, INIT_HCA_TPT_MW_OFFSET); 2043 MLX4_PUT(inbox, param->log_mpt_sz, INIT_HCA_LOG_MPT_SZ_OFFSET); 2044 MLX4_PUT(inbox, param->mtt_base, INIT_HCA_MTT_BASE_OFFSET); 2045 MLX4_PUT(inbox, param->cmpt_base, INIT_HCA_CMPT_BASE_OFFSET); 2046 2047 /* UAR attributes */ 2048 2049 MLX4_PUT(inbox, param->uar_page_sz, INIT_HCA_UAR_PAGE_SZ_OFFSET); 2050 MLX4_PUT(inbox, param->log_uar_sz, INIT_HCA_LOG_UAR_SZ_OFFSET); 2051 2052 /* set parser VXLAN attributes */ 2053 if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS) { 2054 u8 parser_params = 0; 2055 MLX4_PUT(inbox, parser_params, INIT_HCA_VXLAN_OFFSET); 2056 } 2057 2058 err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_INIT_HCA, 2059 MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE); 2060 2061 if (err) 2062 mlx4_err(dev, "INIT_HCA returns %d\n", err); 2063 2064 mlx4_free_cmd_mailbox(dev, mailbox); 2065 return err; 2066} 2067 2068int mlx4_QUERY_HCA(struct mlx4_dev *dev, 2069 struct mlx4_init_hca_param *param) 2070{ 2071 struct mlx4_cmd_mailbox *mailbox; 2072 __be32 *outbox; 2073 u64 qword_field; 2074 u32 dword_field; 2075 u16 word_field; 2076 u8 byte_field; 2077 int err; 2078 static const u8 a0_dmfs_query_hw_steering[] = { 2079 [0] = MLX4_STEERING_DMFS_A0_DEFAULT, 2080 [1] = MLX4_STEERING_DMFS_A0_DYNAMIC, 2081 [2] = MLX4_STEERING_DMFS_A0_STATIC, 2082 [3] = MLX4_STEERING_DMFS_A0_DISABLE 2083 }; 2084 2085#define QUERY_HCA_GLOBAL_CAPS_OFFSET 0x04 2086#define QUERY_HCA_CORE_CLOCK_OFFSET 0x0c 2087 2088 mailbox = mlx4_alloc_cmd_mailbox(dev); 2089 if (IS_ERR(mailbox)) 2090 return PTR_ERR(mailbox); 2091 outbox = mailbox->buf; 2092 2093 err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, 2094 MLX4_CMD_QUERY_HCA, 2095 MLX4_CMD_TIME_CLASS_B, 2096 !mlx4_is_slave(dev)); 2097 if (err) 2098 goto out; 2099 2100 MLX4_GET(param->global_caps, outbox, QUERY_HCA_GLOBAL_CAPS_OFFSET); 2101 MLX4_GET(param->hca_core_clock, outbox, QUERY_HCA_CORE_CLOCK_OFFSET); 2102 2103 /* QPC/EEC/CQC/EQC/RDMARC attributes */ 2104 2105 MLX4_GET(qword_field, outbox, INIT_HCA_QPC_BASE_OFFSET); 2106 param->qpc_base = qword_field & ~((u64)0x1f); 2107 MLX4_GET(byte_field, outbox, INIT_HCA_LOG_QP_OFFSET); 2108 param->log_num_qps = byte_field & 0x1f; 2109 MLX4_GET(qword_field, outbox, INIT_HCA_SRQC_BASE_OFFSET); 2110 param->srqc_base = qword_field & ~((u64)0x1f); 2111 MLX4_GET(byte_field, outbox, INIT_HCA_LOG_SRQ_OFFSET); 2112 param->log_num_srqs = byte_field & 0x1f; 2113 MLX4_GET(qword_field, outbox, INIT_HCA_CQC_BASE_OFFSET); 2114 param->cqc_base = qword_field & ~((u64)0x1f); 2115 MLX4_GET(byte_field, outbox, INIT_HCA_LOG_CQ_OFFSET); 2116 param->log_num_cqs = byte_field & 0x1f; 2117 MLX4_GET(qword_field, outbox, INIT_HCA_ALTC_BASE_OFFSET); 2118 param->altc_base = qword_field; 2119 MLX4_GET(qword_field, outbox, INIT_HCA_AUXC_BASE_OFFSET); 2120 param->auxc_base = qword_field; 2121 MLX4_GET(qword_field, outbox, INIT_HCA_EQC_BASE_OFFSET); 2122 param->eqc_base = qword_field & ~((u64)0x1f); 2123 MLX4_GET(byte_field, outbox, INIT_HCA_LOG_EQ_OFFSET); 2124 param->log_num_eqs = byte_field & 0x1f; 2125 MLX4_GET(word_field, outbox, INIT_HCA_NUM_SYS_EQS_OFFSET); 2126 param->num_sys_eqs = word_field & 0xfff; 2127 MLX4_GET(qword_field, outbox, INIT_HCA_RDMARC_BASE_OFFSET); 2128 param->rdmarc_base = qword_field & ~((u64)0x1f); 2129 MLX4_GET(byte_field, outbox, INIT_HCA_LOG_RD_OFFSET); 2130 param->log_rd_per_qp = byte_field & 0x7; 2131 2132 MLX4_GET(dword_field, outbox, INIT_HCA_FLAGS_OFFSET); 2133 if (dword_field & (1 << INIT_HCA_DEVICE_MANAGED_FLOW_STEERING_EN)) { 2134 param->steering_mode = MLX4_STEERING_MODE_DEVICE_MANAGED; 2135 } else { 2136 MLX4_GET(byte_field, outbox, INIT_HCA_UC_STEERING_OFFSET); 2137 if (byte_field & 0x8) 2138 param->steering_mode = MLX4_STEERING_MODE_B0; 2139 else 2140 param->steering_mode = MLX4_STEERING_MODE_A0; 2141 } 2142 2143 if (dword_field & (1 << 13)) 2144 param->rss_ip_frags = 1; 2145 2146 /* steering attributes */ 2147 if (param->steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) { 2148 MLX4_GET(param->mc_base, outbox, INIT_HCA_FS_BASE_OFFSET); 2149 MLX4_GET(byte_field, outbox, INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); 2150 param->log_mc_entry_sz = byte_field & 0x1f; 2151 MLX4_GET(byte_field, outbox, INIT_HCA_FS_LOG_TABLE_SZ_OFFSET); 2152 param->log_mc_table_sz = byte_field & 0x1f; 2153 MLX4_GET(byte_field, outbox, INIT_HCA_FS_A0_OFFSET); 2154 param->dmfs_high_steer_mode = 2155 a0_dmfs_query_hw_steering[(byte_field >> 6) & 3]; 2156 } else { 2157 MLX4_GET(param->mc_base, outbox, INIT_HCA_MC_BASE_OFFSET); 2158 MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); 2159 param->log_mc_entry_sz = byte_field & 0x1f; 2160 MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MC_HASH_SZ_OFFSET); 2161 param->log_mc_hash_sz = byte_field & 0x1f; 2162 MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); 2163 param->log_mc_table_sz = byte_field & 0x1f; 2164 } 2165 2166 /* CX3 is capable of extending CQEs/EQEs from 32 to 64 bytes */ 2167 MLX4_GET(byte_field, outbox, INIT_HCA_EQE_CQE_OFFSETS); 2168 if (byte_field & 0x20) /* 64-bytes eqe enabled */ 2169 param->dev_cap_enabled |= MLX4_DEV_CAP_64B_EQE_ENABLED; 2170 if (byte_field & 0x40) /* 64-bytes cqe enabled */ 2171 param->dev_cap_enabled |= MLX4_DEV_CAP_64B_CQE_ENABLED; 2172 2173 /* CX3 is capable of extending CQEs\EQEs to strides larger than 64B */ 2174 MLX4_GET(byte_field, outbox, INIT_HCA_EQE_CQE_STRIDE_OFFSET); 2175 if (byte_field) { 2176 param->dev_cap_enabled |= MLX4_DEV_CAP_EQE_STRIDE_ENABLED; 2177 param->dev_cap_enabled |= MLX4_DEV_CAP_CQE_STRIDE_ENABLED; 2178 param->cqe_size = 1 << ((byte_field & 2179 MLX4_CQE_SIZE_MASK_STRIDE) + 5); 2180 param->eqe_size = 1 << (((byte_field & 2181 MLX4_EQE_SIZE_MASK_STRIDE) >> 4) + 5); 2182 } 2183 2184 /* TPT attributes */ 2185 2186 MLX4_GET(param->dmpt_base, outbox, INIT_HCA_DMPT_BASE_OFFSET); 2187 MLX4_GET(byte_field, outbox, INIT_HCA_TPT_MW_OFFSET); 2188 param->mw_enabled = byte_field >> 7; 2189 MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MPT_SZ_OFFSET); 2190 param->log_mpt_sz = byte_field & 0x3f; 2191 MLX4_GET(param->mtt_base, outbox, INIT_HCA_MTT_BASE_OFFSET); 2192 MLX4_GET(param->cmpt_base, outbox, INIT_HCA_CMPT_BASE_OFFSET); 2193 2194 /* UAR attributes */ 2195 2196 MLX4_GET(param->uar_page_sz, outbox, INIT_HCA_UAR_PAGE_SZ_OFFSET); 2197 MLX4_GET(byte_field, outbox, INIT_HCA_LOG_UAR_SZ_OFFSET); 2198 param->log_uar_sz = byte_field & 0xf; 2199 2200 /* phv_check enable */ 2201 MLX4_GET(byte_field, outbox, INIT_HCA_CACHELINE_SZ_OFFSET); 2202 if (byte_field & 0x2) 2203 param->phv_check_en = 1; 2204out: 2205 mlx4_free_cmd_mailbox(dev, mailbox); 2206 2207 return err; 2208} 2209 2210static int mlx4_hca_core_clock_update(struct mlx4_dev *dev) 2211{ 2212 struct mlx4_cmd_mailbox *mailbox; 2213 __be32 *outbox; 2214 int err; 2215 2216 mailbox = mlx4_alloc_cmd_mailbox(dev); 2217 if (IS_ERR(mailbox)) { 2218 mlx4_warn(dev, "hca_core_clock mailbox allocation failed\n"); 2219 return PTR_ERR(mailbox); 2220 } 2221 outbox = mailbox->buf; 2222 2223 err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, 2224 MLX4_CMD_QUERY_HCA, 2225 MLX4_CMD_TIME_CLASS_B, 2226 !mlx4_is_slave(dev)); 2227 if (err) { 2228 mlx4_warn(dev, "hca_core_clock update failed\n"); 2229 goto out; 2230 } 2231 2232 MLX4_GET(dev->caps.hca_core_clock, outbox, QUERY_HCA_CORE_CLOCK_OFFSET); 2233 2234out: 2235 mlx4_free_cmd_mailbox(dev, mailbox); 2236 2237 return err; 2238} 2239 2240/* for IB-type ports only in SRIOV mode. Checks that both proxy QP0 2241 * and real QP0 are active, so that the paravirtualized QP0 is ready 2242 * to operate */ 2243static int check_qp0_state(struct mlx4_dev *dev, int function, int port) 2244{ 2245 struct mlx4_priv *priv = mlx4_priv(dev); 2246 /* irrelevant if not infiniband */ 2247 if (priv->mfunc.master.qp0_state[port].proxy_qp0_active && 2248 priv->mfunc.master.qp0_state[port].qp0_active) 2249 return 1; 2250 return 0; 2251} 2252 2253int mlx4_INIT_PORT_wrapper(struct mlx4_dev *dev, int slave, 2254 struct mlx4_vhcr *vhcr, 2255 struct mlx4_cmd_mailbox *inbox, 2256 struct mlx4_cmd_mailbox *outbox, 2257 struct mlx4_cmd_info *cmd) 2258{ 2259 struct mlx4_priv *priv = mlx4_priv(dev); 2260 int port = mlx4_slave_convert_port(dev, slave, vhcr->in_modifier); 2261 int err; 2262 2263 if (port < 0) 2264 return -EINVAL; 2265 2266 if (priv->mfunc.master.slave_state[slave].init_port_mask & (1 << port)) 2267 return 0; 2268 2269 if (dev->caps.port_mask[port] != MLX4_PORT_TYPE_IB) { 2270 /* Enable port only if it was previously disabled */ 2271 if (!priv->mfunc.master.init_port_ref[port]) { 2272 err = mlx4_cmd(dev, 0, port, 0, MLX4_CMD_INIT_PORT, 2273 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 2274 if (err) 2275 return err; 2276 } 2277 priv->mfunc.master.slave_state[slave].init_port_mask |= (1 << port); 2278 } else { 2279 if (slave == mlx4_master_func_num(dev)) { 2280 if (check_qp0_state(dev, slave, port) && 2281 !priv->mfunc.master.qp0_state[port].port_active) { 2282 err = mlx4_cmd(dev, 0, port, 0, MLX4_CMD_INIT_PORT, 2283 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 2284 if (err) 2285 return err; 2286 priv->mfunc.master.qp0_state[port].port_active = 1; 2287 priv->mfunc.master.slave_state[slave].init_port_mask |= (1 << port); 2288 } 2289 } else 2290 priv->mfunc.master.slave_state[slave].init_port_mask |= (1 << port); 2291 } 2292 ++priv->mfunc.master.init_port_ref[port]; 2293 return 0; 2294} 2295 2296int mlx4_INIT_PORT(struct mlx4_dev *dev, int port) 2297{ 2298 struct mlx4_cmd_mailbox *mailbox; 2299 u32 *inbox; 2300 int err; 2301 u32 flags; 2302 u16 field; 2303 2304 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { 2305#define INIT_PORT_IN_SIZE 256 2306#define INIT_PORT_FLAGS_OFFSET 0x00 2307#define INIT_PORT_FLAG_SIG (1 << 18) 2308#define INIT_PORT_FLAG_NG (1 << 17) 2309#define INIT_PORT_FLAG_G0 (1 << 16) 2310#define INIT_PORT_VL_SHIFT 4 2311#define INIT_PORT_PORT_WIDTH_SHIFT 8 2312#define INIT_PORT_MTU_OFFSET 0x04 2313#define INIT_PORT_MAX_GID_OFFSET 0x06 2314#define INIT_PORT_MAX_PKEY_OFFSET 0x0a 2315#define INIT_PORT_GUID0_OFFSET 0x10 2316#define INIT_PORT_NODE_GUID_OFFSET 0x18 2317#define INIT_PORT_SI_GUID_OFFSET 0x20 2318 2319 mailbox = mlx4_alloc_cmd_mailbox(dev); 2320 if (IS_ERR(mailbox)) 2321 return PTR_ERR(mailbox); 2322 inbox = mailbox->buf; 2323 2324 flags = 0; 2325 flags |= (dev->caps.vl_cap[port] & 0xf) << INIT_PORT_VL_SHIFT; 2326 flags |= (dev->caps.port_width_cap[port] & 0xf) << INIT_PORT_PORT_WIDTH_SHIFT; 2327 MLX4_PUT(inbox, flags, INIT_PORT_FLAGS_OFFSET); 2328 2329 field = 128 << dev->caps.ib_mtu_cap[port]; 2330 MLX4_PUT(inbox, field, INIT_PORT_MTU_OFFSET); 2331 field = dev->caps.gid_table_len[port]; 2332 MLX4_PUT(inbox, field, INIT_PORT_MAX_GID_OFFSET); 2333 field = dev->caps.pkey_table_len[port]; 2334 MLX4_PUT(inbox, field, INIT_PORT_MAX_PKEY_OFFSET); 2335 2336 err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_INIT_PORT, 2337 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 2338 2339 mlx4_free_cmd_mailbox(dev, mailbox); 2340 } else 2341 err = mlx4_cmd(dev, 0, port, 0, MLX4_CMD_INIT_PORT, 2342 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); 2343 2344 if (!err) 2345 mlx4_hca_core_clock_update(dev); 2346 2347 return err; 2348} 2349EXPORT_SYMBOL_GPL(mlx4_INIT_PORT); 2350 2351int mlx4_CLOSE_PORT_wrapper(struct mlx4_dev *dev, int slave, 2352 struct mlx4_vhcr *vhcr, 2353 struct mlx4_cmd_mailbox *inbox, 2354 struct mlx4_cmd_mailbox *outbox, 2355 struct mlx4_cmd_info *cmd) 2356{ 2357 struct mlx4_priv *priv = mlx4_priv(dev); 2358 int port = mlx4_slave_convert_port(dev, slave, vhcr->in_modifier); 2359 int err; 2360 2361 if (port < 0) 2362 return -EINVAL; 2363 2364 if (!(priv->mfunc.master.slave_state[slave].init_port_mask & 2365 (1 << port))) 2366 return 0; 2367 2368 if (dev->caps.port_mask[port] != MLX4_PORT_TYPE_IB) { 2369 if (priv->mfunc.master.init_port_ref[port] == 1) { 2370 err = mlx4_cmd(dev, 0, port, 0, MLX4_CMD_CLOSE_PORT, 2371 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 2372 if (err) 2373 return err; 2374 } 2375 priv->mfunc.master.slave_state[slave].init_port_mask &= ~(1 << port); 2376 } else { 2377 /* infiniband port */ 2378 if (slave == mlx4_master_func_num(dev)) { 2379 if (!priv->mfunc.master.qp0_state[port].qp0_active && 2380 priv->mfunc.master.qp0_state[port].port_active) { 2381 err = mlx4_cmd(dev, 0, port, 0, MLX4_CMD_CLOSE_PORT, 2382 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 2383 if (err) 2384 return err; 2385 priv->mfunc.master.slave_state[slave].init_port_mask &= ~(1 << port); 2386 priv->mfunc.master.qp0_state[port].port_active = 0; 2387 } 2388 } else 2389 priv->mfunc.master.slave_state[slave].init_port_mask &= ~(1 << port); 2390 } 2391 --priv->mfunc.master.init_port_ref[port]; 2392 return 0; 2393} 2394 2395int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port) 2396{ 2397 return mlx4_cmd(dev, 0, port, 0, MLX4_CMD_CLOSE_PORT, 2398 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); 2399} 2400EXPORT_SYMBOL_GPL(mlx4_CLOSE_PORT); 2401 2402int mlx4_CLOSE_HCA(struct mlx4_dev *dev, int panic) 2403{ 2404 return mlx4_cmd(dev, 0, 0, panic, MLX4_CMD_CLOSE_HCA, 2405 MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE); 2406} 2407 2408struct mlx4_config_dev { 2409 __be32 update_flags; 2410 __be32 rsvd1[3]; 2411 __be16 vxlan_udp_dport; 2412 __be16 rsvd2; 2413 __be16 roce_v2_entropy; 2414 __be16 roce_v2_udp_dport; 2415 __be32 roce_flags; 2416 __be32 rsvd4[25]; 2417 __be16 rsvd5; 2418 u8 rsvd6; 2419 u8 rx_checksum_val; 2420}; 2421 2422#define MLX4_VXLAN_UDP_DPORT (1 << 0) 2423#define MLX4_ROCE_V2_UDP_DPORT BIT(3) 2424#define MLX4_DISABLE_RX_PORT BIT(18) 2425 2426static int mlx4_CONFIG_DEV_set(struct mlx4_dev *dev, struct mlx4_config_dev *config_dev) 2427{ 2428 int err; 2429 struct mlx4_cmd_mailbox *mailbox; 2430 2431 mailbox = mlx4_alloc_cmd_mailbox(dev); 2432 if (IS_ERR(mailbox)) 2433 return PTR_ERR(mailbox); 2434 2435 memcpy(mailbox->buf, config_dev, sizeof(*config_dev)); 2436 2437 err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_CONFIG_DEV, 2438 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 2439 2440 mlx4_free_cmd_mailbox(dev, mailbox); 2441 return err; 2442} 2443 2444static int mlx4_CONFIG_DEV_get(struct mlx4_dev *dev, struct mlx4_config_dev *config_dev) 2445{ 2446 int err; 2447 struct mlx4_cmd_mailbox *mailbox; 2448 2449 mailbox = mlx4_alloc_cmd_mailbox(dev); 2450 if (IS_ERR(mailbox)) 2451 return PTR_ERR(mailbox); 2452 2453 err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 1, MLX4_CMD_CONFIG_DEV, 2454 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 2455 2456 if (!err) 2457 memcpy(config_dev, mailbox->buf, sizeof(*config_dev)); 2458 2459 mlx4_free_cmd_mailbox(dev, mailbox); 2460 return err; 2461} 2462 2463/* Conversion between the HW values and the actual functionality. 2464 * The value represented by the array index, 2465 * and the functionality determined by the flags. 2466 */ 2467static const u8 config_dev_csum_flags[] = { 2468 [0] = 0, 2469 [1] = MLX4_RX_CSUM_MODE_VAL_NON_TCP_UDP, 2470 [2] = MLX4_RX_CSUM_MODE_VAL_NON_TCP_UDP | 2471 MLX4_RX_CSUM_MODE_L4, 2472 [3] = MLX4_RX_CSUM_MODE_L4 | 2473 MLX4_RX_CSUM_MODE_IP_OK_IP_NON_TCP_UDP | 2474 MLX4_RX_CSUM_MODE_MULTI_VLAN 2475}; 2476 2477int mlx4_config_dev_retrieval(struct mlx4_dev *dev, 2478 struct mlx4_config_dev_params *params) 2479{ 2480 struct mlx4_config_dev config_dev = {0}; 2481 int err; 2482 u8 csum_mask; 2483 2484#define CONFIG_DEV_RX_CSUM_MODE_MASK 0x7 2485#define CONFIG_DEV_RX_CSUM_MODE_PORT1_BIT_OFFSET 0 2486#define CONFIG_DEV_RX_CSUM_MODE_PORT2_BIT_OFFSET 4 2487 2488 if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_CONFIG_DEV)) 2489 return -EOPNOTSUPP; 2490 2491 err = mlx4_CONFIG_DEV_get(dev, &config_dev); 2492 if (err) 2493 return err; 2494 2495 csum_mask = (config_dev.rx_checksum_val >> CONFIG_DEV_RX_CSUM_MODE_PORT1_BIT_OFFSET) & 2496 CONFIG_DEV_RX_CSUM_MODE_MASK; 2497 2498 if (csum_mask >= ARRAY_SIZE(config_dev_csum_flags)) 2499 return -EINVAL; 2500 params->rx_csum_flags_port_1 = config_dev_csum_flags[csum_mask]; 2501 2502 csum_mask = (config_dev.rx_checksum_val >> CONFIG_DEV_RX_CSUM_MODE_PORT2_BIT_OFFSET) & 2503 CONFIG_DEV_RX_CSUM_MODE_MASK; 2504 2505 if (csum_mask >= ARRAY_SIZE(config_dev_csum_flags)) 2506 return -EINVAL; 2507 params->rx_csum_flags_port_2 = config_dev_csum_flags[csum_mask]; 2508 2509 params->vxlan_udp_dport = be16_to_cpu(config_dev.vxlan_udp_dport); 2510 2511 return 0; 2512} 2513EXPORT_SYMBOL_GPL(mlx4_config_dev_retrieval); 2514 2515int mlx4_config_vxlan_port(struct mlx4_dev *dev, __be16 udp_port) 2516{ 2517 struct mlx4_config_dev config_dev; 2518 2519 memset(&config_dev, 0, sizeof(config_dev)); 2520 config_dev.update_flags = cpu_to_be32(MLX4_VXLAN_UDP_DPORT); 2521 config_dev.vxlan_udp_dport = udp_port; 2522 2523 return mlx4_CONFIG_DEV_set(dev, &config_dev); 2524} 2525EXPORT_SYMBOL_GPL(mlx4_config_vxlan_port); 2526 2527#define CONFIG_DISABLE_RX_PORT BIT(15) 2528int mlx4_disable_rx_port_check(struct mlx4_dev *dev, bool dis) 2529{ 2530 struct mlx4_config_dev config_dev; 2531 2532 memset(&config_dev, 0, sizeof(config_dev)); 2533 config_dev.update_flags = cpu_to_be32(MLX4_DISABLE_RX_PORT); 2534 if (dis) 2535 config_dev.roce_flags = 2536 cpu_to_be32(CONFIG_DISABLE_RX_PORT); 2537 2538 return mlx4_CONFIG_DEV_set(dev, &config_dev); 2539} 2540 2541int mlx4_config_roce_v2_port(struct mlx4_dev *dev, u16 udp_port) 2542{ 2543 struct mlx4_config_dev config_dev; 2544 2545 memset(&config_dev, 0, sizeof(config_dev)); 2546 config_dev.update_flags = cpu_to_be32(MLX4_ROCE_V2_UDP_DPORT); 2547 config_dev.roce_v2_udp_dport = cpu_to_be16(udp_port); 2548 2549 return mlx4_CONFIG_DEV_set(dev, &config_dev); 2550} 2551EXPORT_SYMBOL_GPL(mlx4_config_roce_v2_port); 2552 2553int mlx4_virt2phy_port_map(struct mlx4_dev *dev, u32 port1, u32 port2) 2554{ 2555 struct mlx4_cmd_mailbox *mailbox; 2556 struct { 2557 __be32 v_port1; 2558 __be32 v_port2; 2559 } *v2p; 2560 int err; 2561 2562 mailbox = mlx4_alloc_cmd_mailbox(dev); 2563 if (IS_ERR(mailbox)) 2564 return -ENOMEM; 2565 2566 v2p = mailbox->buf; 2567 v2p->v_port1 = cpu_to_be32(port1); 2568 v2p->v_port2 = cpu_to_be32(port2); 2569 2570 err = mlx4_cmd(dev, mailbox->dma, 0, 2571 MLX4_SET_PORT_VIRT2PHY, MLX4_CMD_VIRT_PORT_MAP, 2572 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 2573 2574 mlx4_free_cmd_mailbox(dev, mailbox); 2575 return err; 2576} 2577 2578 2579int mlx4_SET_ICM_SIZE(struct mlx4_dev *dev, u64 icm_size, u64 *aux_pages) 2580{ 2581 int ret = mlx4_cmd_imm(dev, icm_size, aux_pages, 0, 0, 2582 MLX4_CMD_SET_ICM_SIZE, 2583 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 2584 if (ret) 2585 return ret; 2586 2587 /* 2588 * Round up number of system pages needed in case 2589 * MLX4_ICM_PAGE_SIZE < PAGE_SIZE. 2590 */ 2591 *aux_pages = ALIGN(*aux_pages, PAGE_SIZE / MLX4_ICM_PAGE_SIZE) >> 2592 (PAGE_SHIFT - MLX4_ICM_PAGE_SHIFT); 2593 2594 return 0; 2595} 2596 2597int mlx4_NOP(struct mlx4_dev *dev) 2598{ 2599 /* Input modifier of 0x1f means "finish as soon as possible." */ 2600 return mlx4_cmd(dev, 0, 0x1f, 0, MLX4_CMD_NOP, MLX4_CMD_TIME_CLASS_A, 2601 MLX4_CMD_NATIVE); 2602} 2603 2604int mlx4_query_diag_counters(struct mlx4_dev *dev, u8 op_modifier, 2605 const u32 offset[], 2606 u32 value[], size_t array_len, u8 port) 2607{ 2608 struct mlx4_cmd_mailbox *mailbox; 2609 u32 *outbox; 2610 size_t i; 2611 int ret; 2612 2613 mailbox = mlx4_alloc_cmd_mailbox(dev); 2614 if (IS_ERR(mailbox)) 2615 return PTR_ERR(mailbox); 2616 2617 outbox = mailbox->buf; 2618 2619 ret = mlx4_cmd_box(dev, 0, mailbox->dma, port, op_modifier, 2620 MLX4_CMD_DIAG_RPRT, MLX4_CMD_TIME_CLASS_A, 2621 MLX4_CMD_NATIVE); 2622 if (ret) 2623 goto out; 2624 2625 for (i = 0; i < array_len; i++) { 2626 if (offset[i] > MLX4_MAILBOX_SIZE) { 2627 ret = -EINVAL; 2628 goto out; 2629 } 2630 2631 MLX4_GET(value[i], outbox, offset[i]); 2632 } 2633 2634out: 2635 mlx4_free_cmd_mailbox(dev, mailbox); 2636 return ret; 2637} 2638EXPORT_SYMBOL(mlx4_query_diag_counters); 2639 2640int mlx4_get_phys_port_id(struct mlx4_dev *dev) 2641{ 2642 u8 port; 2643 u32 *outbox; 2644 struct mlx4_cmd_mailbox *mailbox; 2645 u32 in_mod; 2646 u32 guid_hi, guid_lo; 2647 int err, ret = 0; 2648#define MOD_STAT_CFG_PORT_OFFSET 8 2649#define MOD_STAT_CFG_GUID_H 0X14 2650#define MOD_STAT_CFG_GUID_L 0X1c 2651 2652 mailbox = mlx4_alloc_cmd_mailbox(dev); 2653 if (IS_ERR(mailbox)) 2654 return PTR_ERR(mailbox); 2655 outbox = mailbox->buf; 2656 2657 for (port = 1; port <= dev->caps.num_ports; port++) { 2658 in_mod = port << MOD_STAT_CFG_PORT_OFFSET; 2659 err = mlx4_cmd_box(dev, 0, mailbox->dma, in_mod, 0x2, 2660 MLX4_CMD_MOD_STAT_CFG, MLX4_CMD_TIME_CLASS_A, 2661 MLX4_CMD_NATIVE); 2662 if (err) { 2663 mlx4_err(dev, "Fail to get port %d uplink guid\n", 2664 port); 2665 ret = err; 2666 } else { 2667 MLX4_GET(guid_hi, outbox, MOD_STAT_CFG_GUID_H); 2668 MLX4_GET(guid_lo, outbox, MOD_STAT_CFG_GUID_L); 2669 dev->caps.phys_port_id[port] = (u64)guid_lo | 2670 (u64)guid_hi << 32; 2671 } 2672 } 2673 mlx4_free_cmd_mailbox(dev, mailbox); 2674 return ret; 2675} 2676 2677#define MLX4_WOL_SETUP_MODE (5 << 28) 2678int mlx4_wol_read(struct mlx4_dev *dev, u64 *config, int port) 2679{ 2680 u32 in_mod = MLX4_WOL_SETUP_MODE | port << 8; 2681 2682 return mlx4_cmd_imm(dev, 0, config, in_mod, 0x3, 2683 MLX4_CMD_MOD_STAT_CFG, MLX4_CMD_TIME_CLASS_A, 2684 MLX4_CMD_NATIVE); 2685} 2686EXPORT_SYMBOL_GPL(mlx4_wol_read); 2687 2688int mlx4_wol_write(struct mlx4_dev *dev, u64 config, int port) 2689{ 2690 u32 in_mod = MLX4_WOL_SETUP_MODE | port << 8; 2691 2692 return mlx4_cmd(dev, config, in_mod, 0x1, MLX4_CMD_MOD_STAT_CFG, 2693 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 2694} 2695EXPORT_SYMBOL_GPL(mlx4_wol_write); 2696 2697enum { 2698 ADD_TO_MCG = 0x26, 2699}; 2700 2701 2702void mlx4_opreq_action(struct work_struct *work) 2703{ 2704 struct mlx4_priv *priv = container_of(work, struct mlx4_priv, 2705 opreq_task); 2706 struct mlx4_dev *dev = &priv->dev; 2707 int num_tasks = atomic_read(&priv->opreq_count); 2708 struct mlx4_cmd_mailbox *mailbox; 2709 struct mlx4_mgm *mgm; 2710 u32 *outbox; 2711 u32 modifier; 2712 u16 token; 2713 u16 type; 2714 int err; 2715 u32 num_qps; 2716 struct mlx4_qp qp; 2717 int i; 2718 u8 rem_mcg; 2719 u8 prot; 2720 2721#define GET_OP_REQ_MODIFIER_OFFSET 0x08 2722#define GET_OP_REQ_TOKEN_OFFSET 0x14 2723#define GET_OP_REQ_TYPE_OFFSET 0x1a 2724#define GET_OP_REQ_DATA_OFFSET 0x20 2725 2726 mailbox = mlx4_alloc_cmd_mailbox(dev); 2727 if (IS_ERR(mailbox)) { 2728 mlx4_err(dev, "Failed to allocate mailbox for GET_OP_REQ\n"); 2729 return; 2730 } 2731 outbox = mailbox->buf; 2732 2733 while (num_tasks) { 2734 err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, 2735 MLX4_CMD_GET_OP_REQ, MLX4_CMD_TIME_CLASS_A, 2736 MLX4_CMD_NATIVE); 2737 if (err) { 2738 mlx4_err(dev, "Failed to retrieve required operation: %d\n", 2739 err); 2740 goto out; 2741 } 2742 MLX4_GET(modifier, outbox, GET_OP_REQ_MODIFIER_OFFSET); 2743 MLX4_GET(token, outbox, GET_OP_REQ_TOKEN_OFFSET); 2744 MLX4_GET(type, outbox, GET_OP_REQ_TYPE_OFFSET); 2745 type &= 0xfff; 2746 2747 switch (type) { 2748 case ADD_TO_MCG: 2749 if (dev->caps.steering_mode == 2750 MLX4_STEERING_MODE_DEVICE_MANAGED) { 2751 mlx4_warn(dev, "ADD MCG operation is not supported in DEVICE_MANAGED steering mode\n"); 2752 err = EPERM; 2753 break; 2754 } 2755 mgm = (struct mlx4_mgm *)((u8 *)(outbox) + 2756 GET_OP_REQ_DATA_OFFSET); 2757 num_qps = be32_to_cpu(mgm->members_count) & 2758 MGM_QPN_MASK; 2759 rem_mcg = ((u8 *)(&mgm->members_count))[0] & 1; 2760 prot = ((u8 *)(&mgm->members_count))[0] >> 6; 2761 2762 for (i = 0; i < num_qps; i++) { 2763 qp.qpn = be32_to_cpu(mgm->qp[i]); 2764 if (rem_mcg) 2765 err = mlx4_multicast_detach(dev, &qp, 2766 mgm->gid, 2767 prot, 0); 2768 else 2769 err = mlx4_multicast_attach(dev, &qp, 2770 mgm->gid, 2771 mgm->gid[5] 2772 , 0, prot, 2773 NULL); 2774 if (err) 2775 break; 2776 } 2777 break; 2778 default: 2779 mlx4_warn(dev, "Bad type for required operation\n"); 2780 err = EINVAL; 2781 break; 2782 } 2783 err = mlx4_cmd(dev, 0, ((u32) err | 2784 (__force u32)cpu_to_be32(token) << 16), 2785 1, MLX4_CMD_GET_OP_REQ, MLX4_CMD_TIME_CLASS_A, 2786 MLX4_CMD_NATIVE); 2787 if (err) { 2788 mlx4_err(dev, "Failed to acknowledge required request: %d\n", 2789 err); 2790 goto out; 2791 } 2792 memset(outbox, 0, 0xffc); 2793 num_tasks = atomic_dec_return(&priv->opreq_count); 2794 } 2795 2796out: 2797 mlx4_free_cmd_mailbox(dev, mailbox); 2798} 2799 2800static int mlx4_check_smp_firewall_active(struct mlx4_dev *dev, 2801 struct mlx4_cmd_mailbox *mailbox) 2802{ 2803#define MLX4_CMD_MAD_DEMUX_SET_ATTR_OFFSET 0x10 2804#define MLX4_CMD_MAD_DEMUX_GETRESP_ATTR_OFFSET 0x20 2805#define MLX4_CMD_MAD_DEMUX_TRAP_ATTR_OFFSET 0x40 2806#define MLX4_CMD_MAD_DEMUX_TRAP_REPRESS_ATTR_OFFSET 0x70 2807 2808 u32 set_attr_mask, getresp_attr_mask; 2809 u32 trap_attr_mask, traprepress_attr_mask; 2810 2811 MLX4_GET(set_attr_mask, mailbox->buf, 2812 MLX4_CMD_MAD_DEMUX_SET_ATTR_OFFSET); 2813 mlx4_dbg(dev, "SMP firewall set_attribute_mask = 0x%x\n", 2814 set_attr_mask); 2815 2816 MLX4_GET(getresp_attr_mask, mailbox->buf, 2817 MLX4_CMD_MAD_DEMUX_GETRESP_ATTR_OFFSET); 2818 mlx4_dbg(dev, "SMP firewall getresp_attribute_mask = 0x%x\n", 2819 getresp_attr_mask); 2820 2821 MLX4_GET(trap_attr_mask, mailbox->buf, 2822 MLX4_CMD_MAD_DEMUX_TRAP_ATTR_OFFSET); 2823 mlx4_dbg(dev, "SMP firewall trap_attribute_mask = 0x%x\n", 2824 trap_attr_mask); 2825 2826 MLX4_GET(traprepress_attr_mask, mailbox->buf, 2827 MLX4_CMD_MAD_DEMUX_TRAP_REPRESS_ATTR_OFFSET); 2828 mlx4_dbg(dev, "SMP firewall traprepress_attribute_mask = 0x%x\n", 2829 traprepress_attr_mask); 2830 2831 if (set_attr_mask && getresp_attr_mask && trap_attr_mask && 2832 traprepress_attr_mask) 2833 return 1; 2834 2835 return 0; 2836} 2837 2838int mlx4_config_mad_demux(struct mlx4_dev *dev) 2839{ 2840 struct mlx4_cmd_mailbox *mailbox; 2841 int err; 2842 2843 /* Check if mad_demux is supported */ 2844 if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_MAD_DEMUX)) 2845 return 0; 2846 2847 mailbox = mlx4_alloc_cmd_mailbox(dev); 2848 if (IS_ERR(mailbox)) { 2849 mlx4_warn(dev, "Failed to allocate mailbox for cmd MAD_DEMUX"); 2850 return -ENOMEM; 2851 } 2852 2853 /* Query mad_demux to find out which MADs are handled by internal sma */ 2854 err = mlx4_cmd_box(dev, 0, mailbox->dma, 0x01 /* subn mgmt class */, 2855 MLX4_CMD_MAD_DEMUX_QUERY_RESTR, MLX4_CMD_MAD_DEMUX, 2856 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 2857 if (err) { 2858 mlx4_warn(dev, "MLX4_CMD_MAD_DEMUX: query restrictions failed (%d)\n", 2859 err); 2860 goto out; 2861 } 2862 2863 if (mlx4_check_smp_firewall_active(dev, mailbox)) 2864 dev->flags |= MLX4_FLAG_SECURE_HOST; 2865 2866 /* Config mad_demux to handle all MADs returned by the query above */ 2867 err = mlx4_cmd(dev, mailbox->dma, 0x01 /* subn mgmt class */, 2868 MLX4_CMD_MAD_DEMUX_CONFIG, MLX4_CMD_MAD_DEMUX, 2869 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 2870 if (err) { 2871 mlx4_warn(dev, "MLX4_CMD_MAD_DEMUX: configure failed (%d)\n", err); 2872 goto out; 2873 } 2874 2875 if (dev->flags & MLX4_FLAG_SECURE_HOST) 2876 mlx4_warn(dev, "HCA operating in secure-host mode. SMP firewall activated.\n"); 2877out: 2878 mlx4_free_cmd_mailbox(dev, mailbox); 2879 return err; 2880} 2881 2882/* Access Reg commands */ 2883enum mlx4_access_reg_masks { 2884 MLX4_ACCESS_REG_STATUS_MASK = 0x7f, 2885 MLX4_ACCESS_REG_METHOD_MASK = 0x7f, 2886 MLX4_ACCESS_REG_LEN_MASK = 0x7ff 2887}; 2888 2889struct mlx4_access_reg { 2890 __be16 constant1; 2891 u8 status; 2892 u8 resrvd1; 2893 __be16 reg_id; 2894 u8 method; 2895 u8 constant2; 2896 __be32 resrvd2[2]; 2897 __be16 len_const; 2898 __be16 resrvd3; 2899#define MLX4_ACCESS_REG_HEADER_SIZE (20) 2900 u8 reg_data[MLX4_MAILBOX_SIZE-MLX4_ACCESS_REG_HEADER_SIZE]; 2901} __attribute__((__packed__)); 2902 2903/** 2904 * mlx4_ACCESS_REG - Generic access reg command. 2905 * @dev: mlx4_dev. 2906 * @reg_id: register ID to access. 2907 * @method: Access method Read/Write. 2908 * @reg_len: register length to Read/Write in bytes. 2909 * @reg_data: reg_data pointer to Read/Write From/To. 2910 * 2911 * Access ConnectX registers FW command. 2912 * Returns 0 on success and copies outbox mlx4_access_reg data 2913 * field into reg_data or a negative error code. 2914 */ 2915static int mlx4_ACCESS_REG(struct mlx4_dev *dev, u16 reg_id, 2916 enum mlx4_access_reg_method method, 2917 u16 reg_len, void *reg_data) 2918{ 2919 struct mlx4_cmd_mailbox *inbox, *outbox; 2920 struct mlx4_access_reg *inbuf, *outbuf; 2921 int err; 2922 2923 inbox = mlx4_alloc_cmd_mailbox(dev); 2924 if (IS_ERR(inbox)) 2925 return PTR_ERR(inbox); 2926 2927 outbox = mlx4_alloc_cmd_mailbox(dev); 2928 if (IS_ERR(outbox)) { 2929 mlx4_free_cmd_mailbox(dev, inbox); 2930 return PTR_ERR(outbox); 2931 } 2932 2933 inbuf = inbox->buf; 2934 outbuf = outbox->buf; 2935 2936 inbuf->constant1 = cpu_to_be16(0x1<<11 | 0x4); 2937 inbuf->constant2 = 0x1; 2938 inbuf->reg_id = cpu_to_be16(reg_id); 2939 inbuf->method = method & MLX4_ACCESS_REG_METHOD_MASK; 2940 2941 reg_len = min(reg_len, (u16)(sizeof(inbuf->reg_data))); 2942 inbuf->len_const = 2943 cpu_to_be16(((reg_len/4 + 1) & MLX4_ACCESS_REG_LEN_MASK) | 2944 ((0x3) << 12)); 2945 2946 memcpy(inbuf->reg_data, reg_data, reg_len); 2947 err = mlx4_cmd_box(dev, inbox->dma, outbox->dma, 0, 0, 2948 MLX4_CMD_ACCESS_REG, MLX4_CMD_TIME_CLASS_C, 2949 MLX4_CMD_WRAPPED); 2950 if (err) 2951 goto out; 2952 2953 if (outbuf->status & MLX4_ACCESS_REG_STATUS_MASK) { 2954 err = outbuf->status & MLX4_ACCESS_REG_STATUS_MASK; 2955 mlx4_err(dev, 2956 "MLX4_CMD_ACCESS_REG(%x) returned REG status (%x)\n", 2957 reg_id, err); 2958 goto out; 2959 } 2960 2961 memcpy(reg_data, outbuf->reg_data, reg_len); 2962out: 2963 mlx4_free_cmd_mailbox(dev, inbox); 2964 mlx4_free_cmd_mailbox(dev, outbox); 2965 return err; 2966} 2967 2968/* ConnectX registers IDs */ 2969enum mlx4_reg_id { 2970 MLX4_REG_ID_PTYS = 0x5004, 2971}; 2972 2973/** 2974 * mlx4_ACCESS_PTYS_REG - Access PTYs (Port Type and Speed) 2975 * register 2976 * @dev: mlx4_dev. 2977 * @method: Access method Read/Write. 2978 * @ptys_reg: PTYS register data pointer. 2979 * 2980 * Access ConnectX PTYS register, to Read/Write Port Type/Speed 2981 * configuration 2982 * Returns 0 on success or a negative error code. 2983 */ 2984int mlx4_ACCESS_PTYS_REG(struct mlx4_dev *dev, 2985 enum mlx4_access_reg_method method, 2986 struct mlx4_ptys_reg *ptys_reg) 2987{ 2988 return mlx4_ACCESS_REG(dev, MLX4_REG_ID_PTYS, 2989 method, sizeof(*ptys_reg), ptys_reg); 2990} 2991EXPORT_SYMBOL_GPL(mlx4_ACCESS_PTYS_REG); 2992 2993int mlx4_ACCESS_REG_wrapper(struct mlx4_dev *dev, int slave, 2994 struct mlx4_vhcr *vhcr, 2995 struct mlx4_cmd_mailbox *inbox, 2996 struct mlx4_cmd_mailbox *outbox, 2997 struct mlx4_cmd_info *cmd) 2998{ 2999 struct mlx4_access_reg *inbuf = inbox->buf; 3000 u8 method = inbuf->method & MLX4_ACCESS_REG_METHOD_MASK; 3001 u16 reg_id = be16_to_cpu(inbuf->reg_id); 3002 3003 if (slave != mlx4_master_func_num(dev) && 3004 method == MLX4_ACCESS_REG_WRITE) 3005 return -EPERM; 3006 3007 if (reg_id == MLX4_REG_ID_PTYS) { 3008 struct mlx4_ptys_reg *ptys_reg = 3009 (struct mlx4_ptys_reg *)inbuf->reg_data; 3010 3011 ptys_reg->local_port = 3012 mlx4_slave_convert_port(dev, slave, 3013 ptys_reg->local_port); 3014 } 3015 3016 return mlx4_cmd_box(dev, inbox->dma, outbox->dma, vhcr->in_modifier, 3017 0, MLX4_CMD_ACCESS_REG, MLX4_CMD_TIME_CLASS_C, 3018 MLX4_CMD_NATIVE); 3019} 3020 3021static int mlx4_SET_PORT_phv_bit(struct mlx4_dev *dev, u8 port, u8 phv_bit) 3022{ 3023#define SET_PORT_GEN_PHV_VALID 0x10 3024#define SET_PORT_GEN_PHV_EN 0x80 3025 3026 struct mlx4_cmd_mailbox *mailbox; 3027 struct mlx4_set_port_general_context *context; 3028 u32 in_mod; 3029 int err; 3030 3031 mailbox = mlx4_alloc_cmd_mailbox(dev); 3032 if (IS_ERR(mailbox)) 3033 return PTR_ERR(mailbox); 3034 context = mailbox->buf; 3035 3036 context->flags2 |= SET_PORT_GEN_PHV_VALID; 3037 if (phv_bit) 3038 context->phv_en |= SET_PORT_GEN_PHV_EN; 3039 3040 in_mod = MLX4_SET_PORT_GENERAL << 8 | port; 3041 err = mlx4_cmd(dev, mailbox->dma, in_mod, MLX4_SET_PORT_ETH_OPCODE, 3042 MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B, 3043 MLX4_CMD_NATIVE); 3044 3045 mlx4_free_cmd_mailbox(dev, mailbox); 3046 return err; 3047} 3048 3049int get_phv_bit(struct mlx4_dev *dev, u8 port, int *phv) 3050{ 3051 int err; 3052 struct mlx4_func_cap func_cap; 3053 3054 memset(&func_cap, 0, sizeof(func_cap)); 3055 err = mlx4_QUERY_FUNC_CAP(dev, port, &func_cap); 3056 if (!err) 3057 *phv = func_cap.flags0 & QUERY_FUNC_CAP_PHV_BIT; 3058 return err; 3059} 3060EXPORT_SYMBOL(get_phv_bit); 3061 3062int set_phv_bit(struct mlx4_dev *dev, u8 port, int new_val) 3063{ 3064 int ret; 3065 3066 if (mlx4_is_slave(dev)) 3067 return -EPERM; 3068 3069 if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_PHV_EN && 3070 !(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_SKIP_OUTER_VLAN)) { 3071 ret = mlx4_SET_PORT_phv_bit(dev, port, new_val); 3072 if (!ret) 3073 dev->caps.phv_bit[port] = new_val; 3074 return ret; 3075 } 3076 3077 return -EOPNOTSUPP; 3078} 3079EXPORT_SYMBOL(set_phv_bit); 3080 3081int mlx4_get_is_vlan_offload_disabled(struct mlx4_dev *dev, u8 port, 3082 bool *vlan_offload_disabled) 3083{ 3084 struct mlx4_func_cap func_cap; 3085 int err; 3086 3087 memset(&func_cap, 0, sizeof(func_cap)); 3088 err = mlx4_QUERY_FUNC_CAP(dev, port, &func_cap); 3089 if (!err) 3090 *vlan_offload_disabled = 3091 !!(func_cap.flags0 & 3092 QUERY_FUNC_CAP_VLAN_OFFLOAD_DISABLE); 3093 return err; 3094} 3095EXPORT_SYMBOL(mlx4_get_is_vlan_offload_disabled); 3096 3097void mlx4_replace_zero_macs(struct mlx4_dev *dev) 3098{ 3099 int i; 3100 u8 mac_addr[ETH_ALEN]; 3101 3102 dev->port_random_macs = 0; 3103 for (i = 1; i <= dev->caps.num_ports; ++i) 3104 if (!dev->caps.def_mac[i] && 3105 dev->caps.port_type[i] == MLX4_PORT_TYPE_ETH) { 3106 eth_random_addr(mac_addr); 3107 dev->port_random_macs |= 1 << i; 3108 dev->caps.def_mac[i] = ether_addr_to_u64(mac_addr); 3109 } 3110} 3111EXPORT_SYMBOL_GPL(mlx4_replace_zero_macs);