15a2cc190SJeff Kirsher /* 25a2cc190SJeff Kirsher * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 35a2cc190SJeff Kirsher * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved. 45a2cc190SJeff Kirsher * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved. 55a2cc190SJeff Kirsher * 65a2cc190SJeff Kirsher * This software is available to you under a choice of one of two 75a2cc190SJeff Kirsher * licenses. You may choose to be licensed under the terms of the GNU 85a2cc190SJeff Kirsher * General Public License (GPL) Version 2, available from the file 95a2cc190SJeff Kirsher * COPYING in the main directory of this source tree, or the 105a2cc190SJeff Kirsher * OpenIB.org BSD license below: 115a2cc190SJeff Kirsher * 125a2cc190SJeff Kirsher * Redistribution and use in source and binary forms, with or 135a2cc190SJeff Kirsher * without modification, are permitted provided that the following 145a2cc190SJeff Kirsher * conditions are met: 155a2cc190SJeff Kirsher * 165a2cc190SJeff Kirsher * - Redistributions of source code must retain the above 175a2cc190SJeff Kirsher * copyright notice, this list of conditions and the following 185a2cc190SJeff Kirsher * disclaimer. 195a2cc190SJeff Kirsher * 205a2cc190SJeff Kirsher * - Redistributions in binary form must reproduce the above 215a2cc190SJeff Kirsher * copyright notice, this list of conditions and the following 225a2cc190SJeff Kirsher * disclaimer in the documentation and/or other materials 235a2cc190SJeff Kirsher * provided with the distribution. 245a2cc190SJeff Kirsher * 255a2cc190SJeff Kirsher * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 265a2cc190SJeff Kirsher * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 275a2cc190SJeff Kirsher * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 285a2cc190SJeff Kirsher * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 295a2cc190SJeff Kirsher * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 305a2cc190SJeff Kirsher * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 315a2cc190SJeff Kirsher * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 325a2cc190SJeff Kirsher * SOFTWARE. 335a2cc190SJeff Kirsher */ 345a2cc190SJeff Kirsher 355cc914f1SMarcel Apfelbaum #include <linux/etherdevice.h> 365a2cc190SJeff Kirsher #include <linux/mlx4/cmd.h> 379d9779e7SPaul Gortmaker #include <linux/module.h> 385a2cc190SJeff Kirsher #include <linux/cache.h> 395a2cc190SJeff Kirsher 405a2cc190SJeff Kirsher #include "fw.h" 415a2cc190SJeff Kirsher #include "icm.h" 425a2cc190SJeff Kirsher 435a2cc190SJeff Kirsher enum { 445a2cc190SJeff Kirsher MLX4_COMMAND_INTERFACE_MIN_REV = 2, 455a2cc190SJeff Kirsher MLX4_COMMAND_INTERFACE_MAX_REV = 3, 465a2cc190SJeff Kirsher MLX4_COMMAND_INTERFACE_NEW_PORT_CMDS = 3, 475a2cc190SJeff Kirsher }; 485a2cc190SJeff Kirsher 495a2cc190SJeff Kirsher extern void __buggy_use_of_MLX4_GET(void); 505a2cc190SJeff Kirsher extern void __buggy_use_of_MLX4_PUT(void); 515a2cc190SJeff Kirsher 52eb939922SRusty Russell static bool enable_qos; 535a2cc190SJeff Kirsher module_param(enable_qos, bool, 0444); 545a2cc190SJeff Kirsher MODULE_PARM_DESC(enable_qos, "Enable Quality of Service support in the HCA (default: off)"); 555a2cc190SJeff Kirsher 565a2cc190SJeff Kirsher #define MLX4_GET(dest, source, offset) \ 575a2cc190SJeff Kirsher do { \ 585a2cc190SJeff Kirsher void *__p = (char *) (source) + (offset); \ 595a2cc190SJeff Kirsher switch (sizeof (dest)) { \ 605a2cc190SJeff Kirsher case 1: (dest) = *(u8 *) __p; break; \ 615a2cc190SJeff Kirsher case 2: (dest) = be16_to_cpup(__p); break; \ 625a2cc190SJeff Kirsher case 4: (dest) = be32_to_cpup(__p); break; \ 635a2cc190SJeff Kirsher case 8: (dest) = be64_to_cpup(__p); break; \ 645a2cc190SJeff Kirsher default: __buggy_use_of_MLX4_GET(); \ 655a2cc190SJeff Kirsher } \ 665a2cc190SJeff Kirsher } while (0) 675a2cc190SJeff Kirsher 685a2cc190SJeff Kirsher #define MLX4_PUT(dest, source, offset) \ 695a2cc190SJeff Kirsher do { \ 705a2cc190SJeff Kirsher void *__d = ((char *) (dest) + (offset)); \ 715a2cc190SJeff Kirsher switch (sizeof(source)) { \ 725a2cc190SJeff Kirsher case 1: *(u8 *) __d = (source); break; \ 735a2cc190SJeff Kirsher case 2: *(__be16 *) __d = cpu_to_be16(source); break; \ 745a2cc190SJeff Kirsher case 4: *(__be32 *) __d = cpu_to_be32(source); break; \ 755a2cc190SJeff Kirsher case 8: *(__be64 *) __d = cpu_to_be64(source); break; \ 765a2cc190SJeff Kirsher default: __buggy_use_of_MLX4_PUT(); \ 775a2cc190SJeff Kirsher } \ 785a2cc190SJeff Kirsher } while (0) 795a2cc190SJeff Kirsher 805a2cc190SJeff Kirsher static void dump_dev_cap_flags(struct mlx4_dev *dev, u64 flags) 815a2cc190SJeff Kirsher { 825a2cc190SJeff Kirsher static const char *fname[] = { 835a2cc190SJeff Kirsher [ 0] = "RC transport", 845a2cc190SJeff Kirsher [ 1] = "UC transport", 855a2cc190SJeff Kirsher [ 2] = "UD transport", 865a2cc190SJeff Kirsher [ 3] = "XRC transport", 875a2cc190SJeff Kirsher [ 4] = "reliable multicast", 885a2cc190SJeff Kirsher [ 5] = "FCoIB support", 895a2cc190SJeff Kirsher [ 6] = "SRQ support", 905a2cc190SJeff Kirsher [ 7] = "IPoIB checksum offload", 915a2cc190SJeff Kirsher [ 8] = "P_Key violation counter", 925a2cc190SJeff Kirsher [ 9] = "Q_Key violation counter", 935a2cc190SJeff Kirsher [10] = "VMM", 944d531aa8SOr Gerlitz [12] = "Dual Port Different Protocol (DPDP) support", 955a2cc190SJeff Kirsher [15] = "Big LSO headers", 965a2cc190SJeff Kirsher [16] = "MW support", 975a2cc190SJeff Kirsher [17] = "APM support", 985a2cc190SJeff Kirsher [18] = "Atomic ops support", 995a2cc190SJeff Kirsher [19] = "Raw multicast support", 1005a2cc190SJeff Kirsher [20] = "Address vector port checking support", 1015a2cc190SJeff Kirsher [21] = "UD multicast support", 1025a2cc190SJeff Kirsher [24] = "Demand paging support", 1035a2cc190SJeff Kirsher [25] = "Router support", 1045a2cc190SJeff Kirsher [30] = "IBoE support", 1055a2cc190SJeff Kirsher [32] = "Unicast loopback support", 106f3a9d1f2SYevgeny Petrilin [34] = "FCS header control", 1075a2cc190SJeff Kirsher [38] = "Wake On LAN support", 1085a2cc190SJeff Kirsher [40] = "UDP RSS support", 1095a2cc190SJeff Kirsher [41] = "Unicast VEP steering support", 1105a2cc190SJeff Kirsher [42] = "Multicast VEP steering support", 1115a2cc190SJeff Kirsher [48] = "Counters support", 112540b3a39SOr Gerlitz [53] = "Port ETS Scheduler support", 1134d531aa8SOr Gerlitz [55] = "Port link type sensing support", 11400f5ce99SJack Morgenstein [59] = "Port management change event support", 11508ff3235SOr Gerlitz [61] = "64 byte EQE support", 11608ff3235SOr Gerlitz [62] = "64 byte CQE support", 1175a2cc190SJeff Kirsher }; 1185a2cc190SJeff Kirsher int i; 1195a2cc190SJeff Kirsher 1205a2cc190SJeff Kirsher mlx4_dbg(dev, "DEV_CAP flags:\n"); 1215a2cc190SJeff Kirsher for (i = 0; i < ARRAY_SIZE(fname); ++i) 1225a2cc190SJeff Kirsher if (fname[i] && (flags & (1LL << i))) 1235a2cc190SJeff Kirsher mlx4_dbg(dev, " %s\n", fname[i]); 1245a2cc190SJeff Kirsher } 1255a2cc190SJeff Kirsher 126b3416f44SShlomo Pongratz static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) 127b3416f44SShlomo Pongratz { 128b3416f44SShlomo Pongratz static const char * const fname[] = { 129b3416f44SShlomo Pongratz [0] = "RSS support", 130b3416f44SShlomo Pongratz [1] = "RSS Toeplitz Hash Function support", 1310ff1fb65SHadar Hen Zion [2] = "RSS XOR Hash Function support", 13256cb4567SOr Gerlitz [3] = "Device managed flow steering support", 133d998735fSEugenia Emantayev [4] = "Automatic MAC reassignment support", 1344e8cf5b8SOr Gerlitz [5] = "Time stamping support", 1354e8cf5b8SOr Gerlitz [6] = "VST (control vlan insertion/stripping) support", 136b01978caSJack Morgenstein [7] = "FSM (MAC anti-spoofing) support", 1377ffdf726SOr Gerlitz [8] = "Dynamic QP updates support", 13856cb4567SOr Gerlitz [9] = "Device managed flow steering IPoIB support", 139114840c3SJack Morgenstein [10] = "TCP/IP offloads/flow-steering for VXLAN support", 14077507aa2SIdo Shamay [11] = "MAD DEMUX (Secure-Host) support", 14177507aa2SIdo Shamay [12] = "Large cache line (>64B) CQE stride support", 142adbc7ac5SSaeed Mahameed [13] = "Large cache line (>64B) EQE stride support", 143a53e3e8cSSaeed Mahameed [14] = "Ethernet protocol control support", 144d475c95bSMatan Barak [15] = "Ethernet Backplane autoneg support", 145*7ae0e400SMatan Barak [16] = "CONFIG DEV support", 146*7ae0e400SMatan Barak [17] = "Asymmetric EQs support" 147b3416f44SShlomo Pongratz }; 148b3416f44SShlomo Pongratz int i; 149b3416f44SShlomo Pongratz 150b3416f44SShlomo Pongratz for (i = 0; i < ARRAY_SIZE(fname); ++i) 151b3416f44SShlomo Pongratz if (fname[i] && (flags & (1LL << i))) 152b3416f44SShlomo Pongratz mlx4_dbg(dev, " %s\n", fname[i]); 153b3416f44SShlomo Pongratz } 154b3416f44SShlomo Pongratz 1555a2cc190SJeff Kirsher int mlx4_MOD_STAT_CFG(struct mlx4_dev *dev, struct mlx4_mod_stat_cfg *cfg) 1565a2cc190SJeff Kirsher { 1575a2cc190SJeff Kirsher struct mlx4_cmd_mailbox *mailbox; 1585a2cc190SJeff Kirsher u32 *inbox; 1595a2cc190SJeff Kirsher int err = 0; 1605a2cc190SJeff Kirsher 1615a2cc190SJeff Kirsher #define MOD_STAT_CFG_IN_SIZE 0x100 1625a2cc190SJeff Kirsher 1635a2cc190SJeff Kirsher #define MOD_STAT_CFG_PG_SZ_M_OFFSET 0x002 1645a2cc190SJeff Kirsher #define MOD_STAT_CFG_PG_SZ_OFFSET 0x003 1655a2cc190SJeff Kirsher 1665a2cc190SJeff Kirsher mailbox = mlx4_alloc_cmd_mailbox(dev); 1675a2cc190SJeff Kirsher if (IS_ERR(mailbox)) 1685a2cc190SJeff Kirsher return PTR_ERR(mailbox); 1695a2cc190SJeff Kirsher inbox = mailbox->buf; 1705a2cc190SJeff Kirsher 1715a2cc190SJeff Kirsher MLX4_PUT(inbox, cfg->log_pg_sz, MOD_STAT_CFG_PG_SZ_OFFSET); 1725a2cc190SJeff Kirsher MLX4_PUT(inbox, cfg->log_pg_sz_m, MOD_STAT_CFG_PG_SZ_M_OFFSET); 1735a2cc190SJeff Kirsher 1745a2cc190SJeff Kirsher err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_MOD_STAT_CFG, 175f9baff50SJack Morgenstein MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 1765a2cc190SJeff Kirsher 1775a2cc190SJeff Kirsher mlx4_free_cmd_mailbox(dev, mailbox); 1785a2cc190SJeff Kirsher return err; 1795a2cc190SJeff Kirsher } 1805a2cc190SJeff Kirsher 181e8c4265bSMatan Barak int mlx4_QUERY_FUNC(struct mlx4_dev *dev, struct mlx4_func *func, int slave) 182e8c4265bSMatan Barak { 183e8c4265bSMatan Barak struct mlx4_cmd_mailbox *mailbox; 184e8c4265bSMatan Barak u32 *outbox; 185e8c4265bSMatan Barak u8 in_modifier; 186e8c4265bSMatan Barak u8 field; 187e8c4265bSMatan Barak u16 field16; 188e8c4265bSMatan Barak int err; 189e8c4265bSMatan Barak 190e8c4265bSMatan Barak #define QUERY_FUNC_BUS_OFFSET 0x00 191e8c4265bSMatan Barak #define QUERY_FUNC_DEVICE_OFFSET 0x01 192e8c4265bSMatan Barak #define QUERY_FUNC_FUNCTION_OFFSET 0x01 193e8c4265bSMatan Barak #define QUERY_FUNC_PHYSICAL_FUNCTION_OFFSET 0x03 194e8c4265bSMatan Barak #define QUERY_FUNC_RSVD_EQS_OFFSET 0x04 195e8c4265bSMatan Barak #define QUERY_FUNC_MAX_EQ_OFFSET 0x06 196e8c4265bSMatan Barak #define QUERY_FUNC_RSVD_UARS_OFFSET 0x0b 197e8c4265bSMatan Barak 198e8c4265bSMatan Barak mailbox = mlx4_alloc_cmd_mailbox(dev); 199e8c4265bSMatan Barak if (IS_ERR(mailbox)) 200e8c4265bSMatan Barak return PTR_ERR(mailbox); 201e8c4265bSMatan Barak outbox = mailbox->buf; 202e8c4265bSMatan Barak 203e8c4265bSMatan Barak in_modifier = slave; 204e8c4265bSMatan Barak 205e8c4265bSMatan Barak err = mlx4_cmd_box(dev, 0, mailbox->dma, in_modifier, 0, 206e8c4265bSMatan Barak MLX4_CMD_QUERY_FUNC, 207e8c4265bSMatan Barak MLX4_CMD_TIME_CLASS_A, 208e8c4265bSMatan Barak MLX4_CMD_NATIVE); 209e8c4265bSMatan Barak if (err) 210e8c4265bSMatan Barak goto out; 211e8c4265bSMatan Barak 212e8c4265bSMatan Barak MLX4_GET(field, outbox, QUERY_FUNC_BUS_OFFSET); 213e8c4265bSMatan Barak func->bus = field & 0xf; 214e8c4265bSMatan Barak MLX4_GET(field, outbox, QUERY_FUNC_DEVICE_OFFSET); 215e8c4265bSMatan Barak func->device = field & 0xf1; 216e8c4265bSMatan Barak MLX4_GET(field, outbox, QUERY_FUNC_FUNCTION_OFFSET); 217e8c4265bSMatan Barak func->function = field & 0x7; 218e8c4265bSMatan Barak MLX4_GET(field, outbox, QUERY_FUNC_PHYSICAL_FUNCTION_OFFSET); 219e8c4265bSMatan Barak func->physical_function = field & 0xf; 220e8c4265bSMatan Barak MLX4_GET(field16, outbox, QUERY_FUNC_RSVD_EQS_OFFSET); 221e8c4265bSMatan Barak func->rsvd_eqs = field16 & 0xffff; 222e8c4265bSMatan Barak MLX4_GET(field16, outbox, QUERY_FUNC_MAX_EQ_OFFSET); 223e8c4265bSMatan Barak func->max_eq = field16 & 0xffff; 224e8c4265bSMatan Barak MLX4_GET(field, outbox, QUERY_FUNC_RSVD_UARS_OFFSET); 225e8c4265bSMatan Barak func->rsvd_uars = field & 0x0f; 226e8c4265bSMatan Barak 227e8c4265bSMatan Barak mlx4_dbg(dev, "Bus: %d, Device: %d, Function: %d, Physical function: %d, Max EQs: %d, Reserved EQs: %d, Reserved UARs: %d\n", 228e8c4265bSMatan Barak func->bus, func->device, func->function, func->physical_function, 229e8c4265bSMatan Barak func->max_eq, func->rsvd_eqs, func->rsvd_uars); 230e8c4265bSMatan Barak 231e8c4265bSMatan Barak out: 232e8c4265bSMatan Barak mlx4_free_cmd_mailbox(dev, mailbox); 233e8c4265bSMatan Barak return err; 234e8c4265bSMatan Barak } 235e8c4265bSMatan Barak 2365cc914f1SMarcel Apfelbaum int mlx4_QUERY_FUNC_CAP_wrapper(struct mlx4_dev *dev, int slave, 2375cc914f1SMarcel Apfelbaum struct mlx4_vhcr *vhcr, 2385cc914f1SMarcel Apfelbaum struct mlx4_cmd_mailbox *inbox, 2395cc914f1SMarcel Apfelbaum struct mlx4_cmd_mailbox *outbox, 2405cc914f1SMarcel Apfelbaum struct mlx4_cmd_info *cmd) 2415cc914f1SMarcel Apfelbaum { 2425a0d0a61SJack Morgenstein struct mlx4_priv *priv = mlx4_priv(dev); 24399ec41d0SJack Morgenstein u8 field, port; 24499ec41d0SJack Morgenstein u32 size, proxy_qp, qkey; 2455cc914f1SMarcel Apfelbaum int err = 0; 246*7ae0e400SMatan Barak struct mlx4_func func; 2475cc914f1SMarcel Apfelbaum 2485cc914f1SMarcel Apfelbaum #define QUERY_FUNC_CAP_FLAGS_OFFSET 0x0 2495cc914f1SMarcel Apfelbaum #define QUERY_FUNC_CAP_NUM_PORTS_OFFSET 0x1 2505cc914f1SMarcel Apfelbaum #define QUERY_FUNC_CAP_PF_BHVR_OFFSET 0x4 251105c320fSJack Morgenstein #define QUERY_FUNC_CAP_FMR_OFFSET 0x8 252eb456a68SJack Morgenstein #define QUERY_FUNC_CAP_QP_QUOTA_OFFSET_DEP 0x10 253eb456a68SJack Morgenstein #define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP 0x14 254eb456a68SJack Morgenstein #define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET_DEP 0x18 255eb456a68SJack Morgenstein #define QUERY_FUNC_CAP_MPT_QUOTA_OFFSET_DEP 0x20 256eb456a68SJack Morgenstein #define QUERY_FUNC_CAP_MTT_QUOTA_OFFSET_DEP 0x24 257eb456a68SJack Morgenstein #define QUERY_FUNC_CAP_MCG_QUOTA_OFFSET_DEP 0x28 2585cc914f1SMarcel Apfelbaum #define QUERY_FUNC_CAP_MAX_EQ_OFFSET 0x2c 25969612b9fSRoland Dreier #define QUERY_FUNC_CAP_RESERVED_EQ_OFFSET 0x30 2605cc914f1SMarcel Apfelbaum 261eb456a68SJack Morgenstein #define QUERY_FUNC_CAP_QP_QUOTA_OFFSET 0x50 262eb456a68SJack Morgenstein #define QUERY_FUNC_CAP_CQ_QUOTA_OFFSET 0x54 263eb456a68SJack Morgenstein #define QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET 0x58 264eb456a68SJack Morgenstein #define QUERY_FUNC_CAP_MPT_QUOTA_OFFSET 0x60 265eb456a68SJack Morgenstein #define QUERY_FUNC_CAP_MTT_QUOTA_OFFSET 0x64 266eb456a68SJack Morgenstein #define QUERY_FUNC_CAP_MCG_QUOTA_OFFSET 0x68 267eb456a68SJack Morgenstein 268105c320fSJack Morgenstein #define QUERY_FUNC_CAP_FMR_FLAG 0x80 269105c320fSJack Morgenstein #define QUERY_FUNC_CAP_FLAG_RDMA 0x40 270105c320fSJack Morgenstein #define QUERY_FUNC_CAP_FLAG_ETH 0x80 271eb456a68SJack Morgenstein #define QUERY_FUNC_CAP_FLAG_QUOTAS 0x10 272105c320fSJack Morgenstein 273105c320fSJack Morgenstein /* when opcode modifier = 1 */ 2745cc914f1SMarcel Apfelbaum #define QUERY_FUNC_CAP_PHYS_PORT_OFFSET 0x3 27599ec41d0SJack Morgenstein #define QUERY_FUNC_CAP_PRIV_VF_QKEY_OFFSET 0x4 27673e74ab4SHadar Hen Zion #define QUERY_FUNC_CAP_FLAGS0_OFFSET 0x8 27773e74ab4SHadar Hen Zion #define QUERY_FUNC_CAP_FLAGS1_OFFSET 0xc 2785cc914f1SMarcel Apfelbaum 27947605df9SJack Morgenstein #define QUERY_FUNC_CAP_QP0_TUNNEL 0x10 28047605df9SJack Morgenstein #define QUERY_FUNC_CAP_QP0_PROXY 0x14 28147605df9SJack Morgenstein #define QUERY_FUNC_CAP_QP1_TUNNEL 0x18 28247605df9SJack Morgenstein #define QUERY_FUNC_CAP_QP1_PROXY 0x1c 2838e1a28e8SHadar Hen Zion #define QUERY_FUNC_CAP_PHYS_PORT_ID 0x28 28447605df9SJack Morgenstein 28573e74ab4SHadar Hen Zion #define QUERY_FUNC_CAP_FLAGS1_FORCE_MAC 0x40 28673e74ab4SHadar Hen Zion #define QUERY_FUNC_CAP_FLAGS1_FORCE_VLAN 0x80 287eb17711bSHadar Hen Zion #define QUERY_FUNC_CAP_FLAGS1_NIC_INFO 0x10 28899ec41d0SJack Morgenstein #define QUERY_FUNC_CAP_VF_ENABLE_QP0 0x08 289105c320fSJack Morgenstein 29073e74ab4SHadar Hen Zion #define QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID 0x80 291*7ae0e400SMatan Barak #define QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS (1 << 31) 292105c320fSJack Morgenstein 2935cc914f1SMarcel Apfelbaum if (vhcr->op_modifier == 1) { 294449fc488SMatan Barak struct mlx4_active_ports actv_ports = 295449fc488SMatan Barak mlx4_get_active_ports(dev, slave); 296449fc488SMatan Barak int converted_port = mlx4_slave_convert_port( 297449fc488SMatan Barak dev, slave, vhcr->in_modifier); 298449fc488SMatan Barak 299449fc488SMatan Barak if (converted_port < 0) 300449fc488SMatan Barak return -EINVAL; 301449fc488SMatan Barak 302449fc488SMatan Barak vhcr->in_modifier = converted_port; 303449fc488SMatan Barak /* phys-port = logical-port */ 304449fc488SMatan Barak field = vhcr->in_modifier - 305449fc488SMatan Barak find_first_bit(actv_ports.ports, dev->caps.num_ports); 30647605df9SJack Morgenstein MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); 30747605df9SJack Morgenstein 30899ec41d0SJack Morgenstein port = vhcr->in_modifier; 30999ec41d0SJack Morgenstein proxy_qp = dev->phys_caps.base_proxy_sqpn + 8 * slave + port - 1; 31099ec41d0SJack Morgenstein 31199ec41d0SJack Morgenstein /* Set nic_info bit to mark new fields support */ 31299ec41d0SJack Morgenstein field = QUERY_FUNC_CAP_FLAGS1_NIC_INFO; 31399ec41d0SJack Morgenstein 31499ec41d0SJack Morgenstein if (mlx4_vf_smi_enabled(dev, slave, port) && 31599ec41d0SJack Morgenstein !mlx4_get_parav_qkey(dev, proxy_qp, &qkey)) { 31699ec41d0SJack Morgenstein field |= QUERY_FUNC_CAP_VF_ENABLE_QP0; 31799ec41d0SJack Morgenstein MLX4_PUT(outbox->buf, qkey, 31899ec41d0SJack Morgenstein QUERY_FUNC_CAP_PRIV_VF_QKEY_OFFSET); 31999ec41d0SJack Morgenstein } 32099ec41d0SJack Morgenstein MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS1_OFFSET); 32199ec41d0SJack Morgenstein 32247605df9SJack Morgenstein /* size is now the QP number */ 32399ec41d0SJack Morgenstein size = dev->phys_caps.base_tunnel_sqpn + 8 * slave + port - 1; 32447605df9SJack Morgenstein MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP0_TUNNEL); 32547605df9SJack Morgenstein 32647605df9SJack Morgenstein size += 2; 32747605df9SJack Morgenstein MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP1_TUNNEL); 32847605df9SJack Morgenstein 32999ec41d0SJack Morgenstein MLX4_PUT(outbox->buf, proxy_qp, QUERY_FUNC_CAP_QP0_PROXY); 33099ec41d0SJack Morgenstein proxy_qp += 2; 33199ec41d0SJack Morgenstein MLX4_PUT(outbox->buf, proxy_qp, QUERY_FUNC_CAP_QP1_PROXY); 33247605df9SJack Morgenstein 3338e1a28e8SHadar Hen Zion MLX4_PUT(outbox->buf, dev->caps.phys_port_id[vhcr->in_modifier], 3348e1a28e8SHadar Hen Zion QUERY_FUNC_CAP_PHYS_PORT_ID); 3358e1a28e8SHadar Hen Zion 3365cc914f1SMarcel Apfelbaum } else if (vhcr->op_modifier == 0) { 337449fc488SMatan Barak struct mlx4_active_ports actv_ports = 338449fc488SMatan Barak mlx4_get_active_ports(dev, slave); 339eb456a68SJack Morgenstein /* enable rdma and ethernet interfaces, and new quota locations */ 340eb456a68SJack Morgenstein field = (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA | 341eb456a68SJack Morgenstein QUERY_FUNC_CAP_FLAG_QUOTAS); 3425cc914f1SMarcel Apfelbaum MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FLAGS_OFFSET); 3435cc914f1SMarcel Apfelbaum 344449fc488SMatan Barak field = min( 345449fc488SMatan Barak bitmap_weight(actv_ports.ports, dev->caps.num_ports), 346449fc488SMatan Barak dev->caps.num_ports); 3475cc914f1SMarcel Apfelbaum MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); 3485cc914f1SMarcel Apfelbaum 34908ff3235SOr Gerlitz size = dev->caps.function_caps; /* set PF behaviours */ 3505cc914f1SMarcel Apfelbaum MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_PF_BHVR_OFFSET); 3515cc914f1SMarcel Apfelbaum 352105c320fSJack Morgenstein field = 0; /* protected FMR support not available as yet */ 353105c320fSJack Morgenstein MLX4_PUT(outbox->buf, field, QUERY_FUNC_CAP_FMR_OFFSET); 354105c320fSJack Morgenstein 3555a0d0a61SJack Morgenstein size = priv->mfunc.master.res_tracker.res_alloc[RES_QP].quota[slave]; 3565cc914f1SMarcel Apfelbaum MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); 357eb456a68SJack Morgenstein size = dev->caps.num_qps; 358eb456a68SJack Morgenstein MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_QP_QUOTA_OFFSET_DEP); 3595cc914f1SMarcel Apfelbaum 3605a0d0a61SJack Morgenstein size = priv->mfunc.master.res_tracker.res_alloc[RES_SRQ].quota[slave]; 3615cc914f1SMarcel Apfelbaum MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET); 362eb456a68SJack Morgenstein size = dev->caps.num_srqs; 363eb456a68SJack Morgenstein MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET_DEP); 3645cc914f1SMarcel Apfelbaum 3655a0d0a61SJack Morgenstein size = priv->mfunc.master.res_tracker.res_alloc[RES_CQ].quota[slave]; 3665cc914f1SMarcel Apfelbaum MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET); 367eb456a68SJack Morgenstein size = dev->caps.num_cqs; 368eb456a68SJack Morgenstein MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP); 3695cc914f1SMarcel Apfelbaum 370*7ae0e400SMatan Barak if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS) || 371*7ae0e400SMatan Barak mlx4_QUERY_FUNC(dev, &func, slave)) { 372*7ae0e400SMatan Barak size = vhcr->in_modifier & 373*7ae0e400SMatan Barak QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS ? 374*7ae0e400SMatan Barak dev->caps.num_eqs : 375*7ae0e400SMatan Barak rounddown_pow_of_two(dev->caps.num_eqs); 3765cc914f1SMarcel Apfelbaum MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MAX_EQ_OFFSET); 3775cc914f1SMarcel Apfelbaum size = dev->caps.reserved_eqs; 3785cc914f1SMarcel Apfelbaum MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); 379*7ae0e400SMatan Barak } else { 380*7ae0e400SMatan Barak size = vhcr->in_modifier & 381*7ae0e400SMatan Barak QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS ? 382*7ae0e400SMatan Barak func.max_eq : 383*7ae0e400SMatan Barak rounddown_pow_of_two(func.max_eq); 384*7ae0e400SMatan Barak MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MAX_EQ_OFFSET); 385*7ae0e400SMatan Barak size = func.rsvd_eqs; 386*7ae0e400SMatan Barak MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); 387*7ae0e400SMatan Barak } 3885cc914f1SMarcel Apfelbaum 3895a0d0a61SJack Morgenstein size = priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[slave]; 3905cc914f1SMarcel Apfelbaum MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET); 391eb456a68SJack Morgenstein size = dev->caps.num_mpts; 392eb456a68SJack Morgenstein MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET_DEP); 3935cc914f1SMarcel Apfelbaum 3945a0d0a61SJack Morgenstein size = priv->mfunc.master.res_tracker.res_alloc[RES_MTT].quota[slave]; 3955cc914f1SMarcel Apfelbaum MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET); 396eb456a68SJack Morgenstein size = dev->caps.num_mtts; 397eb456a68SJack Morgenstein MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET_DEP); 3985cc914f1SMarcel Apfelbaum 3995cc914f1SMarcel Apfelbaum size = dev->caps.num_mgms + dev->caps.num_amgms; 4005cc914f1SMarcel Apfelbaum MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET); 401eb456a68SJack Morgenstein MLX4_PUT(outbox->buf, size, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET_DEP); 4025cc914f1SMarcel Apfelbaum 4035cc914f1SMarcel Apfelbaum } else 4045cc914f1SMarcel Apfelbaum err = -EINVAL; 4055cc914f1SMarcel Apfelbaum 4065cc914f1SMarcel Apfelbaum return err; 4075cc914f1SMarcel Apfelbaum } 4085cc914f1SMarcel Apfelbaum 409225c6c8cSMatan Barak int mlx4_QUERY_FUNC_CAP(struct mlx4_dev *dev, u8 gen_or_port, 41047605df9SJack Morgenstein struct mlx4_func_cap *func_cap) 4115cc914f1SMarcel Apfelbaum { 4125cc914f1SMarcel Apfelbaum struct mlx4_cmd_mailbox *mailbox; 4135cc914f1SMarcel Apfelbaum u32 *outbox; 41447605df9SJack Morgenstein u8 field, op_modifier; 41599ec41d0SJack Morgenstein u32 size, qkey; 416eb456a68SJack Morgenstein int err = 0, quotas = 0; 417*7ae0e400SMatan Barak u32 in_modifier; 4185cc914f1SMarcel Apfelbaum 41947605df9SJack Morgenstein op_modifier = !!gen_or_port; /* 0 = general, 1 = logical port */ 420*7ae0e400SMatan Barak in_modifier = op_modifier ? gen_or_port : 421*7ae0e400SMatan Barak QUERY_FUNC_CAP_SUPPORTS_NON_POWER_OF_2_NUM_EQS; 4225cc914f1SMarcel Apfelbaum 4235cc914f1SMarcel Apfelbaum mailbox = mlx4_alloc_cmd_mailbox(dev); 4245cc914f1SMarcel Apfelbaum if (IS_ERR(mailbox)) 4255cc914f1SMarcel Apfelbaum return PTR_ERR(mailbox); 4265cc914f1SMarcel Apfelbaum 427*7ae0e400SMatan Barak err = mlx4_cmd_box(dev, 0, mailbox->dma, in_modifier, op_modifier, 42847605df9SJack Morgenstein MLX4_CMD_QUERY_FUNC_CAP, 4295cc914f1SMarcel Apfelbaum MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); 4305cc914f1SMarcel Apfelbaum if (err) 4315cc914f1SMarcel Apfelbaum goto out; 4325cc914f1SMarcel Apfelbaum 4335cc914f1SMarcel Apfelbaum outbox = mailbox->buf; 4345cc914f1SMarcel Apfelbaum 43547605df9SJack Morgenstein if (!op_modifier) { 4365cc914f1SMarcel Apfelbaum MLX4_GET(field, outbox, QUERY_FUNC_CAP_FLAGS_OFFSET); 437105c320fSJack Morgenstein if (!(field & (QUERY_FUNC_CAP_FLAG_ETH | QUERY_FUNC_CAP_FLAG_RDMA))) { 438105c320fSJack Morgenstein mlx4_err(dev, "The host supports neither eth nor rdma interfaces\n"); 4395cc914f1SMarcel Apfelbaum err = -EPROTONOSUPPORT; 4405cc914f1SMarcel Apfelbaum goto out; 4415cc914f1SMarcel Apfelbaum } 442105c320fSJack Morgenstein func_cap->flags = field; 443eb456a68SJack Morgenstein quotas = !!(func_cap->flags & QUERY_FUNC_CAP_FLAG_QUOTAS); 4445cc914f1SMarcel Apfelbaum 4455cc914f1SMarcel Apfelbaum MLX4_GET(field, outbox, QUERY_FUNC_CAP_NUM_PORTS_OFFSET); 4465cc914f1SMarcel Apfelbaum func_cap->num_ports = field; 4475cc914f1SMarcel Apfelbaum 4485cc914f1SMarcel Apfelbaum MLX4_GET(size, outbox, QUERY_FUNC_CAP_PF_BHVR_OFFSET); 4495cc914f1SMarcel Apfelbaum func_cap->pf_context_behaviour = size; 4505cc914f1SMarcel Apfelbaum 451eb456a68SJack Morgenstein if (quotas) { 4525cc914f1SMarcel Apfelbaum MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_QUOTA_OFFSET); 4535cc914f1SMarcel Apfelbaum func_cap->qp_quota = size & 0xFFFFFF; 4545cc914f1SMarcel Apfelbaum 4555cc914f1SMarcel Apfelbaum MLX4_GET(size, outbox, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET); 4565cc914f1SMarcel Apfelbaum func_cap->srq_quota = size & 0xFFFFFF; 4575cc914f1SMarcel Apfelbaum 4585cc914f1SMarcel Apfelbaum MLX4_GET(size, outbox, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET); 4595cc914f1SMarcel Apfelbaum func_cap->cq_quota = size & 0xFFFFFF; 4605cc914f1SMarcel Apfelbaum 4615cc914f1SMarcel Apfelbaum MLX4_GET(size, outbox, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET); 4625cc914f1SMarcel Apfelbaum func_cap->mpt_quota = size & 0xFFFFFF; 4635cc914f1SMarcel Apfelbaum 4645cc914f1SMarcel Apfelbaum MLX4_GET(size, outbox, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET); 4655cc914f1SMarcel Apfelbaum func_cap->mtt_quota = size & 0xFFFFFF; 4665cc914f1SMarcel Apfelbaum 4675cc914f1SMarcel Apfelbaum MLX4_GET(size, outbox, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET); 4685cc914f1SMarcel Apfelbaum func_cap->mcg_quota = size & 0xFFFFFF; 469eb456a68SJack Morgenstein 470eb456a68SJack Morgenstein } else { 471eb456a68SJack Morgenstein MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP_QUOTA_OFFSET_DEP); 472eb456a68SJack Morgenstein func_cap->qp_quota = size & 0xFFFFFF; 473eb456a68SJack Morgenstein 474eb456a68SJack Morgenstein MLX4_GET(size, outbox, QUERY_FUNC_CAP_SRQ_QUOTA_OFFSET_DEP); 475eb456a68SJack Morgenstein func_cap->srq_quota = size & 0xFFFFFF; 476eb456a68SJack Morgenstein 477eb456a68SJack Morgenstein MLX4_GET(size, outbox, QUERY_FUNC_CAP_CQ_QUOTA_OFFSET_DEP); 478eb456a68SJack Morgenstein func_cap->cq_quota = size & 0xFFFFFF; 479eb456a68SJack Morgenstein 480eb456a68SJack Morgenstein MLX4_GET(size, outbox, QUERY_FUNC_CAP_MPT_QUOTA_OFFSET_DEP); 481eb456a68SJack Morgenstein func_cap->mpt_quota = size & 0xFFFFFF; 482eb456a68SJack Morgenstein 483eb456a68SJack Morgenstein MLX4_GET(size, outbox, QUERY_FUNC_CAP_MTT_QUOTA_OFFSET_DEP); 484eb456a68SJack Morgenstein func_cap->mtt_quota = size & 0xFFFFFF; 485eb456a68SJack Morgenstein 486eb456a68SJack Morgenstein MLX4_GET(size, outbox, QUERY_FUNC_CAP_MCG_QUOTA_OFFSET_DEP); 487eb456a68SJack Morgenstein func_cap->mcg_quota = size & 0xFFFFFF; 488eb456a68SJack Morgenstein } 489eb456a68SJack Morgenstein MLX4_GET(size, outbox, QUERY_FUNC_CAP_MAX_EQ_OFFSET); 490eb456a68SJack Morgenstein func_cap->max_eq = size & 0xFFFFFF; 491eb456a68SJack Morgenstein 492eb456a68SJack Morgenstein MLX4_GET(size, outbox, QUERY_FUNC_CAP_RESERVED_EQ_OFFSET); 493eb456a68SJack Morgenstein func_cap->reserved_eq = size & 0xFFFFFF; 494eb456a68SJack Morgenstein 4955cc914f1SMarcel Apfelbaum goto out; 49647605df9SJack Morgenstein } 4975cc914f1SMarcel Apfelbaum 49847605df9SJack Morgenstein /* logical port query */ 49947605df9SJack Morgenstein if (gen_or_port > dev->caps.num_ports) { 50047605df9SJack Morgenstein err = -EINVAL; 50147605df9SJack Morgenstein goto out; 50247605df9SJack Morgenstein } 50347605df9SJack Morgenstein 504eb17711bSHadar Hen Zion MLX4_GET(func_cap->flags1, outbox, QUERY_FUNC_CAP_FLAGS1_OFFSET); 50547605df9SJack Morgenstein if (dev->caps.port_type[gen_or_port] == MLX4_PORT_TYPE_ETH) { 506bc82878bSJack Morgenstein if (func_cap->flags1 & QUERY_FUNC_CAP_FLAGS1_FORCE_VLAN) { 5075cc914f1SMarcel Apfelbaum mlx4_err(dev, "VLAN is enforced on this port\n"); 5085cc914f1SMarcel Apfelbaum err = -EPROTONOSUPPORT; 5095cc914f1SMarcel Apfelbaum goto out; 5105cc914f1SMarcel Apfelbaum } 5115cc914f1SMarcel Apfelbaum 512eb17711bSHadar Hen Zion if (func_cap->flags1 & QUERY_FUNC_CAP_FLAGS1_FORCE_MAC) { 5135cc914f1SMarcel Apfelbaum mlx4_err(dev, "Force mac is enabled on this port\n"); 5145cc914f1SMarcel Apfelbaum err = -EPROTONOSUPPORT; 5155cc914f1SMarcel Apfelbaum goto out; 5165cc914f1SMarcel Apfelbaum } 51747605df9SJack Morgenstein } else if (dev->caps.port_type[gen_or_port] == MLX4_PORT_TYPE_IB) { 51873e74ab4SHadar Hen Zion MLX4_GET(field, outbox, QUERY_FUNC_CAP_FLAGS0_OFFSET); 51973e74ab4SHadar Hen Zion if (field & QUERY_FUNC_CAP_FLAGS0_FORCE_PHY_WQE_GID) { 5201a91de28SJoe Perches mlx4_err(dev, "phy_wqe_gid is enforced on this ib port\n"); 521105c320fSJack Morgenstein err = -EPROTONOSUPPORT; 522105c320fSJack Morgenstein goto out; 523105c320fSJack Morgenstein } 524105c320fSJack Morgenstein } 5255cc914f1SMarcel Apfelbaum 5265cc914f1SMarcel Apfelbaum MLX4_GET(field, outbox, QUERY_FUNC_CAP_PHYS_PORT_OFFSET); 52747605df9SJack Morgenstein func_cap->physical_port = field; 52847605df9SJack Morgenstein if (func_cap->physical_port != gen_or_port) { 52947605df9SJack Morgenstein err = -ENOSYS; 53047605df9SJack Morgenstein goto out; 5315cc914f1SMarcel Apfelbaum } 5325cc914f1SMarcel Apfelbaum 53399ec41d0SJack Morgenstein if (func_cap->flags1 & QUERY_FUNC_CAP_VF_ENABLE_QP0) { 53499ec41d0SJack Morgenstein MLX4_GET(qkey, outbox, QUERY_FUNC_CAP_PRIV_VF_QKEY_OFFSET); 53599ec41d0SJack Morgenstein func_cap->qp0_qkey = qkey; 53699ec41d0SJack Morgenstein } else { 53799ec41d0SJack Morgenstein func_cap->qp0_qkey = 0; 53899ec41d0SJack Morgenstein } 53999ec41d0SJack Morgenstein 54047605df9SJack Morgenstein MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP0_TUNNEL); 54147605df9SJack Morgenstein func_cap->qp0_tunnel_qpn = size & 0xFFFFFF; 54247605df9SJack Morgenstein 54347605df9SJack Morgenstein MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP0_PROXY); 54447605df9SJack Morgenstein func_cap->qp0_proxy_qpn = size & 0xFFFFFF; 54547605df9SJack Morgenstein 54647605df9SJack Morgenstein MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP1_TUNNEL); 54747605df9SJack Morgenstein func_cap->qp1_tunnel_qpn = size & 0xFFFFFF; 54847605df9SJack Morgenstein 54947605df9SJack Morgenstein MLX4_GET(size, outbox, QUERY_FUNC_CAP_QP1_PROXY); 55047605df9SJack Morgenstein func_cap->qp1_proxy_qpn = size & 0xFFFFFF; 55147605df9SJack Morgenstein 5528e1a28e8SHadar Hen Zion if (func_cap->flags1 & QUERY_FUNC_CAP_FLAGS1_NIC_INFO) 5538e1a28e8SHadar Hen Zion MLX4_GET(func_cap->phys_port_id, outbox, 5548e1a28e8SHadar Hen Zion QUERY_FUNC_CAP_PHYS_PORT_ID); 5558e1a28e8SHadar Hen Zion 5565cc914f1SMarcel Apfelbaum /* All other resources are allocated by the master, but we still report 5575cc914f1SMarcel Apfelbaum * 'num' and 'reserved' capabilities as follows: 5585cc914f1SMarcel Apfelbaum * - num remains the maximum resource index 5595cc914f1SMarcel Apfelbaum * - 'num - reserved' is the total available objects of a resource, but 5605cc914f1SMarcel Apfelbaum * resource indices may be less than 'reserved' 5615cc914f1SMarcel Apfelbaum * TODO: set per-resource quotas */ 5625cc914f1SMarcel Apfelbaum 5635cc914f1SMarcel Apfelbaum out: 5645cc914f1SMarcel Apfelbaum mlx4_free_cmd_mailbox(dev, mailbox); 5655cc914f1SMarcel Apfelbaum 5665cc914f1SMarcel Apfelbaum return err; 5675cc914f1SMarcel Apfelbaum } 5685cc914f1SMarcel Apfelbaum 5695a2cc190SJeff Kirsher int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) 5705a2cc190SJeff Kirsher { 5715a2cc190SJeff Kirsher struct mlx4_cmd_mailbox *mailbox; 5725a2cc190SJeff Kirsher u32 *outbox; 5735a2cc190SJeff Kirsher u8 field; 5745a2cc190SJeff Kirsher u32 field32, flags, ext_flags; 5755a2cc190SJeff Kirsher u16 size; 5765a2cc190SJeff Kirsher u16 stat_rate; 5775a2cc190SJeff Kirsher int err; 5785a2cc190SJeff Kirsher int i; 5795a2cc190SJeff Kirsher 5805a2cc190SJeff Kirsher #define QUERY_DEV_CAP_OUT_SIZE 0x100 5815a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_SRQ_SZ_OFFSET 0x10 5825a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_QP_SZ_OFFSET 0x11 5835a2cc190SJeff Kirsher #define QUERY_DEV_CAP_RSVD_QP_OFFSET 0x12 5845a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_QP_OFFSET 0x13 5855a2cc190SJeff Kirsher #define QUERY_DEV_CAP_RSVD_SRQ_OFFSET 0x14 5865a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_SRQ_OFFSET 0x15 5875a2cc190SJeff Kirsher #define QUERY_DEV_CAP_RSVD_EEC_OFFSET 0x16 5885a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_EEC_OFFSET 0x17 5895a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_CQ_SZ_OFFSET 0x19 5905a2cc190SJeff Kirsher #define QUERY_DEV_CAP_RSVD_CQ_OFFSET 0x1a 5915a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_CQ_OFFSET 0x1b 5925a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_MPT_OFFSET 0x1d 5935a2cc190SJeff Kirsher #define QUERY_DEV_CAP_RSVD_EQ_OFFSET 0x1e 5945a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_EQ_OFFSET 0x1f 5955a2cc190SJeff Kirsher #define QUERY_DEV_CAP_RSVD_MTT_OFFSET 0x20 5965a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_MRW_SZ_OFFSET 0x21 5975a2cc190SJeff Kirsher #define QUERY_DEV_CAP_RSVD_MRW_OFFSET 0x22 5985a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_MTT_SEG_OFFSET 0x23 599*7ae0e400SMatan Barak #define QUERY_DEV_CAP_NUM_SYS_EQ_OFFSET 0x26 6005a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_AV_OFFSET 0x27 6015a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_REQ_QP_OFFSET 0x29 6025a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_RES_QP_OFFSET 0x2b 6035a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_GSO_OFFSET 0x2d 604b3416f44SShlomo Pongratz #define QUERY_DEV_CAP_RSS_OFFSET 0x2e 6055a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_RDMA_OFFSET 0x2f 6065a2cc190SJeff Kirsher #define QUERY_DEV_CAP_RSZ_SRQ_OFFSET 0x33 6075a2cc190SJeff Kirsher #define QUERY_DEV_CAP_ACK_DELAY_OFFSET 0x35 6085a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MTU_WIDTH_OFFSET 0x36 6095a2cc190SJeff Kirsher #define QUERY_DEV_CAP_VL_PORT_OFFSET 0x37 6105a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_MSG_SZ_OFFSET 0x38 6115a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_GID_OFFSET 0x3b 6125a2cc190SJeff Kirsher #define QUERY_DEV_CAP_RATE_SUPPORT_OFFSET 0x3c 613d998735fSEugenia Emantayev #define QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET 0x3e 6145a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_PKEY_OFFSET 0x3f 6155a2cc190SJeff Kirsher #define QUERY_DEV_CAP_EXT_FLAGS_OFFSET 0x40 6165a2cc190SJeff Kirsher #define QUERY_DEV_CAP_FLAGS_OFFSET 0x44 6175a2cc190SJeff Kirsher #define QUERY_DEV_CAP_RSVD_UAR_OFFSET 0x48 6185a2cc190SJeff Kirsher #define QUERY_DEV_CAP_UAR_SZ_OFFSET 0x49 6195a2cc190SJeff Kirsher #define QUERY_DEV_CAP_PAGE_SZ_OFFSET 0x4b 6205a2cc190SJeff Kirsher #define QUERY_DEV_CAP_BF_OFFSET 0x4c 6215a2cc190SJeff Kirsher #define QUERY_DEV_CAP_LOG_BF_REG_SZ_OFFSET 0x4d 6225a2cc190SJeff Kirsher #define QUERY_DEV_CAP_LOG_MAX_BF_REGS_PER_PAGE_OFFSET 0x4e 6235a2cc190SJeff Kirsher #define QUERY_DEV_CAP_LOG_MAX_BF_PAGES_OFFSET 0x4f 6245a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_SG_SQ_OFFSET 0x51 6255a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_DESC_SZ_SQ_OFFSET 0x52 6265a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_SG_RQ_OFFSET 0x55 6275a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_DESC_SZ_RQ_OFFSET 0x56 6285a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_QP_MCG_OFFSET 0x61 6295a2cc190SJeff Kirsher #define QUERY_DEV_CAP_RSVD_MCG_OFFSET 0x62 6305a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_MCG_OFFSET 0x63 6315a2cc190SJeff Kirsher #define QUERY_DEV_CAP_RSVD_PD_OFFSET 0x64 6325a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_PD_OFFSET 0x65 633f470f8d4SLinus Torvalds #define QUERY_DEV_CAP_RSVD_XRC_OFFSET 0x66 634f470f8d4SLinus Torvalds #define QUERY_DEV_CAP_MAX_XRC_OFFSET 0x67 6355a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_COUNTERS_OFFSET 0x68 6363f7fb021SRony Efraim #define QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET 0x70 6374de65803SMatan Barak #define QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET 0x74 6380ff1fb65SHadar Hen Zion #define QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET 0x76 6390ff1fb65SHadar Hen Zion #define QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET 0x77 64077507aa2SIdo Shamay #define QUERY_DEV_CAP_CQ_EQ_CACHE_LINE_STRIDE 0x7a 641adbc7ac5SSaeed Mahameed #define QUERY_DEV_CAP_ETH_PROT_CTRL_OFFSET 0x7a 6425a2cc190SJeff Kirsher #define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80 6435a2cc190SJeff Kirsher #define QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET 0x82 6445a2cc190SJeff Kirsher #define QUERY_DEV_CAP_AUX_ENTRY_SZ_OFFSET 0x84 6455a2cc190SJeff Kirsher #define QUERY_DEV_CAP_ALTC_ENTRY_SZ_OFFSET 0x86 6465a2cc190SJeff Kirsher #define QUERY_DEV_CAP_EQC_ENTRY_SZ_OFFSET 0x88 6475a2cc190SJeff Kirsher #define QUERY_DEV_CAP_CQC_ENTRY_SZ_OFFSET 0x8a 6485a2cc190SJeff Kirsher #define QUERY_DEV_CAP_SRQ_ENTRY_SZ_OFFSET 0x8c 6495a2cc190SJeff Kirsher #define QUERY_DEV_CAP_C_MPT_ENTRY_SZ_OFFSET 0x8e 6505a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MTT_ENTRY_SZ_OFFSET 0x90 6515a2cc190SJeff Kirsher #define QUERY_DEV_CAP_D_MPT_ENTRY_SZ_OFFSET 0x92 6525a2cc190SJeff Kirsher #define QUERY_DEV_CAP_BMME_FLAGS_OFFSET 0x94 653d475c95bSMatan Barak #define QUERY_DEV_CAP_CONFIG_DEV_OFFSET 0x94 6545a2cc190SJeff Kirsher #define QUERY_DEV_CAP_RSVD_LKEY_OFFSET 0x98 6555a2cc190SJeff Kirsher #define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET 0xa0 656a53e3e8cSSaeed Mahameed #define QUERY_DEV_CAP_ETH_BACKPL_OFFSET 0x9c 657955154faSMatan Barak #define QUERY_DEV_CAP_FW_REASSIGN_MAC 0x9d 6587ffdf726SOr Gerlitz #define QUERY_DEV_CAP_VXLAN 0x9e 659114840c3SJack Morgenstein #define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0 6605a2cc190SJeff Kirsher 661b3416f44SShlomo Pongratz dev_cap->flags2 = 0; 6625a2cc190SJeff Kirsher mailbox = mlx4_alloc_cmd_mailbox(dev); 6635a2cc190SJeff Kirsher if (IS_ERR(mailbox)) 6645a2cc190SJeff Kirsher return PTR_ERR(mailbox); 6655a2cc190SJeff Kirsher outbox = mailbox->buf; 6665a2cc190SJeff Kirsher 6675a2cc190SJeff Kirsher err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP, 668401453a3SJack Morgenstein MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 6695a2cc190SJeff Kirsher if (err) 6705a2cc190SJeff Kirsher goto out; 6715a2cc190SJeff Kirsher 6725a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_QP_OFFSET); 6735a2cc190SJeff Kirsher dev_cap->reserved_qps = 1 << (field & 0xf); 6745a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_QP_OFFSET); 6755a2cc190SJeff Kirsher dev_cap->max_qps = 1 << (field & 0x1f); 6765a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_SRQ_OFFSET); 6775a2cc190SJeff Kirsher dev_cap->reserved_srqs = 1 << (field >> 4); 6785a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_SRQ_OFFSET); 6795a2cc190SJeff Kirsher dev_cap->max_srqs = 1 << (field & 0x1f); 6805a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_CQ_SZ_OFFSET); 6815a2cc190SJeff Kirsher dev_cap->max_cq_sz = 1 << field; 6825a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_CQ_OFFSET); 6835a2cc190SJeff Kirsher dev_cap->reserved_cqs = 1 << (field & 0xf); 6845a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_CQ_OFFSET); 6855a2cc190SJeff Kirsher dev_cap->max_cqs = 1 << (field & 0x1f); 6865a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MPT_OFFSET); 6875a2cc190SJeff Kirsher dev_cap->max_mpts = 1 << (field & 0x3f); 6885a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_EQ_OFFSET); 6897c68dd43SMatan Barak dev_cap->reserved_eqs = 1 << (field & 0xf); 6905a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_EQ_OFFSET); 6915a2cc190SJeff Kirsher dev_cap->max_eqs = 1 << (field & 0xf); 6925a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_MTT_OFFSET); 6935a2cc190SJeff Kirsher dev_cap->reserved_mtts = 1 << (field >> 4); 6945a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MRW_SZ_OFFSET); 6955a2cc190SJeff Kirsher dev_cap->max_mrw_sz = 1 << field; 6965a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_MRW_OFFSET); 6975a2cc190SJeff Kirsher dev_cap->reserved_mrws = 1 << (field & 0xf); 6985a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MTT_SEG_OFFSET); 6995a2cc190SJeff Kirsher dev_cap->max_mtt_seg = 1 << (field & 0x3f); 700*7ae0e400SMatan Barak MLX4_GET(size, outbox, QUERY_DEV_CAP_NUM_SYS_EQ_OFFSET); 701*7ae0e400SMatan Barak dev_cap->num_sys_eqs = size & 0xfff; 7025a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_REQ_QP_OFFSET); 7035a2cc190SJeff Kirsher dev_cap->max_requester_per_qp = 1 << (field & 0x3f); 7045a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_RES_QP_OFFSET); 7055a2cc190SJeff Kirsher dev_cap->max_responder_per_qp = 1 << (field & 0x3f); 7065a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_GSO_OFFSET); 7075a2cc190SJeff Kirsher field &= 0x1f; 7085a2cc190SJeff Kirsher if (!field) 7095a2cc190SJeff Kirsher dev_cap->max_gso_sz = 0; 7105a2cc190SJeff Kirsher else 7115a2cc190SJeff Kirsher dev_cap->max_gso_sz = 1 << field; 7125a2cc190SJeff Kirsher 713b3416f44SShlomo Pongratz MLX4_GET(field, outbox, QUERY_DEV_CAP_RSS_OFFSET); 714b3416f44SShlomo Pongratz if (field & 0x20) 715b3416f44SShlomo Pongratz dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RSS_XOR; 716b3416f44SShlomo Pongratz if (field & 0x10) 717b3416f44SShlomo Pongratz dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RSS_TOP; 718b3416f44SShlomo Pongratz field &= 0xf; 719b3416f44SShlomo Pongratz if (field) { 720b3416f44SShlomo Pongratz dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_RSS; 721b3416f44SShlomo Pongratz dev_cap->max_rss_tbl_sz = 1 << field; 722b3416f44SShlomo Pongratz } else 723b3416f44SShlomo Pongratz dev_cap->max_rss_tbl_sz = 0; 7245a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_RDMA_OFFSET); 7255a2cc190SJeff Kirsher dev_cap->max_rdma_global = 1 << (field & 0x3f); 7265a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_ACK_DELAY_OFFSET); 7275a2cc190SJeff Kirsher dev_cap->local_ca_ack_delay = field & 0x1f; 7285a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET); 7295a2cc190SJeff Kirsher dev_cap->num_ports = field & 0xf; 7305a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MSG_SZ_OFFSET); 7315a2cc190SJeff Kirsher dev_cap->max_msg_sz = 1 << (field & 0x1f); 7320ff1fb65SHadar Hen Zion MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET); 7330ff1fb65SHadar Hen Zion if (field & 0x80) 7340ff1fb65SHadar Hen Zion dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_FS_EN; 7350ff1fb65SHadar Hen Zion dev_cap->fs_log_max_ucast_qp_range_size = field & 0x1f; 7364de65803SMatan Barak MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET); 7374de65803SMatan Barak if (field & 0x80) 7384de65803SMatan Barak dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_DMFS_IPOIB; 7390ff1fb65SHadar Hen Zion MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_MAX_QP_OFFSET); 7400ff1fb65SHadar Hen Zion dev_cap->fs_max_num_qp_per_entry = field; 7415a2cc190SJeff Kirsher MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET); 7425a2cc190SJeff Kirsher dev_cap->stat_rate_support = stat_rate; 743d998735fSEugenia Emantayev MLX4_GET(field, outbox, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET); 744d998735fSEugenia Emantayev if (field & 0x80) 745d998735fSEugenia Emantayev dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_TS; 7465a2cc190SJeff Kirsher MLX4_GET(ext_flags, outbox, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); 7475a2cc190SJeff Kirsher MLX4_GET(flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET); 7485a2cc190SJeff Kirsher dev_cap->flags = flags | (u64)ext_flags << 32; 7495a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET); 7505a2cc190SJeff Kirsher dev_cap->reserved_uars = field >> 4; 7515a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_UAR_SZ_OFFSET); 7525a2cc190SJeff Kirsher dev_cap->uar_size = 1 << ((field & 0x3f) + 20); 7535a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_PAGE_SZ_OFFSET); 7545a2cc190SJeff Kirsher dev_cap->min_page_sz = 1 << field; 7555a2cc190SJeff Kirsher 7565a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_BF_OFFSET); 7575a2cc190SJeff Kirsher if (field & 0x80) { 7585a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_LOG_BF_REG_SZ_OFFSET); 7595a2cc190SJeff Kirsher dev_cap->bf_reg_size = 1 << (field & 0x1f); 7605a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_LOG_MAX_BF_REGS_PER_PAGE_OFFSET); 7615a2cc190SJeff Kirsher if ((1 << (field & 0x3f)) > (PAGE_SIZE / dev_cap->bf_reg_size)) 7625a2cc190SJeff Kirsher field = 3; 7635a2cc190SJeff Kirsher dev_cap->bf_regs_per_page = 1 << (field & 0x3f); 7645a2cc190SJeff Kirsher mlx4_dbg(dev, "BlueFlame available (reg size %d, regs/page %d)\n", 7655a2cc190SJeff Kirsher dev_cap->bf_reg_size, dev_cap->bf_regs_per_page); 7665a2cc190SJeff Kirsher } else { 7675a2cc190SJeff Kirsher dev_cap->bf_reg_size = 0; 7685a2cc190SJeff Kirsher mlx4_dbg(dev, "BlueFlame not available\n"); 7695a2cc190SJeff Kirsher } 7705a2cc190SJeff Kirsher 7715a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_SG_SQ_OFFSET); 7725a2cc190SJeff Kirsher dev_cap->max_sq_sg = field; 7735a2cc190SJeff Kirsher MLX4_GET(size, outbox, QUERY_DEV_CAP_MAX_DESC_SZ_SQ_OFFSET); 7745a2cc190SJeff Kirsher dev_cap->max_sq_desc_sz = size; 7755a2cc190SJeff Kirsher 7765a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_QP_MCG_OFFSET); 7775a2cc190SJeff Kirsher dev_cap->max_qp_per_mcg = 1 << field; 7785a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_MCG_OFFSET); 7795a2cc190SJeff Kirsher dev_cap->reserved_mgms = field & 0xf; 7805a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_MCG_OFFSET); 7815a2cc190SJeff Kirsher dev_cap->max_mcgs = 1 << field; 7825a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_PD_OFFSET); 7835a2cc190SJeff Kirsher dev_cap->reserved_pds = field >> 4; 7845a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_PD_OFFSET); 7855a2cc190SJeff Kirsher dev_cap->max_pds = 1 << (field & 0x3f); 786f470f8d4SLinus Torvalds MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_XRC_OFFSET); 787f470f8d4SLinus Torvalds dev_cap->reserved_xrcds = field >> 4; 788426dd00dSDotan Barak MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_XRC_OFFSET); 789f470f8d4SLinus Torvalds dev_cap->max_xrcds = 1 << (field & 0x1f); 7905a2cc190SJeff Kirsher 7915a2cc190SJeff Kirsher MLX4_GET(size, outbox, QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET); 7925a2cc190SJeff Kirsher dev_cap->rdmarc_entry_sz = size; 7935a2cc190SJeff Kirsher MLX4_GET(size, outbox, QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET); 7945a2cc190SJeff Kirsher dev_cap->qpc_entry_sz = size; 7955a2cc190SJeff Kirsher MLX4_GET(size, outbox, QUERY_DEV_CAP_AUX_ENTRY_SZ_OFFSET); 7965a2cc190SJeff Kirsher dev_cap->aux_entry_sz = size; 7975a2cc190SJeff Kirsher MLX4_GET(size, outbox, QUERY_DEV_CAP_ALTC_ENTRY_SZ_OFFSET); 7985a2cc190SJeff Kirsher dev_cap->altc_entry_sz = size; 7995a2cc190SJeff Kirsher MLX4_GET(size, outbox, QUERY_DEV_CAP_EQC_ENTRY_SZ_OFFSET); 8005a2cc190SJeff Kirsher dev_cap->eqc_entry_sz = size; 8015a2cc190SJeff Kirsher MLX4_GET(size, outbox, QUERY_DEV_CAP_CQC_ENTRY_SZ_OFFSET); 8025a2cc190SJeff Kirsher dev_cap->cqc_entry_sz = size; 8035a2cc190SJeff Kirsher MLX4_GET(size, outbox, QUERY_DEV_CAP_SRQ_ENTRY_SZ_OFFSET); 8045a2cc190SJeff Kirsher dev_cap->srq_entry_sz = size; 8055a2cc190SJeff Kirsher MLX4_GET(size, outbox, QUERY_DEV_CAP_C_MPT_ENTRY_SZ_OFFSET); 8065a2cc190SJeff Kirsher dev_cap->cmpt_entry_sz = size; 8075a2cc190SJeff Kirsher MLX4_GET(size, outbox, QUERY_DEV_CAP_MTT_ENTRY_SZ_OFFSET); 8085a2cc190SJeff Kirsher dev_cap->mtt_entry_sz = size; 8095a2cc190SJeff Kirsher MLX4_GET(size, outbox, QUERY_DEV_CAP_D_MPT_ENTRY_SZ_OFFSET); 8105a2cc190SJeff Kirsher dev_cap->dmpt_entry_sz = size; 8115a2cc190SJeff Kirsher 8125a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_SRQ_SZ_OFFSET); 8135a2cc190SJeff Kirsher dev_cap->max_srq_sz = 1 << field; 8145a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_QP_SZ_OFFSET); 8155a2cc190SJeff Kirsher dev_cap->max_qp_sz = 1 << field; 8165a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_RSZ_SRQ_OFFSET); 8175a2cc190SJeff Kirsher dev_cap->resize_srq = field & 1; 8185a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_SG_RQ_OFFSET); 8195a2cc190SJeff Kirsher dev_cap->max_rq_sg = field; 8205a2cc190SJeff Kirsher MLX4_GET(size, outbox, QUERY_DEV_CAP_MAX_DESC_SZ_RQ_OFFSET); 8215a2cc190SJeff Kirsher dev_cap->max_rq_desc_sz = size; 82277507aa2SIdo Shamay MLX4_GET(field, outbox, QUERY_DEV_CAP_CQ_EQ_CACHE_LINE_STRIDE); 823adbc7ac5SSaeed Mahameed if (field & (1 << 5)) 824adbc7ac5SSaeed Mahameed dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL; 82577507aa2SIdo Shamay if (field & (1 << 6)) 82677507aa2SIdo Shamay dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_CQE_STRIDE; 82777507aa2SIdo Shamay if (field & (1 << 7)) 82877507aa2SIdo Shamay dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_EQE_STRIDE; 8295a2cc190SJeff Kirsher MLX4_GET(dev_cap->bmme_flags, outbox, 8305a2cc190SJeff Kirsher QUERY_DEV_CAP_BMME_FLAGS_OFFSET); 831d475c95bSMatan Barak MLX4_GET(field, outbox, QUERY_DEV_CAP_CONFIG_DEV_OFFSET); 832d475c95bSMatan Barak if (field & 0x20) 833d475c95bSMatan Barak dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_CONFIG_DEV; 8345a2cc190SJeff Kirsher MLX4_GET(dev_cap->reserved_lkey, outbox, 8355a2cc190SJeff Kirsher QUERY_DEV_CAP_RSVD_LKEY_OFFSET); 836a53e3e8cSSaeed Mahameed MLX4_GET(field32, outbox, QUERY_DEV_CAP_ETH_BACKPL_OFFSET); 837a53e3e8cSSaeed Mahameed if (field32 & (1 << 0)) 838a53e3e8cSSaeed Mahameed dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP; 839955154faSMatan Barak MLX4_GET(field, outbox, QUERY_DEV_CAP_FW_REASSIGN_MAC); 840955154faSMatan Barak if (field & 1<<6) 8415930e8d0SOr Gerlitz dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_REASSIGN_MAC_EN; 8427ffdf726SOr Gerlitz MLX4_GET(field, outbox, QUERY_DEV_CAP_VXLAN); 8437ffdf726SOr Gerlitz if (field & 1<<3) 8447ffdf726SOr Gerlitz dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS; 8455a2cc190SJeff Kirsher MLX4_GET(dev_cap->max_icm_sz, outbox, 8465a2cc190SJeff Kirsher QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET); 8475a2cc190SJeff Kirsher if (dev_cap->flags & MLX4_DEV_CAP_FLAG_COUNTERS) 8485a2cc190SJeff Kirsher MLX4_GET(dev_cap->max_counters, outbox, 8495a2cc190SJeff Kirsher QUERY_DEV_CAP_MAX_COUNTERS_OFFSET); 8505a2cc190SJeff Kirsher 851114840c3SJack Morgenstein MLX4_GET(field32, outbox, 852114840c3SJack Morgenstein QUERY_DEV_CAP_MAD_DEMUX_OFFSET); 853114840c3SJack Morgenstein if (field32 & (1 << 0)) 854114840c3SJack Morgenstein dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_MAD_DEMUX; 855114840c3SJack Morgenstein 8563f7fb021SRony Efraim MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); 857b01978caSJack Morgenstein if (field32 & (1 << 16)) 858b01978caSJack Morgenstein dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP; 8593f7fb021SRony Efraim if (field32 & (1 << 26)) 8603f7fb021SRony Efraim dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_VLAN_CONTROL; 861e6b6a231SRony Efraim if (field32 & (1 << 20)) 862e6b6a231SRony Efraim dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_FSM; 8633f7fb021SRony Efraim 8645a2cc190SJeff Kirsher if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { 8655a2cc190SJeff Kirsher for (i = 1; i <= dev_cap->num_ports; ++i) { 8665a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_VL_PORT_OFFSET); 8675a2cc190SJeff Kirsher dev_cap->max_vl[i] = field >> 4; 8685a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MTU_WIDTH_OFFSET); 8695a2cc190SJeff Kirsher dev_cap->ib_mtu[i] = field >> 4; 8705a2cc190SJeff Kirsher dev_cap->max_port_width[i] = field & 0xf; 8715a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_GID_OFFSET); 8725a2cc190SJeff Kirsher dev_cap->max_gids[i] = 1 << (field & 0xf); 8735a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_PKEY_OFFSET); 8745a2cc190SJeff Kirsher dev_cap->max_pkeys[i] = 1 << (field & 0xf); 8755a2cc190SJeff Kirsher } 8765a2cc190SJeff Kirsher } else { 8775a2cc190SJeff Kirsher #define QUERY_PORT_SUPPORTED_TYPE_OFFSET 0x00 8785a2cc190SJeff Kirsher #define QUERY_PORT_MTU_OFFSET 0x01 8795a2cc190SJeff Kirsher #define QUERY_PORT_ETH_MTU_OFFSET 0x02 8805a2cc190SJeff Kirsher #define QUERY_PORT_WIDTH_OFFSET 0x06 8815a2cc190SJeff Kirsher #define QUERY_PORT_MAX_GID_PKEY_OFFSET 0x07 8825a2cc190SJeff Kirsher #define QUERY_PORT_MAX_MACVLAN_OFFSET 0x0a 8835a2cc190SJeff Kirsher #define QUERY_PORT_MAX_VL_OFFSET 0x0b 8845a2cc190SJeff Kirsher #define QUERY_PORT_MAC_OFFSET 0x10 8855a2cc190SJeff Kirsher #define QUERY_PORT_TRANS_VENDOR_OFFSET 0x18 8865a2cc190SJeff Kirsher #define QUERY_PORT_WAVELENGTH_OFFSET 0x1c 8875a2cc190SJeff Kirsher #define QUERY_PORT_TRANS_CODE_OFFSET 0x20 8885a2cc190SJeff Kirsher 8895a2cc190SJeff Kirsher for (i = 1; i <= dev_cap->num_ports; ++i) { 8905a2cc190SJeff Kirsher err = mlx4_cmd_box(dev, 0, mailbox->dma, i, 0, MLX4_CMD_QUERY_PORT, 891401453a3SJack Morgenstein MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 8925a2cc190SJeff Kirsher if (err) 8935a2cc190SJeff Kirsher goto out; 8945a2cc190SJeff Kirsher 8955a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_PORT_SUPPORTED_TYPE_OFFSET); 8965a2cc190SJeff Kirsher dev_cap->supported_port_types[i] = field & 3; 8978d0fc7b6SYevgeny Petrilin dev_cap->suggested_type[i] = (field >> 3) & 1; 8988d0fc7b6SYevgeny Petrilin dev_cap->default_sense[i] = (field >> 4) & 1; 8995a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_PORT_MTU_OFFSET); 9005a2cc190SJeff Kirsher dev_cap->ib_mtu[i] = field & 0xf; 9015a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_PORT_WIDTH_OFFSET); 9025a2cc190SJeff Kirsher dev_cap->max_port_width[i] = field & 0xf; 9035a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_PORT_MAX_GID_PKEY_OFFSET); 9045a2cc190SJeff Kirsher dev_cap->max_gids[i] = 1 << (field >> 4); 9055a2cc190SJeff Kirsher dev_cap->max_pkeys[i] = 1 << (field & 0xf); 9065a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_PORT_MAX_VL_OFFSET); 9075a2cc190SJeff Kirsher dev_cap->max_vl[i] = field & 0xf; 9085a2cc190SJeff Kirsher MLX4_GET(field, outbox, QUERY_PORT_MAX_MACVLAN_OFFSET); 9095a2cc190SJeff Kirsher dev_cap->log_max_macs[i] = field & 0xf; 9105a2cc190SJeff Kirsher dev_cap->log_max_vlans[i] = field >> 4; 9115a2cc190SJeff Kirsher MLX4_GET(dev_cap->eth_mtu[i], outbox, QUERY_PORT_ETH_MTU_OFFSET); 9125a2cc190SJeff Kirsher MLX4_GET(dev_cap->def_mac[i], outbox, QUERY_PORT_MAC_OFFSET); 9135a2cc190SJeff Kirsher MLX4_GET(field32, outbox, QUERY_PORT_TRANS_VENDOR_OFFSET); 9145a2cc190SJeff Kirsher dev_cap->trans_type[i] = field32 >> 24; 9155a2cc190SJeff Kirsher dev_cap->vendor_oui[i] = field32 & 0xffffff; 9165a2cc190SJeff Kirsher MLX4_GET(dev_cap->wavelength[i], outbox, QUERY_PORT_WAVELENGTH_OFFSET); 9175a2cc190SJeff Kirsher MLX4_GET(dev_cap->trans_code[i], outbox, QUERY_PORT_TRANS_CODE_OFFSET); 9185a2cc190SJeff Kirsher } 9195a2cc190SJeff Kirsher } 9205a2cc190SJeff Kirsher 9215a2cc190SJeff Kirsher mlx4_dbg(dev, "Base MM extensions: flags %08x, rsvd L_Key %08x\n", 9225a2cc190SJeff Kirsher dev_cap->bmme_flags, dev_cap->reserved_lkey); 9235a2cc190SJeff Kirsher 9245a2cc190SJeff Kirsher /* 9255a2cc190SJeff Kirsher * Each UAR has 4 EQ doorbells; so if a UAR is reserved, then 9265a2cc190SJeff Kirsher * we can't use any EQs whose doorbell falls on that page, 9275a2cc190SJeff Kirsher * even if the EQ itself isn't reserved. 9285a2cc190SJeff Kirsher */ 929*7ae0e400SMatan Barak if (dev_cap->num_sys_eqs == 0) 9305a2cc190SJeff Kirsher dev_cap->reserved_eqs = max(dev_cap->reserved_uars * 4, 9315a2cc190SJeff Kirsher dev_cap->reserved_eqs); 932*7ae0e400SMatan Barak else 933*7ae0e400SMatan Barak dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_SYS_EQS; 9345a2cc190SJeff Kirsher 9355a2cc190SJeff Kirsher mlx4_dbg(dev, "Max ICM size %lld MB\n", 9365a2cc190SJeff Kirsher (unsigned long long) dev_cap->max_icm_sz >> 20); 9375a2cc190SJeff Kirsher mlx4_dbg(dev, "Max QPs: %d, reserved QPs: %d, entry size: %d\n", 9385a2cc190SJeff Kirsher dev_cap->max_qps, dev_cap->reserved_qps, dev_cap->qpc_entry_sz); 9395a2cc190SJeff Kirsher mlx4_dbg(dev, "Max SRQs: %d, reserved SRQs: %d, entry size: %d\n", 9405a2cc190SJeff Kirsher dev_cap->max_srqs, dev_cap->reserved_srqs, dev_cap->srq_entry_sz); 9415a2cc190SJeff Kirsher mlx4_dbg(dev, "Max CQs: %d, reserved CQs: %d, entry size: %d\n", 9425a2cc190SJeff Kirsher dev_cap->max_cqs, dev_cap->reserved_cqs, dev_cap->cqc_entry_sz); 943*7ae0e400SMatan Barak mlx4_dbg(dev, "Num sys EQs: %d, max EQs: %d, reserved EQs: %d, entry size: %d\n", 944*7ae0e400SMatan Barak dev_cap->num_sys_eqs, dev_cap->max_eqs, dev_cap->reserved_eqs, 945*7ae0e400SMatan Barak dev_cap->eqc_entry_sz); 9465a2cc190SJeff Kirsher mlx4_dbg(dev, "reserved MPTs: %d, reserved MTTs: %d\n", 9475a2cc190SJeff Kirsher dev_cap->reserved_mrws, dev_cap->reserved_mtts); 9485a2cc190SJeff Kirsher mlx4_dbg(dev, "Max PDs: %d, reserved PDs: %d, reserved UARs: %d\n", 9495a2cc190SJeff Kirsher dev_cap->max_pds, dev_cap->reserved_pds, dev_cap->reserved_uars); 9505a2cc190SJeff Kirsher mlx4_dbg(dev, "Max QP/MCG: %d, reserved MGMs: %d\n", 9515a2cc190SJeff Kirsher dev_cap->max_pds, dev_cap->reserved_mgms); 9525a2cc190SJeff Kirsher mlx4_dbg(dev, "Max CQEs: %d, max WQEs: %d, max SRQ WQEs: %d\n", 9535a2cc190SJeff Kirsher dev_cap->max_cq_sz, dev_cap->max_qp_sz, dev_cap->max_srq_sz); 9545a2cc190SJeff Kirsher mlx4_dbg(dev, "Local CA ACK delay: %d, max MTU: %d, port width cap: %d\n", 9555a2cc190SJeff Kirsher dev_cap->local_ca_ack_delay, 128 << dev_cap->ib_mtu[1], 9565a2cc190SJeff Kirsher dev_cap->max_port_width[1]); 9575a2cc190SJeff Kirsher mlx4_dbg(dev, "Max SQ desc size: %d, max SQ S/G: %d\n", 9585a2cc190SJeff Kirsher dev_cap->max_sq_desc_sz, dev_cap->max_sq_sg); 9595a2cc190SJeff Kirsher mlx4_dbg(dev, "Max RQ desc size: %d, max RQ S/G: %d\n", 9605a2cc190SJeff Kirsher dev_cap->max_rq_desc_sz, dev_cap->max_rq_sg); 9615a2cc190SJeff Kirsher mlx4_dbg(dev, "Max GSO size: %d\n", dev_cap->max_gso_sz); 9625a2cc190SJeff Kirsher mlx4_dbg(dev, "Max counters: %d\n", dev_cap->max_counters); 963b3416f44SShlomo Pongratz mlx4_dbg(dev, "Max RSS Table size: %d\n", dev_cap->max_rss_tbl_sz); 9645a2cc190SJeff Kirsher 9655a2cc190SJeff Kirsher dump_dev_cap_flags(dev, dev_cap->flags); 966b3416f44SShlomo Pongratz dump_dev_cap_flags2(dev, dev_cap->flags2); 9675a2cc190SJeff Kirsher 9685a2cc190SJeff Kirsher out: 9695a2cc190SJeff Kirsher mlx4_free_cmd_mailbox(dev, mailbox); 9705a2cc190SJeff Kirsher return err; 9715a2cc190SJeff Kirsher } 9725a2cc190SJeff Kirsher 973b91cb3ebSJack Morgenstein int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, 974b91cb3ebSJack Morgenstein struct mlx4_vhcr *vhcr, 975b91cb3ebSJack Morgenstein struct mlx4_cmd_mailbox *inbox, 976b91cb3ebSJack Morgenstein struct mlx4_cmd_mailbox *outbox, 977b91cb3ebSJack Morgenstein struct mlx4_cmd_info *cmd) 978b91cb3ebSJack Morgenstein { 9792a4fae14SJack Morgenstein u64 flags; 980b91cb3ebSJack Morgenstein int err = 0; 981b91cb3ebSJack Morgenstein u8 field; 982cc1ade94SShani Michaeli u32 bmme_flags; 983449fc488SMatan Barak int real_port; 984449fc488SMatan Barak int slave_port; 985449fc488SMatan Barak int first_port; 986449fc488SMatan Barak struct mlx4_active_ports actv_ports; 987b91cb3ebSJack Morgenstein 988b91cb3ebSJack Morgenstein err = mlx4_cmd_box(dev, 0, outbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP, 989b91cb3ebSJack Morgenstein MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 990b91cb3ebSJack Morgenstein if (err) 991b91cb3ebSJack Morgenstein return err; 992b91cb3ebSJack Morgenstein 993cc1ade94SShani Michaeli /* add port mng change event capability and disable mw type 1 994cc1ade94SShani Michaeli * unconditionally to slaves 995cc1ade94SShani Michaeli */ 9962a4fae14SJack Morgenstein MLX4_GET(flags, outbox->buf, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); 9972a4fae14SJack Morgenstein flags |= MLX4_DEV_CAP_FLAG_PORT_MNG_CHG_EV; 998cc1ade94SShani Michaeli flags &= ~MLX4_DEV_CAP_FLAG_MEM_WINDOW; 999449fc488SMatan Barak actv_ports = mlx4_get_active_ports(dev, slave); 1000449fc488SMatan Barak first_port = find_first_bit(actv_ports.ports, dev->caps.num_ports); 1001449fc488SMatan Barak for (slave_port = 0, real_port = first_port; 1002449fc488SMatan Barak real_port < first_port + 1003449fc488SMatan Barak bitmap_weight(actv_ports.ports, dev->caps.num_ports); 1004449fc488SMatan Barak ++real_port, ++slave_port) { 1005449fc488SMatan Barak if (flags & (MLX4_DEV_CAP_FLAG_WOL_PORT1 << real_port)) 1006449fc488SMatan Barak flags |= MLX4_DEV_CAP_FLAG_WOL_PORT1 << slave_port; 1007449fc488SMatan Barak else 1008449fc488SMatan Barak flags &= ~(MLX4_DEV_CAP_FLAG_WOL_PORT1 << slave_port); 1009449fc488SMatan Barak } 1010449fc488SMatan Barak for (; slave_port < dev->caps.num_ports; ++slave_port) 1011449fc488SMatan Barak flags &= ~(MLX4_DEV_CAP_FLAG_WOL_PORT1 << slave_port); 10122a4fae14SJack Morgenstein MLX4_PUT(outbox->buf, flags, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); 10132a4fae14SJack Morgenstein 1014449fc488SMatan Barak MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_VL_PORT_OFFSET); 1015449fc488SMatan Barak field &= ~0x0F; 1016449fc488SMatan Barak field |= bitmap_weight(actv_ports.ports, dev->caps.num_ports) & 0x0F; 1017449fc488SMatan Barak MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_VL_PORT_OFFSET); 1018449fc488SMatan Barak 101930b40c31SAmir Vadai /* For guests, disable timestamp */ 102030b40c31SAmir Vadai MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET); 102130b40c31SAmir Vadai field &= 0x7f; 102230b40c31SAmir Vadai MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET); 102330b40c31SAmir Vadai 10247ffdf726SOr Gerlitz /* For guests, disable vxlan tunneling */ 102557352ef4SAmir Vadai MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_VXLAN); 10267ffdf726SOr Gerlitz field &= 0xf7; 10277ffdf726SOr Gerlitz MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_VXLAN); 10287ffdf726SOr Gerlitz 1029b91cb3ebSJack Morgenstein /* For guests, report Blueflame disabled */ 1030b91cb3ebSJack Morgenstein MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_BF_OFFSET); 1031b91cb3ebSJack Morgenstein field &= 0x7f; 1032b91cb3ebSJack Morgenstein MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_BF_OFFSET); 1033b91cb3ebSJack Morgenstein 1034cc1ade94SShani Michaeli /* For guests, disable mw type 2 */ 103557352ef4SAmir Vadai MLX4_GET(bmme_flags, outbox->buf, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); 1036cc1ade94SShani Michaeli bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN; 1037cc1ade94SShani Michaeli MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); 1038cc1ade94SShani Michaeli 10390081c8f3SJack Morgenstein /* turn off device-managed steering capability if not enabled */ 10400081c8f3SJack Morgenstein if (dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) { 10410081c8f3SJack Morgenstein MLX4_GET(field, outbox->buf, 10420081c8f3SJack Morgenstein QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET); 10430081c8f3SJack Morgenstein field &= 0x7f; 10440081c8f3SJack Morgenstein MLX4_PUT(outbox->buf, field, 10450081c8f3SJack Morgenstein QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET); 10460081c8f3SJack Morgenstein } 10474de65803SMatan Barak 10484de65803SMatan Barak /* turn off ipoib managed steering for guests */ 104957352ef4SAmir Vadai MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET); 10504de65803SMatan Barak field &= ~0x80; 10514de65803SMatan Barak MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET); 10524de65803SMatan Barak 1053b91cb3ebSJack Morgenstein return 0; 1054b91cb3ebSJack Morgenstein } 1055b91cb3ebSJack Morgenstein 10565cc914f1SMarcel Apfelbaum int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, 10575cc914f1SMarcel Apfelbaum struct mlx4_vhcr *vhcr, 10585cc914f1SMarcel Apfelbaum struct mlx4_cmd_mailbox *inbox, 10595cc914f1SMarcel Apfelbaum struct mlx4_cmd_mailbox *outbox, 10605cc914f1SMarcel Apfelbaum struct mlx4_cmd_info *cmd) 10615cc914f1SMarcel Apfelbaum { 10620eb62b93SRony Efraim struct mlx4_priv *priv = mlx4_priv(dev); 10635cc914f1SMarcel Apfelbaum u64 def_mac; 10645cc914f1SMarcel Apfelbaum u8 port_type; 10656634961cSJack Morgenstein u16 short_field; 10665cc914f1SMarcel Apfelbaum int err; 1067948e306dSRony Efraim int admin_link_state; 1068449fc488SMatan Barak int port = mlx4_slave_convert_port(dev, slave, 1069449fc488SMatan Barak vhcr->in_modifier & 0xFF); 10705cc914f1SMarcel Apfelbaum 1071105c320fSJack Morgenstein #define MLX4_VF_PORT_NO_LINK_SENSE_MASK 0xE0 1072948e306dSRony Efraim #define MLX4_PORT_LINK_UP_MASK 0x80 10736634961cSJack Morgenstein #define QUERY_PORT_CUR_MAX_PKEY_OFFSET 0x0c 10746634961cSJack Morgenstein #define QUERY_PORT_CUR_MAX_GID_OFFSET 0x0e 107595f56e7aSYevgeny Petrilin 1076449fc488SMatan Barak if (port < 0) 1077449fc488SMatan Barak return -EINVAL; 1078449fc488SMatan Barak 1079a7401b9cSJack Morgenstein /* Protect against untrusted guests: enforce that this is the 1080a7401b9cSJack Morgenstein * QUERY_PORT general query. 1081a7401b9cSJack Morgenstein */ 1082a7401b9cSJack Morgenstein if (vhcr->op_modifier || vhcr->in_modifier & ~0xFF) 1083a7401b9cSJack Morgenstein return -EINVAL; 1084a7401b9cSJack Morgenstein 1085a7401b9cSJack Morgenstein vhcr->in_modifier = port; 1086449fc488SMatan Barak 10875cc914f1SMarcel Apfelbaum err = mlx4_cmd_box(dev, 0, outbox->dma, vhcr->in_modifier, 0, 10885cc914f1SMarcel Apfelbaum MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B, 10895cc914f1SMarcel Apfelbaum MLX4_CMD_NATIVE); 10905cc914f1SMarcel Apfelbaum 10915cc914f1SMarcel Apfelbaum if (!err && dev->caps.function != slave) { 10920eb62b93SRony Efraim def_mac = priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.mac; 10935cc914f1SMarcel Apfelbaum MLX4_PUT(outbox->buf, def_mac, QUERY_PORT_MAC_OFFSET); 10945cc914f1SMarcel Apfelbaum 10955cc914f1SMarcel Apfelbaum /* get port type - currently only eth is enabled */ 10965cc914f1SMarcel Apfelbaum MLX4_GET(port_type, outbox->buf, 10975cc914f1SMarcel Apfelbaum QUERY_PORT_SUPPORTED_TYPE_OFFSET); 10985cc914f1SMarcel Apfelbaum 1099105c320fSJack Morgenstein /* No link sensing allowed */ 1100105c320fSJack Morgenstein port_type &= MLX4_VF_PORT_NO_LINK_SENSE_MASK; 1101105c320fSJack Morgenstein /* set port type to currently operating port type */ 1102105c320fSJack Morgenstein port_type |= (dev->caps.port_type[vhcr->in_modifier] & 0x3); 11035cc914f1SMarcel Apfelbaum 1104948e306dSRony Efraim admin_link_state = priv->mfunc.master.vf_oper[slave].vport[vhcr->in_modifier].state.link_state; 1105948e306dSRony Efraim if (IFLA_VF_LINK_STATE_ENABLE == admin_link_state) 1106948e306dSRony Efraim port_type |= MLX4_PORT_LINK_UP_MASK; 1107948e306dSRony Efraim else if (IFLA_VF_LINK_STATE_DISABLE == admin_link_state) 1108948e306dSRony Efraim port_type &= ~MLX4_PORT_LINK_UP_MASK; 1109948e306dSRony Efraim 11105cc914f1SMarcel Apfelbaum MLX4_PUT(outbox->buf, port_type, 11115cc914f1SMarcel Apfelbaum QUERY_PORT_SUPPORTED_TYPE_OFFSET); 11126634961cSJack Morgenstein 1113b6ffaeffSJack Morgenstein if (dev->caps.port_type[vhcr->in_modifier] == MLX4_PORT_TYPE_ETH) 1114449fc488SMatan Barak short_field = mlx4_get_slave_num_gids(dev, slave, port); 1115b6ffaeffSJack Morgenstein else 11166634961cSJack Morgenstein short_field = 1; /* slave max gids */ 11176634961cSJack Morgenstein MLX4_PUT(outbox->buf, short_field, 11186634961cSJack Morgenstein QUERY_PORT_CUR_MAX_GID_OFFSET); 11196634961cSJack Morgenstein 11206634961cSJack Morgenstein short_field = dev->caps.pkey_table_len[vhcr->in_modifier]; 11216634961cSJack Morgenstein MLX4_PUT(outbox->buf, short_field, 11226634961cSJack Morgenstein QUERY_PORT_CUR_MAX_PKEY_OFFSET); 11235cc914f1SMarcel Apfelbaum } 11245cc914f1SMarcel Apfelbaum 11255cc914f1SMarcel Apfelbaum return err; 11265cc914f1SMarcel Apfelbaum } 11275cc914f1SMarcel Apfelbaum 11286634961cSJack Morgenstein int mlx4_get_slave_pkey_gid_tbl_len(struct mlx4_dev *dev, u8 port, 11296634961cSJack Morgenstein int *gid_tbl_len, int *pkey_tbl_len) 11306634961cSJack Morgenstein { 11316634961cSJack Morgenstein struct mlx4_cmd_mailbox *mailbox; 11326634961cSJack Morgenstein u32 *outbox; 11336634961cSJack Morgenstein u16 field; 11346634961cSJack Morgenstein int err; 11356634961cSJack Morgenstein 11366634961cSJack Morgenstein mailbox = mlx4_alloc_cmd_mailbox(dev); 11376634961cSJack Morgenstein if (IS_ERR(mailbox)) 11386634961cSJack Morgenstein return PTR_ERR(mailbox); 11396634961cSJack Morgenstein 11406634961cSJack Morgenstein err = mlx4_cmd_box(dev, 0, mailbox->dma, port, 0, 11416634961cSJack Morgenstein MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B, 11426634961cSJack Morgenstein MLX4_CMD_WRAPPED); 11436634961cSJack Morgenstein if (err) 11446634961cSJack Morgenstein goto out; 11456634961cSJack Morgenstein 11466634961cSJack Morgenstein outbox = mailbox->buf; 11476634961cSJack Morgenstein 11486634961cSJack Morgenstein MLX4_GET(field, outbox, QUERY_PORT_CUR_MAX_GID_OFFSET); 11496634961cSJack Morgenstein *gid_tbl_len = field; 11506634961cSJack Morgenstein 11516634961cSJack Morgenstein MLX4_GET(field, outbox, QUERY_PORT_CUR_MAX_PKEY_OFFSET); 11526634961cSJack Morgenstein *pkey_tbl_len = field; 11536634961cSJack Morgenstein 11546634961cSJack Morgenstein out: 11556634961cSJack Morgenstein mlx4_free_cmd_mailbox(dev, mailbox); 11566634961cSJack Morgenstein return err; 11576634961cSJack Morgenstein } 11586634961cSJack Morgenstein EXPORT_SYMBOL(mlx4_get_slave_pkey_gid_tbl_len); 11596634961cSJack Morgenstein 11605a2cc190SJeff Kirsher int mlx4_map_cmd(struct mlx4_dev *dev, u16 op, struct mlx4_icm *icm, u64 virt) 11615a2cc190SJeff Kirsher { 11625a2cc190SJeff Kirsher struct mlx4_cmd_mailbox *mailbox; 11635a2cc190SJeff Kirsher struct mlx4_icm_iter iter; 11645a2cc190SJeff Kirsher __be64 *pages; 11655a2cc190SJeff Kirsher int lg; 11665a2cc190SJeff Kirsher int nent = 0; 11675a2cc190SJeff Kirsher int i; 11685a2cc190SJeff Kirsher int err = 0; 11695a2cc190SJeff Kirsher int ts = 0, tc = 0; 11705a2cc190SJeff Kirsher 11715a2cc190SJeff Kirsher mailbox = mlx4_alloc_cmd_mailbox(dev); 11725a2cc190SJeff Kirsher if (IS_ERR(mailbox)) 11735a2cc190SJeff Kirsher return PTR_ERR(mailbox); 11745a2cc190SJeff Kirsher pages = mailbox->buf; 11755a2cc190SJeff Kirsher 11765a2cc190SJeff Kirsher for (mlx4_icm_first(icm, &iter); 11775a2cc190SJeff Kirsher !mlx4_icm_last(&iter); 11785a2cc190SJeff Kirsher mlx4_icm_next(&iter)) { 11795a2cc190SJeff Kirsher /* 11805a2cc190SJeff Kirsher * We have to pass pages that are aligned to their 11815a2cc190SJeff Kirsher * size, so find the least significant 1 in the 11825a2cc190SJeff Kirsher * address or size and use that as our log2 size. 11835a2cc190SJeff Kirsher */ 11845a2cc190SJeff Kirsher lg = ffs(mlx4_icm_addr(&iter) | mlx4_icm_size(&iter)) - 1; 11855a2cc190SJeff Kirsher if (lg < MLX4_ICM_PAGE_SHIFT) { 11861a91de28SJoe Perches mlx4_warn(dev, "Got FW area not aligned to %d (%llx/%lx)\n", 11875a2cc190SJeff Kirsher MLX4_ICM_PAGE_SIZE, 11885a2cc190SJeff Kirsher (unsigned long long) mlx4_icm_addr(&iter), 11895a2cc190SJeff Kirsher mlx4_icm_size(&iter)); 11905a2cc190SJeff Kirsher err = -EINVAL; 11915a2cc190SJeff Kirsher goto out; 11925a2cc190SJeff Kirsher } 11935a2cc190SJeff Kirsher 11945a2cc190SJeff Kirsher for (i = 0; i < mlx4_icm_size(&iter) >> lg; ++i) { 11955a2cc190SJeff Kirsher if (virt != -1) { 11965a2cc190SJeff Kirsher pages[nent * 2] = cpu_to_be64(virt); 11975a2cc190SJeff Kirsher virt += 1 << lg; 11985a2cc190SJeff Kirsher } 11995a2cc190SJeff Kirsher 12005a2cc190SJeff Kirsher pages[nent * 2 + 1] = 12015a2cc190SJeff Kirsher cpu_to_be64((mlx4_icm_addr(&iter) + (i << lg)) | 12025a2cc190SJeff Kirsher (lg - MLX4_ICM_PAGE_SHIFT)); 12035a2cc190SJeff Kirsher ts += 1 << (lg - 10); 12045a2cc190SJeff Kirsher ++tc; 12055a2cc190SJeff Kirsher 12065a2cc190SJeff Kirsher if (++nent == MLX4_MAILBOX_SIZE / 16) { 12075a2cc190SJeff Kirsher err = mlx4_cmd(dev, mailbox->dma, nent, 0, op, 1208f9baff50SJack Morgenstein MLX4_CMD_TIME_CLASS_B, 1209f9baff50SJack Morgenstein MLX4_CMD_NATIVE); 12105a2cc190SJeff Kirsher if (err) 12115a2cc190SJeff Kirsher goto out; 12125a2cc190SJeff Kirsher nent = 0; 12135a2cc190SJeff Kirsher } 12145a2cc190SJeff Kirsher } 12155a2cc190SJeff Kirsher } 12165a2cc190SJeff Kirsher 12175a2cc190SJeff Kirsher if (nent) 1218f9baff50SJack Morgenstein err = mlx4_cmd(dev, mailbox->dma, nent, 0, op, 1219f9baff50SJack Morgenstein MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 12205a2cc190SJeff Kirsher if (err) 12215a2cc190SJeff Kirsher goto out; 12225a2cc190SJeff Kirsher 12235a2cc190SJeff Kirsher switch (op) { 12245a2cc190SJeff Kirsher case MLX4_CMD_MAP_FA: 12251a91de28SJoe Perches mlx4_dbg(dev, "Mapped %d chunks/%d KB for FW\n", tc, ts); 12265a2cc190SJeff Kirsher break; 12275a2cc190SJeff Kirsher case MLX4_CMD_MAP_ICM_AUX: 12281a91de28SJoe Perches mlx4_dbg(dev, "Mapped %d chunks/%d KB for ICM aux\n", tc, ts); 12295a2cc190SJeff Kirsher break; 12305a2cc190SJeff Kirsher case MLX4_CMD_MAP_ICM: 12311a91de28SJoe Perches mlx4_dbg(dev, "Mapped %d chunks/%d KB at %llx for ICM\n", 12325a2cc190SJeff Kirsher tc, ts, (unsigned long long) virt - (ts << 10)); 12335a2cc190SJeff Kirsher break; 12345a2cc190SJeff Kirsher } 12355a2cc190SJeff Kirsher 12365a2cc190SJeff Kirsher out: 12375a2cc190SJeff Kirsher mlx4_free_cmd_mailbox(dev, mailbox); 12385a2cc190SJeff Kirsher return err; 12395a2cc190SJeff Kirsher } 12405a2cc190SJeff Kirsher 12415a2cc190SJeff Kirsher int mlx4_MAP_FA(struct mlx4_dev *dev, struct mlx4_icm *icm) 12425a2cc190SJeff Kirsher { 12435a2cc190SJeff Kirsher return mlx4_map_cmd(dev, MLX4_CMD_MAP_FA, icm, -1); 12445a2cc190SJeff Kirsher } 12455a2cc190SJeff Kirsher 12465a2cc190SJeff Kirsher int mlx4_UNMAP_FA(struct mlx4_dev *dev) 12475a2cc190SJeff Kirsher { 1248f9baff50SJack Morgenstein return mlx4_cmd(dev, 0, 0, 0, MLX4_CMD_UNMAP_FA, 1249f9baff50SJack Morgenstein MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 12505a2cc190SJeff Kirsher } 12515a2cc190SJeff Kirsher 12525a2cc190SJeff Kirsher 12535a2cc190SJeff Kirsher int mlx4_RUN_FW(struct mlx4_dev *dev) 12545a2cc190SJeff Kirsher { 1255f9baff50SJack Morgenstein return mlx4_cmd(dev, 0, 0, 0, MLX4_CMD_RUN_FW, 1256f9baff50SJack Morgenstein MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 12575a2cc190SJeff Kirsher } 12585a2cc190SJeff Kirsher 12595a2cc190SJeff Kirsher int mlx4_QUERY_FW(struct mlx4_dev *dev) 12605a2cc190SJeff Kirsher { 12615a2cc190SJeff Kirsher struct mlx4_fw *fw = &mlx4_priv(dev)->fw; 12625a2cc190SJeff Kirsher struct mlx4_cmd *cmd = &mlx4_priv(dev)->cmd; 12635a2cc190SJeff Kirsher struct mlx4_cmd_mailbox *mailbox; 12645a2cc190SJeff Kirsher u32 *outbox; 12655a2cc190SJeff Kirsher int err = 0; 12665a2cc190SJeff Kirsher u64 fw_ver; 12675a2cc190SJeff Kirsher u16 cmd_if_rev; 12685a2cc190SJeff Kirsher u8 lg; 12695a2cc190SJeff Kirsher 12705a2cc190SJeff Kirsher #define QUERY_FW_OUT_SIZE 0x100 12715a2cc190SJeff Kirsher #define QUERY_FW_VER_OFFSET 0x00 12725cc914f1SMarcel Apfelbaum #define QUERY_FW_PPF_ID 0x09 12735a2cc190SJeff Kirsher #define QUERY_FW_CMD_IF_REV_OFFSET 0x0a 12745a2cc190SJeff Kirsher #define QUERY_FW_MAX_CMD_OFFSET 0x0f 12755a2cc190SJeff Kirsher #define QUERY_FW_ERR_START_OFFSET 0x30 12765a2cc190SJeff Kirsher #define QUERY_FW_ERR_SIZE_OFFSET 0x38 12775a2cc190SJeff Kirsher #define QUERY_FW_ERR_BAR_OFFSET 0x3c 12785a2cc190SJeff Kirsher 12795a2cc190SJeff Kirsher #define QUERY_FW_SIZE_OFFSET 0x00 12805a2cc190SJeff Kirsher #define QUERY_FW_CLR_INT_BASE_OFFSET 0x20 12815a2cc190SJeff Kirsher #define QUERY_FW_CLR_INT_BAR_OFFSET 0x28 12825a2cc190SJeff Kirsher 12835cc914f1SMarcel Apfelbaum #define QUERY_FW_COMM_BASE_OFFSET 0x40 12845cc914f1SMarcel Apfelbaum #define QUERY_FW_COMM_BAR_OFFSET 0x48 12855cc914f1SMarcel Apfelbaum 1286ddd8a6c1SEugenia Emantayev #define QUERY_FW_CLOCK_OFFSET 0x50 1287ddd8a6c1SEugenia Emantayev #define QUERY_FW_CLOCK_BAR 0x58 1288ddd8a6c1SEugenia Emantayev 12895a2cc190SJeff Kirsher mailbox = mlx4_alloc_cmd_mailbox(dev); 12905a2cc190SJeff Kirsher if (IS_ERR(mailbox)) 12915a2cc190SJeff Kirsher return PTR_ERR(mailbox); 12925a2cc190SJeff Kirsher outbox = mailbox->buf; 12935a2cc190SJeff Kirsher 12945a2cc190SJeff Kirsher err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, MLX4_CMD_QUERY_FW, 1295f9baff50SJack Morgenstein MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 12965a2cc190SJeff Kirsher if (err) 12975a2cc190SJeff Kirsher goto out; 12985a2cc190SJeff Kirsher 12995a2cc190SJeff Kirsher MLX4_GET(fw_ver, outbox, QUERY_FW_VER_OFFSET); 13005a2cc190SJeff Kirsher /* 13015a2cc190SJeff Kirsher * FW subminor version is at more significant bits than minor 13025a2cc190SJeff Kirsher * version, so swap here. 13035a2cc190SJeff Kirsher */ 13045a2cc190SJeff Kirsher dev->caps.fw_ver = (fw_ver & 0xffff00000000ull) | 13055a2cc190SJeff Kirsher ((fw_ver & 0xffff0000ull) >> 16) | 13065a2cc190SJeff Kirsher ((fw_ver & 0x0000ffffull) << 16); 13075a2cc190SJeff Kirsher 1308752a50caSJack Morgenstein MLX4_GET(lg, outbox, QUERY_FW_PPF_ID); 1309752a50caSJack Morgenstein dev->caps.function = lg; 1310752a50caSJack Morgenstein 1311b91cb3ebSJack Morgenstein if (mlx4_is_slave(dev)) 1312b91cb3ebSJack Morgenstein goto out; 1313b91cb3ebSJack Morgenstein 13145cc914f1SMarcel Apfelbaum 13155a2cc190SJeff Kirsher MLX4_GET(cmd_if_rev, outbox, QUERY_FW_CMD_IF_REV_OFFSET); 13165a2cc190SJeff Kirsher if (cmd_if_rev < MLX4_COMMAND_INTERFACE_MIN_REV || 13175a2cc190SJeff Kirsher cmd_if_rev > MLX4_COMMAND_INTERFACE_MAX_REV) { 13181a91de28SJoe Perches mlx4_err(dev, "Installed FW has unsupported command interface revision %d\n", 13195a2cc190SJeff Kirsher cmd_if_rev); 13205a2cc190SJeff Kirsher mlx4_err(dev, "(Installed FW version is %d.%d.%03d)\n", 13215a2cc190SJeff Kirsher (int) (dev->caps.fw_ver >> 32), 13225a2cc190SJeff Kirsher (int) (dev->caps.fw_ver >> 16) & 0xffff, 13235a2cc190SJeff Kirsher (int) dev->caps.fw_ver & 0xffff); 13241a91de28SJoe Perches mlx4_err(dev, "This driver version supports only revisions %d to %d\n", 13255a2cc190SJeff Kirsher MLX4_COMMAND_INTERFACE_MIN_REV, MLX4_COMMAND_INTERFACE_MAX_REV); 13265a2cc190SJeff Kirsher err = -ENODEV; 13275a2cc190SJeff Kirsher goto out; 13285a2cc190SJeff Kirsher } 13295a2cc190SJeff Kirsher 13305a2cc190SJeff Kirsher if (cmd_if_rev < MLX4_COMMAND_INTERFACE_NEW_PORT_CMDS) 13315a2cc190SJeff Kirsher dev->flags |= MLX4_FLAG_OLD_PORT_CMDS; 13325a2cc190SJeff Kirsher 13335a2cc190SJeff Kirsher MLX4_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET); 13345a2cc190SJeff Kirsher cmd->max_cmds = 1 << lg; 13355a2cc190SJeff Kirsher 13365a2cc190SJeff Kirsher mlx4_dbg(dev, "FW version %d.%d.%03d (cmd intf rev %d), max commands %d\n", 13375a2cc190SJeff Kirsher (int) (dev->caps.fw_ver >> 32), 13385a2cc190SJeff Kirsher (int) (dev->caps.fw_ver >> 16) & 0xffff, 13395a2cc190SJeff Kirsher (int) dev->caps.fw_ver & 0xffff, 13405a2cc190SJeff Kirsher cmd_if_rev, cmd->max_cmds); 13415a2cc190SJeff Kirsher 13425a2cc190SJeff Kirsher MLX4_GET(fw->catas_offset, outbox, QUERY_FW_ERR_START_OFFSET); 13435a2cc190SJeff Kirsher MLX4_GET(fw->catas_size, outbox, QUERY_FW_ERR_SIZE_OFFSET); 13445a2cc190SJeff Kirsher MLX4_GET(fw->catas_bar, outbox, QUERY_FW_ERR_BAR_OFFSET); 13455a2cc190SJeff Kirsher fw->catas_bar = (fw->catas_bar >> 6) * 2; 13465a2cc190SJeff Kirsher 13475a2cc190SJeff Kirsher mlx4_dbg(dev, "Catastrophic error buffer at 0x%llx, size 0x%x, BAR %d\n", 13485a2cc190SJeff Kirsher (unsigned long long) fw->catas_offset, fw->catas_size, fw->catas_bar); 13495a2cc190SJeff Kirsher 13505a2cc190SJeff Kirsher MLX4_GET(fw->fw_pages, outbox, QUERY_FW_SIZE_OFFSET); 13515a2cc190SJeff Kirsher MLX4_GET(fw->clr_int_base, outbox, QUERY_FW_CLR_INT_BASE_OFFSET); 13525a2cc190SJeff Kirsher MLX4_GET(fw->clr_int_bar, outbox, QUERY_FW_CLR_INT_BAR_OFFSET); 13535a2cc190SJeff Kirsher fw->clr_int_bar = (fw->clr_int_bar >> 6) * 2; 13545a2cc190SJeff Kirsher 13555cc914f1SMarcel Apfelbaum MLX4_GET(fw->comm_base, outbox, QUERY_FW_COMM_BASE_OFFSET); 13565cc914f1SMarcel Apfelbaum MLX4_GET(fw->comm_bar, outbox, QUERY_FW_COMM_BAR_OFFSET); 13575cc914f1SMarcel Apfelbaum fw->comm_bar = (fw->comm_bar >> 6) * 2; 13585cc914f1SMarcel Apfelbaum mlx4_dbg(dev, "Communication vector bar:%d offset:0x%llx\n", 13595cc914f1SMarcel Apfelbaum fw->comm_bar, fw->comm_base); 13605a2cc190SJeff Kirsher mlx4_dbg(dev, "FW size %d KB\n", fw->fw_pages >> 2); 13615a2cc190SJeff Kirsher 1362ddd8a6c1SEugenia Emantayev MLX4_GET(fw->clock_offset, outbox, QUERY_FW_CLOCK_OFFSET); 1363ddd8a6c1SEugenia Emantayev MLX4_GET(fw->clock_bar, outbox, QUERY_FW_CLOCK_BAR); 1364ddd8a6c1SEugenia Emantayev fw->clock_bar = (fw->clock_bar >> 6) * 2; 1365ddd8a6c1SEugenia Emantayev mlx4_dbg(dev, "Internal clock bar:%d offset:0x%llx\n", 1366ddd8a6c1SEugenia Emantayev fw->clock_bar, fw->clock_offset); 1367ddd8a6c1SEugenia Emantayev 13685a2cc190SJeff Kirsher /* 13695a2cc190SJeff Kirsher * Round up number of system pages needed in case 13705a2cc190SJeff Kirsher * MLX4_ICM_PAGE_SIZE < PAGE_SIZE. 13715a2cc190SJeff Kirsher */ 13725a2cc190SJeff Kirsher fw->fw_pages = 13735a2cc190SJeff Kirsher ALIGN(fw->fw_pages, PAGE_SIZE / MLX4_ICM_PAGE_SIZE) >> 13745a2cc190SJeff Kirsher (PAGE_SHIFT - MLX4_ICM_PAGE_SHIFT); 13755a2cc190SJeff Kirsher 13765a2cc190SJeff Kirsher mlx4_dbg(dev, "Clear int @ %llx, BAR %d\n", 13775a2cc190SJeff Kirsher (unsigned long long) fw->clr_int_base, fw->clr_int_bar); 13785a2cc190SJeff Kirsher 13795a2cc190SJeff Kirsher out: 13805a2cc190SJeff Kirsher mlx4_free_cmd_mailbox(dev, mailbox); 13815a2cc190SJeff Kirsher return err; 13825a2cc190SJeff Kirsher } 13835a2cc190SJeff Kirsher 1384b91cb3ebSJack Morgenstein int mlx4_QUERY_FW_wrapper(struct mlx4_dev *dev, int slave, 1385b91cb3ebSJack Morgenstein struct mlx4_vhcr *vhcr, 1386b91cb3ebSJack Morgenstein struct mlx4_cmd_mailbox *inbox, 1387b91cb3ebSJack Morgenstein struct mlx4_cmd_mailbox *outbox, 1388b91cb3ebSJack Morgenstein struct mlx4_cmd_info *cmd) 1389b91cb3ebSJack Morgenstein { 1390b91cb3ebSJack Morgenstein u8 *outbuf; 1391b91cb3ebSJack Morgenstein int err; 1392b91cb3ebSJack Morgenstein 1393b91cb3ebSJack Morgenstein outbuf = outbox->buf; 1394b91cb3ebSJack Morgenstein err = mlx4_cmd_box(dev, 0, outbox->dma, 0, 0, MLX4_CMD_QUERY_FW, 1395b91cb3ebSJack Morgenstein MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 1396b91cb3ebSJack Morgenstein if (err) 1397b91cb3ebSJack Morgenstein return err; 1398b91cb3ebSJack Morgenstein 1399752a50caSJack Morgenstein /* for slaves, set pci PPF ID to invalid and zero out everything 1400752a50caSJack Morgenstein * else except FW version */ 1401b91cb3ebSJack Morgenstein outbuf[0] = outbuf[1] = 0; 1402b91cb3ebSJack Morgenstein memset(&outbuf[8], 0, QUERY_FW_OUT_SIZE - 8); 1403752a50caSJack Morgenstein outbuf[QUERY_FW_PPF_ID] = MLX4_INVALID_SLAVE_ID; 1404752a50caSJack Morgenstein 1405b91cb3ebSJack Morgenstein return 0; 1406b91cb3ebSJack Morgenstein } 1407b91cb3ebSJack Morgenstein 14085a2cc190SJeff Kirsher static void get_board_id(void *vsd, char *board_id) 14095a2cc190SJeff Kirsher { 14105a2cc190SJeff Kirsher int i; 14115a2cc190SJeff Kirsher 14125a2cc190SJeff Kirsher #define VSD_OFFSET_SIG1 0x00 14135a2cc190SJeff Kirsher #define VSD_OFFSET_SIG2 0xde 14145a2cc190SJeff Kirsher #define VSD_OFFSET_MLX_BOARD_ID 0xd0 14155a2cc190SJeff Kirsher #define VSD_OFFSET_TS_BOARD_ID 0x20 14165a2cc190SJeff Kirsher 14175a2cc190SJeff Kirsher #define VSD_SIGNATURE_TOPSPIN 0x5ad 14185a2cc190SJeff Kirsher 14195a2cc190SJeff Kirsher memset(board_id, 0, MLX4_BOARD_ID_LEN); 14205a2cc190SJeff Kirsher 14215a2cc190SJeff Kirsher if (be16_to_cpup(vsd + VSD_OFFSET_SIG1) == VSD_SIGNATURE_TOPSPIN && 14225a2cc190SJeff Kirsher be16_to_cpup(vsd + VSD_OFFSET_SIG2) == VSD_SIGNATURE_TOPSPIN) { 14235a2cc190SJeff Kirsher strlcpy(board_id, vsd + VSD_OFFSET_TS_BOARD_ID, MLX4_BOARD_ID_LEN); 14245a2cc190SJeff Kirsher } else { 14255a2cc190SJeff Kirsher /* 14265a2cc190SJeff Kirsher * The board ID is a string but the firmware byte 14275a2cc190SJeff Kirsher * swaps each 4-byte word before passing it back to 14285a2cc190SJeff Kirsher * us. Therefore we need to swab it before printing. 14295a2cc190SJeff Kirsher */ 14305a2cc190SJeff Kirsher for (i = 0; i < 4; ++i) 14315a2cc190SJeff Kirsher ((u32 *) board_id)[i] = 14325a2cc190SJeff Kirsher swab32(*(u32 *) (vsd + VSD_OFFSET_MLX_BOARD_ID + i * 4)); 14335a2cc190SJeff Kirsher } 14345a2cc190SJeff Kirsher } 14355a2cc190SJeff Kirsher 14365a2cc190SJeff Kirsher int mlx4_QUERY_ADAPTER(struct mlx4_dev *dev, struct mlx4_adapter *adapter) 14375a2cc190SJeff Kirsher { 14385a2cc190SJeff Kirsher struct mlx4_cmd_mailbox *mailbox; 14395a2cc190SJeff Kirsher u32 *outbox; 14405a2cc190SJeff Kirsher int err; 14415a2cc190SJeff Kirsher 14425a2cc190SJeff Kirsher #define QUERY_ADAPTER_OUT_SIZE 0x100 14435a2cc190SJeff Kirsher #define QUERY_ADAPTER_INTA_PIN_OFFSET 0x10 14445a2cc190SJeff Kirsher #define QUERY_ADAPTER_VSD_OFFSET 0x20 14455a2cc190SJeff Kirsher 14465a2cc190SJeff Kirsher mailbox = mlx4_alloc_cmd_mailbox(dev); 14475a2cc190SJeff Kirsher if (IS_ERR(mailbox)) 14485a2cc190SJeff Kirsher return PTR_ERR(mailbox); 14495a2cc190SJeff Kirsher outbox = mailbox->buf; 14505a2cc190SJeff Kirsher 14515a2cc190SJeff Kirsher err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, MLX4_CMD_QUERY_ADAPTER, 1452f9baff50SJack Morgenstein MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 14535a2cc190SJeff Kirsher if (err) 14545a2cc190SJeff Kirsher goto out; 14555a2cc190SJeff Kirsher 14565a2cc190SJeff Kirsher MLX4_GET(adapter->inta_pin, outbox, QUERY_ADAPTER_INTA_PIN_OFFSET); 14575a2cc190SJeff Kirsher 14585a2cc190SJeff Kirsher get_board_id(outbox + QUERY_ADAPTER_VSD_OFFSET / 4, 14595a2cc190SJeff Kirsher adapter->board_id); 14605a2cc190SJeff Kirsher 14615a2cc190SJeff Kirsher out: 14625a2cc190SJeff Kirsher mlx4_free_cmd_mailbox(dev, mailbox); 14635a2cc190SJeff Kirsher return err; 14645a2cc190SJeff Kirsher } 14655a2cc190SJeff Kirsher 14665a2cc190SJeff Kirsher int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) 14675a2cc190SJeff Kirsher { 14685a2cc190SJeff Kirsher struct mlx4_cmd_mailbox *mailbox; 14695a2cc190SJeff Kirsher __be32 *inbox; 14705a2cc190SJeff Kirsher int err; 14715a2cc190SJeff Kirsher 14725a2cc190SJeff Kirsher #define INIT_HCA_IN_SIZE 0x200 14735a2cc190SJeff Kirsher #define INIT_HCA_VERSION_OFFSET 0x000 14745a2cc190SJeff Kirsher #define INIT_HCA_VERSION 2 14757ffdf726SOr Gerlitz #define INIT_HCA_VXLAN_OFFSET 0x0c 14765a2cc190SJeff Kirsher #define INIT_HCA_CACHELINE_SZ_OFFSET 0x0e 14775a2cc190SJeff Kirsher #define INIT_HCA_FLAGS_OFFSET 0x014 14785a2cc190SJeff Kirsher #define INIT_HCA_QPC_OFFSET 0x020 14795a2cc190SJeff Kirsher #define INIT_HCA_QPC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x10) 14805a2cc190SJeff Kirsher #define INIT_HCA_LOG_QP_OFFSET (INIT_HCA_QPC_OFFSET + 0x17) 14815a2cc190SJeff Kirsher #define INIT_HCA_SRQC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x28) 14825a2cc190SJeff Kirsher #define INIT_HCA_LOG_SRQ_OFFSET (INIT_HCA_QPC_OFFSET + 0x2f) 14835a2cc190SJeff Kirsher #define INIT_HCA_CQC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x30) 14845a2cc190SJeff Kirsher #define INIT_HCA_LOG_CQ_OFFSET (INIT_HCA_QPC_OFFSET + 0x37) 14855cc914f1SMarcel Apfelbaum #define INIT_HCA_EQE_CQE_OFFSETS (INIT_HCA_QPC_OFFSET + 0x38) 148677507aa2SIdo Shamay #define INIT_HCA_EQE_CQE_STRIDE_OFFSET (INIT_HCA_QPC_OFFSET + 0x3b) 14875a2cc190SJeff Kirsher #define INIT_HCA_ALTC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x40) 14885a2cc190SJeff Kirsher #define INIT_HCA_AUXC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x50) 14895a2cc190SJeff Kirsher #define INIT_HCA_EQC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x60) 14905a2cc190SJeff Kirsher #define INIT_HCA_LOG_EQ_OFFSET (INIT_HCA_QPC_OFFSET + 0x67) 1491*7ae0e400SMatan Barak #define INIT_HCA_NUM_SYS_EQS_OFFSET (INIT_HCA_QPC_OFFSET + 0x6a) 14925a2cc190SJeff Kirsher #define INIT_HCA_RDMARC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x70) 14935a2cc190SJeff Kirsher #define INIT_HCA_LOG_RD_OFFSET (INIT_HCA_QPC_OFFSET + 0x77) 14945a2cc190SJeff Kirsher #define INIT_HCA_MCAST_OFFSET 0x0c0 14955a2cc190SJeff Kirsher #define INIT_HCA_MC_BASE_OFFSET (INIT_HCA_MCAST_OFFSET + 0x00) 14965a2cc190SJeff Kirsher #define INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x12) 14975a2cc190SJeff Kirsher #define INIT_HCA_LOG_MC_HASH_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x16) 14985a2cc190SJeff Kirsher #define INIT_HCA_UC_STEERING_OFFSET (INIT_HCA_MCAST_OFFSET + 0x18) 14995a2cc190SJeff Kirsher #define INIT_HCA_LOG_MC_TABLE_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x1b) 15000ff1fb65SHadar Hen Zion #define INIT_HCA_DEVICE_MANAGED_FLOW_STEERING_EN 0x6 15010ff1fb65SHadar Hen Zion #define INIT_HCA_FS_PARAM_OFFSET 0x1d0 15020ff1fb65SHadar Hen Zion #define INIT_HCA_FS_BASE_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x00) 15030ff1fb65SHadar Hen Zion #define INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x12) 15040ff1fb65SHadar Hen Zion #define INIT_HCA_FS_LOG_TABLE_SZ_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x1b) 15050ff1fb65SHadar Hen Zion #define INIT_HCA_FS_ETH_BITS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x21) 15060ff1fb65SHadar Hen Zion #define INIT_HCA_FS_ETH_NUM_ADDRS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x22) 15070ff1fb65SHadar Hen Zion #define INIT_HCA_FS_IB_BITS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x25) 15080ff1fb65SHadar Hen Zion #define INIT_HCA_FS_IB_NUM_ADDRS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x26) 15095a2cc190SJeff Kirsher #define INIT_HCA_TPT_OFFSET 0x0f0 15105a2cc190SJeff Kirsher #define INIT_HCA_DMPT_BASE_OFFSET (INIT_HCA_TPT_OFFSET + 0x00) 1511e448834eSShani Michaeli #define INIT_HCA_TPT_MW_OFFSET (INIT_HCA_TPT_OFFSET + 0x08) 15125a2cc190SJeff Kirsher #define INIT_HCA_LOG_MPT_SZ_OFFSET (INIT_HCA_TPT_OFFSET + 0x0b) 15135a2cc190SJeff Kirsher #define INIT_HCA_MTT_BASE_OFFSET (INIT_HCA_TPT_OFFSET + 0x10) 15145a2cc190SJeff Kirsher #define INIT_HCA_CMPT_BASE_OFFSET (INIT_HCA_TPT_OFFSET + 0x18) 15155a2cc190SJeff Kirsher #define INIT_HCA_UAR_OFFSET 0x120 15165a2cc190SJeff Kirsher #define INIT_HCA_LOG_UAR_SZ_OFFSET (INIT_HCA_UAR_OFFSET + 0x0a) 15175a2cc190SJeff Kirsher #define INIT_HCA_UAR_PAGE_SZ_OFFSET (INIT_HCA_UAR_OFFSET + 0x0b) 15185a2cc190SJeff Kirsher 15195a2cc190SJeff Kirsher mailbox = mlx4_alloc_cmd_mailbox(dev); 15205a2cc190SJeff Kirsher if (IS_ERR(mailbox)) 15215a2cc190SJeff Kirsher return PTR_ERR(mailbox); 15225a2cc190SJeff Kirsher inbox = mailbox->buf; 15235a2cc190SJeff Kirsher 15245a2cc190SJeff Kirsher *((u8 *) mailbox->buf + INIT_HCA_VERSION_OFFSET) = INIT_HCA_VERSION; 15255a2cc190SJeff Kirsher 15265a2cc190SJeff Kirsher *((u8 *) mailbox->buf + INIT_HCA_CACHELINE_SZ_OFFSET) = 15275a2cc190SJeff Kirsher (ilog2(cache_line_size()) - 4) << 5; 15285a2cc190SJeff Kirsher 15295a2cc190SJeff Kirsher #if defined(__LITTLE_ENDIAN) 15305a2cc190SJeff Kirsher *(inbox + INIT_HCA_FLAGS_OFFSET / 4) &= ~cpu_to_be32(1 << 1); 15315a2cc190SJeff Kirsher #elif defined(__BIG_ENDIAN) 15325a2cc190SJeff Kirsher *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 1); 15335a2cc190SJeff Kirsher #else 15345a2cc190SJeff Kirsher #error Host endianness not defined 15355a2cc190SJeff Kirsher #endif 15365a2cc190SJeff Kirsher /* Check port for UD address vector: */ 15375a2cc190SJeff Kirsher *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1); 15385a2cc190SJeff Kirsher 15395a2cc190SJeff Kirsher /* Enable IPoIB checksumming if we can: */ 15405a2cc190SJeff Kirsher if (dev->caps.flags & MLX4_DEV_CAP_FLAG_IPOIB_CSUM) 15415a2cc190SJeff Kirsher *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 3); 15425a2cc190SJeff Kirsher 15435a2cc190SJeff Kirsher /* Enable QoS support if module parameter set */ 15445a2cc190SJeff Kirsher if (enable_qos) 15455a2cc190SJeff Kirsher *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 2); 15465a2cc190SJeff Kirsher 15475a2cc190SJeff Kirsher /* enable counters */ 15485a2cc190SJeff Kirsher if (dev->caps.flags & MLX4_DEV_CAP_FLAG_COUNTERS) 15495a2cc190SJeff Kirsher *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 4); 15505a2cc190SJeff Kirsher 155108ff3235SOr Gerlitz /* CX3 is capable of extending CQEs/EQEs from 32 to 64 bytes */ 155208ff3235SOr Gerlitz if (dev->caps.flags & MLX4_DEV_CAP_FLAG_64B_EQE) { 155308ff3235SOr Gerlitz *(inbox + INIT_HCA_EQE_CQE_OFFSETS / 4) |= cpu_to_be32(1 << 29); 155408ff3235SOr Gerlitz dev->caps.eqe_size = 64; 155508ff3235SOr Gerlitz dev->caps.eqe_factor = 1; 155608ff3235SOr Gerlitz } else { 155708ff3235SOr Gerlitz dev->caps.eqe_size = 32; 155808ff3235SOr Gerlitz dev->caps.eqe_factor = 0; 155908ff3235SOr Gerlitz } 156008ff3235SOr Gerlitz 156108ff3235SOr Gerlitz if (dev->caps.flags & MLX4_DEV_CAP_FLAG_64B_CQE) { 156208ff3235SOr Gerlitz *(inbox + INIT_HCA_EQE_CQE_OFFSETS / 4) |= cpu_to_be32(1 << 30); 156308ff3235SOr Gerlitz dev->caps.cqe_size = 64; 156477507aa2SIdo Shamay dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_LARGE_CQE; 156508ff3235SOr Gerlitz } else { 156608ff3235SOr Gerlitz dev->caps.cqe_size = 32; 156708ff3235SOr Gerlitz } 156808ff3235SOr Gerlitz 156977507aa2SIdo Shamay /* CX3 is capable of extending CQEs\EQEs to strides larger than 64B */ 157077507aa2SIdo Shamay if ((dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_EQE_STRIDE) && 157177507aa2SIdo Shamay (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_CQE_STRIDE)) { 157277507aa2SIdo Shamay dev->caps.eqe_size = cache_line_size(); 157377507aa2SIdo Shamay dev->caps.cqe_size = cache_line_size(); 157477507aa2SIdo Shamay dev->caps.eqe_factor = 0; 157577507aa2SIdo Shamay MLX4_PUT(inbox, (u8)((ilog2(dev->caps.eqe_size) - 5) << 4 | 157677507aa2SIdo Shamay (ilog2(dev->caps.eqe_size) - 5)), 157777507aa2SIdo Shamay INIT_HCA_EQE_CQE_STRIDE_OFFSET); 157877507aa2SIdo Shamay 157977507aa2SIdo Shamay /* User still need to know to support CQE > 32B */ 158077507aa2SIdo Shamay dev->caps.userspace_caps |= MLX4_USER_DEV_CAP_LARGE_CQE; 158177507aa2SIdo Shamay } 158277507aa2SIdo Shamay 15835a2cc190SJeff Kirsher /* QPC/EEC/CQC/EQC/RDMARC attributes */ 15845a2cc190SJeff Kirsher 15855a2cc190SJeff Kirsher MLX4_PUT(inbox, param->qpc_base, INIT_HCA_QPC_BASE_OFFSET); 15865a2cc190SJeff Kirsher MLX4_PUT(inbox, param->log_num_qps, INIT_HCA_LOG_QP_OFFSET); 15875a2cc190SJeff Kirsher MLX4_PUT(inbox, param->srqc_base, INIT_HCA_SRQC_BASE_OFFSET); 15885a2cc190SJeff Kirsher MLX4_PUT(inbox, param->log_num_srqs, INIT_HCA_LOG_SRQ_OFFSET); 15895a2cc190SJeff Kirsher MLX4_PUT(inbox, param->cqc_base, INIT_HCA_CQC_BASE_OFFSET); 15905a2cc190SJeff Kirsher MLX4_PUT(inbox, param->log_num_cqs, INIT_HCA_LOG_CQ_OFFSET); 15915a2cc190SJeff Kirsher MLX4_PUT(inbox, param->altc_base, INIT_HCA_ALTC_BASE_OFFSET); 15925a2cc190SJeff Kirsher MLX4_PUT(inbox, param->auxc_base, INIT_HCA_AUXC_BASE_OFFSET); 15935a2cc190SJeff Kirsher MLX4_PUT(inbox, param->eqc_base, INIT_HCA_EQC_BASE_OFFSET); 15945a2cc190SJeff Kirsher MLX4_PUT(inbox, param->log_num_eqs, INIT_HCA_LOG_EQ_OFFSET); 1595*7ae0e400SMatan Barak MLX4_PUT(inbox, param->num_sys_eqs, INIT_HCA_NUM_SYS_EQS_OFFSET); 15965a2cc190SJeff Kirsher MLX4_PUT(inbox, param->rdmarc_base, INIT_HCA_RDMARC_BASE_OFFSET); 15975a2cc190SJeff Kirsher MLX4_PUT(inbox, param->log_rd_per_qp, INIT_HCA_LOG_RD_OFFSET); 15985a2cc190SJeff Kirsher 15990ff1fb65SHadar Hen Zion /* steering attributes */ 16000ff1fb65SHadar Hen Zion if (dev->caps.steering_mode == 16010ff1fb65SHadar Hen Zion MLX4_STEERING_MODE_DEVICE_MANAGED) { 16020ff1fb65SHadar Hen Zion *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= 16030ff1fb65SHadar Hen Zion cpu_to_be32(1 << 16040ff1fb65SHadar Hen Zion INIT_HCA_DEVICE_MANAGED_FLOW_STEERING_EN); 16055a2cc190SJeff Kirsher 16060ff1fb65SHadar Hen Zion MLX4_PUT(inbox, param->mc_base, INIT_HCA_FS_BASE_OFFSET); 16070ff1fb65SHadar Hen Zion MLX4_PUT(inbox, param->log_mc_entry_sz, 16080ff1fb65SHadar Hen Zion INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); 16090ff1fb65SHadar Hen Zion MLX4_PUT(inbox, param->log_mc_table_sz, 16100ff1fb65SHadar Hen Zion INIT_HCA_FS_LOG_TABLE_SZ_OFFSET); 16110ff1fb65SHadar Hen Zion /* Enable Ethernet flow steering 16120ff1fb65SHadar Hen Zion * with udp unicast and tcp unicast 16130ff1fb65SHadar Hen Zion */ 161423537b73SHadar Hen Zion MLX4_PUT(inbox, (u8) (MLX4_FS_UDP_UC_EN | MLX4_FS_TCP_UC_EN), 16150ff1fb65SHadar Hen Zion INIT_HCA_FS_ETH_BITS_OFFSET); 16160ff1fb65SHadar Hen Zion MLX4_PUT(inbox, (u16) MLX4_FS_NUM_OF_L2_ADDR, 16170ff1fb65SHadar Hen Zion INIT_HCA_FS_ETH_NUM_ADDRS_OFFSET); 16180ff1fb65SHadar Hen Zion /* Enable IPoIB flow steering 16190ff1fb65SHadar Hen Zion * with udp unicast and tcp unicast 16200ff1fb65SHadar Hen Zion */ 162123537b73SHadar Hen Zion MLX4_PUT(inbox, (u8) (MLX4_FS_UDP_UC_EN | MLX4_FS_TCP_UC_EN), 16220ff1fb65SHadar Hen Zion INIT_HCA_FS_IB_BITS_OFFSET); 16230ff1fb65SHadar Hen Zion MLX4_PUT(inbox, (u16) MLX4_FS_NUM_OF_L2_ADDR, 16240ff1fb65SHadar Hen Zion INIT_HCA_FS_IB_NUM_ADDRS_OFFSET); 16250ff1fb65SHadar Hen Zion } else { 16265a2cc190SJeff Kirsher MLX4_PUT(inbox, param->mc_base, INIT_HCA_MC_BASE_OFFSET); 16270ff1fb65SHadar Hen Zion MLX4_PUT(inbox, param->log_mc_entry_sz, 16280ff1fb65SHadar Hen Zion INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); 16290ff1fb65SHadar Hen Zion MLX4_PUT(inbox, param->log_mc_hash_sz, 16300ff1fb65SHadar Hen Zion INIT_HCA_LOG_MC_HASH_SZ_OFFSET); 16310ff1fb65SHadar Hen Zion MLX4_PUT(inbox, param->log_mc_table_sz, 16320ff1fb65SHadar Hen Zion INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); 1633c96d97f4SHadar Hen Zion if (dev->caps.steering_mode == MLX4_STEERING_MODE_B0) 16340ff1fb65SHadar Hen Zion MLX4_PUT(inbox, (u8) (1 << 3), 16350ff1fb65SHadar Hen Zion INIT_HCA_UC_STEERING_OFFSET); 16360ff1fb65SHadar Hen Zion } 16375a2cc190SJeff Kirsher 16385a2cc190SJeff Kirsher /* TPT attributes */ 16395a2cc190SJeff Kirsher 16405a2cc190SJeff Kirsher MLX4_PUT(inbox, param->dmpt_base, INIT_HCA_DMPT_BASE_OFFSET); 1641e448834eSShani Michaeli MLX4_PUT(inbox, param->mw_enabled, INIT_HCA_TPT_MW_OFFSET); 16425a2cc190SJeff Kirsher MLX4_PUT(inbox, param->log_mpt_sz, INIT_HCA_LOG_MPT_SZ_OFFSET); 16435a2cc190SJeff Kirsher MLX4_PUT(inbox, param->mtt_base, INIT_HCA_MTT_BASE_OFFSET); 16445a2cc190SJeff Kirsher MLX4_PUT(inbox, param->cmpt_base, INIT_HCA_CMPT_BASE_OFFSET); 16455a2cc190SJeff Kirsher 16465a2cc190SJeff Kirsher /* UAR attributes */ 16475a2cc190SJeff Kirsher 1648ab9c17a0SJack Morgenstein MLX4_PUT(inbox, param->uar_page_sz, INIT_HCA_UAR_PAGE_SZ_OFFSET); 16495a2cc190SJeff Kirsher MLX4_PUT(inbox, param->log_uar_sz, INIT_HCA_LOG_UAR_SZ_OFFSET); 16505a2cc190SJeff Kirsher 16517ffdf726SOr Gerlitz /* set parser VXLAN attributes */ 16527ffdf726SOr Gerlitz if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS) { 16537ffdf726SOr Gerlitz u8 parser_params = 0; 16547ffdf726SOr Gerlitz MLX4_PUT(inbox, parser_params, INIT_HCA_VXLAN_OFFSET); 16557ffdf726SOr Gerlitz } 16567ffdf726SOr Gerlitz 1657f9baff50SJack Morgenstein err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_INIT_HCA, 10000, 1658f9baff50SJack Morgenstein MLX4_CMD_NATIVE); 16595a2cc190SJeff Kirsher 16605a2cc190SJeff Kirsher if (err) 16615a2cc190SJeff Kirsher mlx4_err(dev, "INIT_HCA returns %d\n", err); 16625a2cc190SJeff Kirsher 16635a2cc190SJeff Kirsher mlx4_free_cmd_mailbox(dev, mailbox); 16645a2cc190SJeff Kirsher return err; 16655a2cc190SJeff Kirsher } 16665a2cc190SJeff Kirsher 1667ab9c17a0SJack Morgenstein int mlx4_QUERY_HCA(struct mlx4_dev *dev, 1668ab9c17a0SJack Morgenstein struct mlx4_init_hca_param *param) 1669ab9c17a0SJack Morgenstein { 1670ab9c17a0SJack Morgenstein struct mlx4_cmd_mailbox *mailbox; 1671ab9c17a0SJack Morgenstein __be32 *outbox; 16727b8157beSJack Morgenstein u32 dword_field; 1673ab9c17a0SJack Morgenstein int err; 167408ff3235SOr Gerlitz u8 byte_field; 1675ab9c17a0SJack Morgenstein 1676ab9c17a0SJack Morgenstein #define QUERY_HCA_GLOBAL_CAPS_OFFSET 0x04 1677ddd8a6c1SEugenia Emantayev #define QUERY_HCA_CORE_CLOCK_OFFSET 0x0c 1678ab9c17a0SJack Morgenstein 1679ab9c17a0SJack Morgenstein mailbox = mlx4_alloc_cmd_mailbox(dev); 1680ab9c17a0SJack Morgenstein if (IS_ERR(mailbox)) 1681ab9c17a0SJack Morgenstein return PTR_ERR(mailbox); 1682ab9c17a0SJack Morgenstein outbox = mailbox->buf; 1683ab9c17a0SJack Morgenstein 1684ab9c17a0SJack Morgenstein err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, 1685ab9c17a0SJack Morgenstein MLX4_CMD_QUERY_HCA, 1686ab9c17a0SJack Morgenstein MLX4_CMD_TIME_CLASS_B, 1687ab9c17a0SJack Morgenstein !mlx4_is_slave(dev)); 1688ab9c17a0SJack Morgenstein if (err) 1689ab9c17a0SJack Morgenstein goto out; 1690ab9c17a0SJack Morgenstein 1691ab9c17a0SJack Morgenstein MLX4_GET(param->global_caps, outbox, QUERY_HCA_GLOBAL_CAPS_OFFSET); 1692ddd8a6c1SEugenia Emantayev MLX4_GET(param->hca_core_clock, outbox, QUERY_HCA_CORE_CLOCK_OFFSET); 1693ab9c17a0SJack Morgenstein 1694ab9c17a0SJack Morgenstein /* QPC/EEC/CQC/EQC/RDMARC attributes */ 1695ab9c17a0SJack Morgenstein 1696ab9c17a0SJack Morgenstein MLX4_GET(param->qpc_base, outbox, INIT_HCA_QPC_BASE_OFFSET); 1697ab9c17a0SJack Morgenstein MLX4_GET(param->log_num_qps, outbox, INIT_HCA_LOG_QP_OFFSET); 1698ab9c17a0SJack Morgenstein MLX4_GET(param->srqc_base, outbox, INIT_HCA_SRQC_BASE_OFFSET); 1699ab9c17a0SJack Morgenstein MLX4_GET(param->log_num_srqs, outbox, INIT_HCA_LOG_SRQ_OFFSET); 1700ab9c17a0SJack Morgenstein MLX4_GET(param->cqc_base, outbox, INIT_HCA_CQC_BASE_OFFSET); 1701ab9c17a0SJack Morgenstein MLX4_GET(param->log_num_cqs, outbox, INIT_HCA_LOG_CQ_OFFSET); 1702ab9c17a0SJack Morgenstein MLX4_GET(param->altc_base, outbox, INIT_HCA_ALTC_BASE_OFFSET); 1703ab9c17a0SJack Morgenstein MLX4_GET(param->auxc_base, outbox, INIT_HCA_AUXC_BASE_OFFSET); 1704ab9c17a0SJack Morgenstein MLX4_GET(param->eqc_base, outbox, INIT_HCA_EQC_BASE_OFFSET); 1705ab9c17a0SJack Morgenstein MLX4_GET(param->log_num_eqs, outbox, INIT_HCA_LOG_EQ_OFFSET); 1706*7ae0e400SMatan Barak MLX4_GET(param->num_sys_eqs, outbox, INIT_HCA_NUM_SYS_EQS_OFFSET); 1707ab9c17a0SJack Morgenstein MLX4_GET(param->rdmarc_base, outbox, INIT_HCA_RDMARC_BASE_OFFSET); 1708ab9c17a0SJack Morgenstein MLX4_GET(param->log_rd_per_qp, outbox, INIT_HCA_LOG_RD_OFFSET); 1709ab9c17a0SJack Morgenstein 17107b8157beSJack Morgenstein MLX4_GET(dword_field, outbox, INIT_HCA_FLAGS_OFFSET); 17117b8157beSJack Morgenstein if (dword_field & (1 << INIT_HCA_DEVICE_MANAGED_FLOW_STEERING_EN)) { 17127b8157beSJack Morgenstein param->steering_mode = MLX4_STEERING_MODE_DEVICE_MANAGED; 17137b8157beSJack Morgenstein } else { 17147b8157beSJack Morgenstein MLX4_GET(byte_field, outbox, INIT_HCA_UC_STEERING_OFFSET); 17157b8157beSJack Morgenstein if (byte_field & 0x8) 17167b8157beSJack Morgenstein param->steering_mode = MLX4_STEERING_MODE_B0; 17177b8157beSJack Morgenstein else 17187b8157beSJack Morgenstein param->steering_mode = MLX4_STEERING_MODE_A0; 17197b8157beSJack Morgenstein } 17200ff1fb65SHadar Hen Zion /* steering attributes */ 17217b8157beSJack Morgenstein if (param->steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) { 17220ff1fb65SHadar Hen Zion MLX4_GET(param->mc_base, outbox, INIT_HCA_FS_BASE_OFFSET); 17230ff1fb65SHadar Hen Zion MLX4_GET(param->log_mc_entry_sz, outbox, 17240ff1fb65SHadar Hen Zion INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); 17250ff1fb65SHadar Hen Zion MLX4_GET(param->log_mc_table_sz, outbox, 17260ff1fb65SHadar Hen Zion INIT_HCA_FS_LOG_TABLE_SZ_OFFSET); 17270ff1fb65SHadar Hen Zion } else { 1728ab9c17a0SJack Morgenstein MLX4_GET(param->mc_base, outbox, INIT_HCA_MC_BASE_OFFSET); 1729ab9c17a0SJack Morgenstein MLX4_GET(param->log_mc_entry_sz, outbox, 1730ab9c17a0SJack Morgenstein INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); 1731ab9c17a0SJack Morgenstein MLX4_GET(param->log_mc_hash_sz, outbox, 1732ab9c17a0SJack Morgenstein INIT_HCA_LOG_MC_HASH_SZ_OFFSET); 1733ab9c17a0SJack Morgenstein MLX4_GET(param->log_mc_table_sz, outbox, 1734ab9c17a0SJack Morgenstein INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); 17350ff1fb65SHadar Hen Zion } 1736ab9c17a0SJack Morgenstein 173708ff3235SOr Gerlitz /* CX3 is capable of extending CQEs/EQEs from 32 to 64 bytes */ 173808ff3235SOr Gerlitz MLX4_GET(byte_field, outbox, INIT_HCA_EQE_CQE_OFFSETS); 173908ff3235SOr Gerlitz if (byte_field & 0x20) /* 64-bytes eqe enabled */ 174008ff3235SOr Gerlitz param->dev_cap_enabled |= MLX4_DEV_CAP_64B_EQE_ENABLED; 174108ff3235SOr Gerlitz if (byte_field & 0x40) /* 64-bytes cqe enabled */ 174208ff3235SOr Gerlitz param->dev_cap_enabled |= MLX4_DEV_CAP_64B_CQE_ENABLED; 174308ff3235SOr Gerlitz 174477507aa2SIdo Shamay /* CX3 is capable of extending CQEs\EQEs to strides larger than 64B */ 174577507aa2SIdo Shamay MLX4_GET(byte_field, outbox, INIT_HCA_EQE_CQE_STRIDE_OFFSET); 174677507aa2SIdo Shamay if (byte_field) { 174777507aa2SIdo Shamay param->dev_cap_enabled |= MLX4_DEV_CAP_64B_EQE_ENABLED; 174877507aa2SIdo Shamay param->dev_cap_enabled |= MLX4_DEV_CAP_64B_CQE_ENABLED; 174977507aa2SIdo Shamay param->cqe_size = 1 << ((byte_field & 175077507aa2SIdo Shamay MLX4_CQE_SIZE_MASK_STRIDE) + 5); 175177507aa2SIdo Shamay param->eqe_size = 1 << (((byte_field & 175277507aa2SIdo Shamay MLX4_EQE_SIZE_MASK_STRIDE) >> 4) + 5); 175377507aa2SIdo Shamay } 175477507aa2SIdo Shamay 1755ab9c17a0SJack Morgenstein /* TPT attributes */ 1756ab9c17a0SJack Morgenstein 1757ab9c17a0SJack Morgenstein MLX4_GET(param->dmpt_base, outbox, INIT_HCA_DMPT_BASE_OFFSET); 1758e448834eSShani Michaeli MLX4_GET(param->mw_enabled, outbox, INIT_HCA_TPT_MW_OFFSET); 1759ab9c17a0SJack Morgenstein MLX4_GET(param->log_mpt_sz, outbox, INIT_HCA_LOG_MPT_SZ_OFFSET); 1760ab9c17a0SJack Morgenstein MLX4_GET(param->mtt_base, outbox, INIT_HCA_MTT_BASE_OFFSET); 1761ab9c17a0SJack Morgenstein MLX4_GET(param->cmpt_base, outbox, INIT_HCA_CMPT_BASE_OFFSET); 1762ab9c17a0SJack Morgenstein 1763ab9c17a0SJack Morgenstein /* UAR attributes */ 1764ab9c17a0SJack Morgenstein 1765ab9c17a0SJack Morgenstein MLX4_GET(param->uar_page_sz, outbox, INIT_HCA_UAR_PAGE_SZ_OFFSET); 1766ab9c17a0SJack Morgenstein MLX4_GET(param->log_uar_sz, outbox, INIT_HCA_LOG_UAR_SZ_OFFSET); 1767ab9c17a0SJack Morgenstein 1768ab9c17a0SJack Morgenstein out: 1769ab9c17a0SJack Morgenstein mlx4_free_cmd_mailbox(dev, mailbox); 1770ab9c17a0SJack Morgenstein 1771ab9c17a0SJack Morgenstein return err; 1772ab9c17a0SJack Morgenstein } 1773ab9c17a0SJack Morgenstein 1774980e9001SJack Morgenstein /* for IB-type ports only in SRIOV mode. Checks that both proxy QP0 1775980e9001SJack Morgenstein * and real QP0 are active, so that the paravirtualized QP0 is ready 1776980e9001SJack Morgenstein * to operate */ 1777980e9001SJack Morgenstein static int check_qp0_state(struct mlx4_dev *dev, int function, int port) 1778980e9001SJack Morgenstein { 1779980e9001SJack Morgenstein struct mlx4_priv *priv = mlx4_priv(dev); 1780980e9001SJack Morgenstein /* irrelevant if not infiniband */ 1781980e9001SJack Morgenstein if (priv->mfunc.master.qp0_state[port].proxy_qp0_active && 1782980e9001SJack Morgenstein priv->mfunc.master.qp0_state[port].qp0_active) 1783980e9001SJack Morgenstein return 1; 1784980e9001SJack Morgenstein return 0; 1785980e9001SJack Morgenstein } 1786980e9001SJack Morgenstein 17875cc914f1SMarcel Apfelbaum int mlx4_INIT_PORT_wrapper(struct mlx4_dev *dev, int slave, 17885cc914f1SMarcel Apfelbaum struct mlx4_vhcr *vhcr, 17895cc914f1SMarcel Apfelbaum struct mlx4_cmd_mailbox *inbox, 17905cc914f1SMarcel Apfelbaum struct mlx4_cmd_mailbox *outbox, 17915cc914f1SMarcel Apfelbaum struct mlx4_cmd_info *cmd) 17925cc914f1SMarcel Apfelbaum { 17935cc914f1SMarcel Apfelbaum struct mlx4_priv *priv = mlx4_priv(dev); 1794449fc488SMatan Barak int port = mlx4_slave_convert_port(dev, slave, vhcr->in_modifier); 17955cc914f1SMarcel Apfelbaum int err; 17965cc914f1SMarcel Apfelbaum 1797449fc488SMatan Barak if (port < 0) 1798449fc488SMatan Barak return -EINVAL; 1799449fc488SMatan Barak 18005cc914f1SMarcel Apfelbaum if (priv->mfunc.master.slave_state[slave].init_port_mask & (1 << port)) 18015cc914f1SMarcel Apfelbaum return 0; 18025cc914f1SMarcel Apfelbaum 1803980e9001SJack Morgenstein if (dev->caps.port_mask[port] != MLX4_PORT_TYPE_IB) { 18045cc914f1SMarcel Apfelbaum /* Enable port only if it was previously disabled */ 18055cc914f1SMarcel Apfelbaum if (!priv->mfunc.master.init_port_ref[port]) { 18065cc914f1SMarcel Apfelbaum err = mlx4_cmd(dev, 0, port, 0, MLX4_CMD_INIT_PORT, 18075cc914f1SMarcel Apfelbaum MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 18085cc914f1SMarcel Apfelbaum if (err) 18095cc914f1SMarcel Apfelbaum return err; 18105cc914f1SMarcel Apfelbaum } 18118bac9edeSJack Morgenstein priv->mfunc.master.slave_state[slave].init_port_mask |= (1 << port); 1812980e9001SJack Morgenstein } else { 1813980e9001SJack Morgenstein if (slave == mlx4_master_func_num(dev)) { 1814980e9001SJack Morgenstein if (check_qp0_state(dev, slave, port) && 1815980e9001SJack Morgenstein !priv->mfunc.master.qp0_state[port].port_active) { 1816980e9001SJack Morgenstein err = mlx4_cmd(dev, 0, port, 0, MLX4_CMD_INIT_PORT, 1817980e9001SJack Morgenstein MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 1818980e9001SJack Morgenstein if (err) 1819980e9001SJack Morgenstein return err; 1820980e9001SJack Morgenstein priv->mfunc.master.qp0_state[port].port_active = 1; 1821980e9001SJack Morgenstein priv->mfunc.master.slave_state[slave].init_port_mask |= (1 << port); 1822980e9001SJack Morgenstein } 1823980e9001SJack Morgenstein } else 1824980e9001SJack Morgenstein priv->mfunc.master.slave_state[slave].init_port_mask |= (1 << port); 1825980e9001SJack Morgenstein } 18265cc914f1SMarcel Apfelbaum ++priv->mfunc.master.init_port_ref[port]; 18275cc914f1SMarcel Apfelbaum return 0; 18285cc914f1SMarcel Apfelbaum } 18295cc914f1SMarcel Apfelbaum 18305a2cc190SJeff Kirsher int mlx4_INIT_PORT(struct mlx4_dev *dev, int port) 18315a2cc190SJeff Kirsher { 18325a2cc190SJeff Kirsher struct mlx4_cmd_mailbox *mailbox; 18335a2cc190SJeff Kirsher u32 *inbox; 18345a2cc190SJeff Kirsher int err; 18355a2cc190SJeff Kirsher u32 flags; 18365a2cc190SJeff Kirsher u16 field; 18375a2cc190SJeff Kirsher 18385a2cc190SJeff Kirsher if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { 18395a2cc190SJeff Kirsher #define INIT_PORT_IN_SIZE 256 18405a2cc190SJeff Kirsher #define INIT_PORT_FLAGS_OFFSET 0x00 18415a2cc190SJeff Kirsher #define INIT_PORT_FLAG_SIG (1 << 18) 18425a2cc190SJeff Kirsher #define INIT_PORT_FLAG_NG (1 << 17) 18435a2cc190SJeff Kirsher #define INIT_PORT_FLAG_G0 (1 << 16) 18445a2cc190SJeff Kirsher #define INIT_PORT_VL_SHIFT 4 18455a2cc190SJeff Kirsher #define INIT_PORT_PORT_WIDTH_SHIFT 8 18465a2cc190SJeff Kirsher #define INIT_PORT_MTU_OFFSET 0x04 18475a2cc190SJeff Kirsher #define INIT_PORT_MAX_GID_OFFSET 0x06 18485a2cc190SJeff Kirsher #define INIT_PORT_MAX_PKEY_OFFSET 0x0a 18495a2cc190SJeff Kirsher #define INIT_PORT_GUID0_OFFSET 0x10 18505a2cc190SJeff Kirsher #define INIT_PORT_NODE_GUID_OFFSET 0x18 18515a2cc190SJeff Kirsher #define INIT_PORT_SI_GUID_OFFSET 0x20 18525a2cc190SJeff Kirsher 18535a2cc190SJeff Kirsher mailbox = mlx4_alloc_cmd_mailbox(dev); 18545a2cc190SJeff Kirsher if (IS_ERR(mailbox)) 18555a2cc190SJeff Kirsher return PTR_ERR(mailbox); 18565a2cc190SJeff Kirsher inbox = mailbox->buf; 18575a2cc190SJeff Kirsher 18585a2cc190SJeff Kirsher flags = 0; 18595a2cc190SJeff Kirsher flags |= (dev->caps.vl_cap[port] & 0xf) << INIT_PORT_VL_SHIFT; 18605a2cc190SJeff Kirsher flags |= (dev->caps.port_width_cap[port] & 0xf) << INIT_PORT_PORT_WIDTH_SHIFT; 18615a2cc190SJeff Kirsher MLX4_PUT(inbox, flags, INIT_PORT_FLAGS_OFFSET); 18625a2cc190SJeff Kirsher 18635a2cc190SJeff Kirsher field = 128 << dev->caps.ib_mtu_cap[port]; 18645a2cc190SJeff Kirsher MLX4_PUT(inbox, field, INIT_PORT_MTU_OFFSET); 18655a2cc190SJeff Kirsher field = dev->caps.gid_table_len[port]; 18665a2cc190SJeff Kirsher MLX4_PUT(inbox, field, INIT_PORT_MAX_GID_OFFSET); 18675a2cc190SJeff Kirsher field = dev->caps.pkey_table_len[port]; 18685a2cc190SJeff Kirsher MLX4_PUT(inbox, field, INIT_PORT_MAX_PKEY_OFFSET); 18695a2cc190SJeff Kirsher 18705a2cc190SJeff Kirsher err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_INIT_PORT, 1871f9baff50SJack Morgenstein MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 18725a2cc190SJeff Kirsher 18735a2cc190SJeff Kirsher mlx4_free_cmd_mailbox(dev, mailbox); 18745a2cc190SJeff Kirsher } else 18755a2cc190SJeff Kirsher err = mlx4_cmd(dev, 0, port, 0, MLX4_CMD_INIT_PORT, 1876f9baff50SJack Morgenstein MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); 18775a2cc190SJeff Kirsher 18785a2cc190SJeff Kirsher return err; 18795a2cc190SJeff Kirsher } 18805a2cc190SJeff Kirsher EXPORT_SYMBOL_GPL(mlx4_INIT_PORT); 18815a2cc190SJeff Kirsher 18825cc914f1SMarcel Apfelbaum int mlx4_CLOSE_PORT_wrapper(struct mlx4_dev *dev, int slave, 18835cc914f1SMarcel Apfelbaum struct mlx4_vhcr *vhcr, 18845cc914f1SMarcel Apfelbaum struct mlx4_cmd_mailbox *inbox, 18855cc914f1SMarcel Apfelbaum struct mlx4_cmd_mailbox *outbox, 18865cc914f1SMarcel Apfelbaum struct mlx4_cmd_info *cmd) 18875cc914f1SMarcel Apfelbaum { 18885cc914f1SMarcel Apfelbaum struct mlx4_priv *priv = mlx4_priv(dev); 1889449fc488SMatan Barak int port = mlx4_slave_convert_port(dev, slave, vhcr->in_modifier); 18905cc914f1SMarcel Apfelbaum int err; 18915cc914f1SMarcel Apfelbaum 1892449fc488SMatan Barak if (port < 0) 1893449fc488SMatan Barak return -EINVAL; 1894449fc488SMatan Barak 18955cc914f1SMarcel Apfelbaum if (!(priv->mfunc.master.slave_state[slave].init_port_mask & 18965cc914f1SMarcel Apfelbaum (1 << port))) 18975cc914f1SMarcel Apfelbaum return 0; 18985cc914f1SMarcel Apfelbaum 1899980e9001SJack Morgenstein if (dev->caps.port_mask[port] != MLX4_PORT_TYPE_IB) { 19005cc914f1SMarcel Apfelbaum if (priv->mfunc.master.init_port_ref[port] == 1) { 1901980e9001SJack Morgenstein err = mlx4_cmd(dev, 0, port, 0, MLX4_CMD_CLOSE_PORT, 1902980e9001SJack Morgenstein 1000, MLX4_CMD_NATIVE); 19035cc914f1SMarcel Apfelbaum if (err) 19045cc914f1SMarcel Apfelbaum return err; 19055cc914f1SMarcel Apfelbaum } 19065cc914f1SMarcel Apfelbaum priv->mfunc.master.slave_state[slave].init_port_mask &= ~(1 << port); 1907980e9001SJack Morgenstein } else { 1908980e9001SJack Morgenstein /* infiniband port */ 1909980e9001SJack Morgenstein if (slave == mlx4_master_func_num(dev)) { 1910980e9001SJack Morgenstein if (!priv->mfunc.master.qp0_state[port].qp0_active && 1911980e9001SJack Morgenstein priv->mfunc.master.qp0_state[port].port_active) { 1912980e9001SJack Morgenstein err = mlx4_cmd(dev, 0, port, 0, MLX4_CMD_CLOSE_PORT, 1913980e9001SJack Morgenstein 1000, MLX4_CMD_NATIVE); 1914980e9001SJack Morgenstein if (err) 1915980e9001SJack Morgenstein return err; 1916980e9001SJack Morgenstein priv->mfunc.master.slave_state[slave].init_port_mask &= ~(1 << port); 1917980e9001SJack Morgenstein priv->mfunc.master.qp0_state[port].port_active = 0; 1918980e9001SJack Morgenstein } 1919980e9001SJack Morgenstein } else 1920980e9001SJack Morgenstein priv->mfunc.master.slave_state[slave].init_port_mask &= ~(1 << port); 1921980e9001SJack Morgenstein } 19225cc914f1SMarcel Apfelbaum --priv->mfunc.master.init_port_ref[port]; 19235cc914f1SMarcel Apfelbaum return 0; 19245cc914f1SMarcel Apfelbaum } 19255cc914f1SMarcel Apfelbaum 19265a2cc190SJeff Kirsher int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port) 19275a2cc190SJeff Kirsher { 1928f9baff50SJack Morgenstein return mlx4_cmd(dev, 0, port, 0, MLX4_CMD_CLOSE_PORT, 1000, 1929f9baff50SJack Morgenstein MLX4_CMD_WRAPPED); 19305a2cc190SJeff Kirsher } 19315a2cc190SJeff Kirsher EXPORT_SYMBOL_GPL(mlx4_CLOSE_PORT); 19325a2cc190SJeff Kirsher 19335a2cc190SJeff Kirsher int mlx4_CLOSE_HCA(struct mlx4_dev *dev, int panic) 19345a2cc190SJeff Kirsher { 1935f9baff50SJack Morgenstein return mlx4_cmd(dev, 0, 0, panic, MLX4_CMD_CLOSE_HCA, 1000, 1936f9baff50SJack Morgenstein MLX4_CMD_NATIVE); 19375a2cc190SJeff Kirsher } 19385a2cc190SJeff Kirsher 1939d18f141aSOr Gerlitz struct mlx4_config_dev { 1940d18f141aSOr Gerlitz __be32 update_flags; 1941d475c95bSMatan Barak __be32 rsvd1[3]; 1942d18f141aSOr Gerlitz __be16 vxlan_udp_dport; 1943d18f141aSOr Gerlitz __be16 rsvd2; 1944d475c95bSMatan Barak __be32 rsvd3[27]; 1945d475c95bSMatan Barak __be16 rsvd4; 1946d475c95bSMatan Barak u8 rsvd5; 1947d475c95bSMatan Barak u8 rx_checksum_val; 1948d18f141aSOr Gerlitz }; 1949d18f141aSOr Gerlitz 1950d18f141aSOr Gerlitz #define MLX4_VXLAN_UDP_DPORT (1 << 0) 1951d18f141aSOr Gerlitz 1952d475c95bSMatan Barak static int mlx4_CONFIG_DEV_set(struct mlx4_dev *dev, struct mlx4_config_dev *config_dev) 1953d18f141aSOr Gerlitz { 1954d18f141aSOr Gerlitz int err; 1955d18f141aSOr Gerlitz struct mlx4_cmd_mailbox *mailbox; 1956d18f141aSOr Gerlitz 1957d18f141aSOr Gerlitz mailbox = mlx4_alloc_cmd_mailbox(dev); 1958d18f141aSOr Gerlitz if (IS_ERR(mailbox)) 1959d18f141aSOr Gerlitz return PTR_ERR(mailbox); 1960d18f141aSOr Gerlitz 1961d18f141aSOr Gerlitz memcpy(mailbox->buf, config_dev, sizeof(*config_dev)); 1962d18f141aSOr Gerlitz 1963d18f141aSOr Gerlitz err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_CONFIG_DEV, 1964d18f141aSOr Gerlitz MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 1965d18f141aSOr Gerlitz 1966d18f141aSOr Gerlitz mlx4_free_cmd_mailbox(dev, mailbox); 1967d18f141aSOr Gerlitz return err; 1968d18f141aSOr Gerlitz } 1969d18f141aSOr Gerlitz 1970d475c95bSMatan Barak static int mlx4_CONFIG_DEV_get(struct mlx4_dev *dev, struct mlx4_config_dev *config_dev) 1971d475c95bSMatan Barak { 1972d475c95bSMatan Barak int err; 1973d475c95bSMatan Barak struct mlx4_cmd_mailbox *mailbox; 1974d475c95bSMatan Barak 1975d475c95bSMatan Barak mailbox = mlx4_alloc_cmd_mailbox(dev); 1976d475c95bSMatan Barak if (IS_ERR(mailbox)) 1977d475c95bSMatan Barak return PTR_ERR(mailbox); 1978d475c95bSMatan Barak 1979d475c95bSMatan Barak err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 1, MLX4_CMD_CONFIG_DEV, 1980d475c95bSMatan Barak MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 1981d475c95bSMatan Barak 1982d475c95bSMatan Barak if (!err) 1983d475c95bSMatan Barak memcpy(config_dev, mailbox->buf, sizeof(*config_dev)); 1984d475c95bSMatan Barak 1985d475c95bSMatan Barak mlx4_free_cmd_mailbox(dev, mailbox); 1986d475c95bSMatan Barak return err; 1987d475c95bSMatan Barak } 1988d475c95bSMatan Barak 1989d475c95bSMatan Barak /* Conversion between the HW values and the actual functionality. 1990d475c95bSMatan Barak * The value represented by the array index, 1991d475c95bSMatan Barak * and the functionality determined by the flags. 1992d475c95bSMatan Barak */ 1993d475c95bSMatan Barak static const u8 config_dev_csum_flags[] = { 1994d475c95bSMatan Barak [0] = 0, 1995d475c95bSMatan Barak [1] = MLX4_RX_CSUM_MODE_VAL_NON_TCP_UDP, 1996d475c95bSMatan Barak [2] = MLX4_RX_CSUM_MODE_VAL_NON_TCP_UDP | 1997d475c95bSMatan Barak MLX4_RX_CSUM_MODE_L4, 1998d475c95bSMatan Barak [3] = MLX4_RX_CSUM_MODE_L4 | 1999d475c95bSMatan Barak MLX4_RX_CSUM_MODE_IP_OK_IP_NON_TCP_UDP | 2000d475c95bSMatan Barak MLX4_RX_CSUM_MODE_MULTI_VLAN 2001d475c95bSMatan Barak }; 2002d475c95bSMatan Barak 2003d475c95bSMatan Barak int mlx4_config_dev_retrieval(struct mlx4_dev *dev, 2004d475c95bSMatan Barak struct mlx4_config_dev_params *params) 2005d475c95bSMatan Barak { 2006d475c95bSMatan Barak struct mlx4_config_dev config_dev; 2007d475c95bSMatan Barak int err; 2008d475c95bSMatan Barak u8 csum_mask; 2009d475c95bSMatan Barak 2010d475c95bSMatan Barak #define CONFIG_DEV_RX_CSUM_MODE_MASK 0x7 2011d475c95bSMatan Barak #define CONFIG_DEV_RX_CSUM_MODE_PORT1_BIT_OFFSET 0 2012d475c95bSMatan Barak #define CONFIG_DEV_RX_CSUM_MODE_PORT2_BIT_OFFSET 4 2013d475c95bSMatan Barak 2014d475c95bSMatan Barak if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_CONFIG_DEV)) 2015d475c95bSMatan Barak return -ENOTSUPP; 2016d475c95bSMatan Barak 2017d475c95bSMatan Barak err = mlx4_CONFIG_DEV_get(dev, &config_dev); 2018d475c95bSMatan Barak if (err) 2019d475c95bSMatan Barak return err; 2020d475c95bSMatan Barak 2021d475c95bSMatan Barak csum_mask = (config_dev.rx_checksum_val >> CONFIG_DEV_RX_CSUM_MODE_PORT1_BIT_OFFSET) & 2022d475c95bSMatan Barak CONFIG_DEV_RX_CSUM_MODE_MASK; 2023d475c95bSMatan Barak 2024d475c95bSMatan Barak if (csum_mask >= sizeof(config_dev_csum_flags)/sizeof(config_dev_csum_flags[0])) 2025d475c95bSMatan Barak return -EINVAL; 2026d475c95bSMatan Barak params->rx_csum_flags_port_1 = config_dev_csum_flags[csum_mask]; 2027d475c95bSMatan Barak 2028d475c95bSMatan Barak csum_mask = (config_dev.rx_checksum_val >> CONFIG_DEV_RX_CSUM_MODE_PORT2_BIT_OFFSET) & 2029d475c95bSMatan Barak CONFIG_DEV_RX_CSUM_MODE_MASK; 2030d475c95bSMatan Barak 2031d475c95bSMatan Barak if (csum_mask >= sizeof(config_dev_csum_flags)/sizeof(config_dev_csum_flags[0])) 2032d475c95bSMatan Barak return -EINVAL; 2033d475c95bSMatan Barak params->rx_csum_flags_port_2 = config_dev_csum_flags[csum_mask]; 2034d475c95bSMatan Barak 2035d475c95bSMatan Barak params->vxlan_udp_dport = be16_to_cpu(config_dev.vxlan_udp_dport); 2036d475c95bSMatan Barak 2037d475c95bSMatan Barak return 0; 2038d475c95bSMatan Barak } 2039d475c95bSMatan Barak EXPORT_SYMBOL_GPL(mlx4_config_dev_retrieval); 2040d475c95bSMatan Barak 2041d18f141aSOr Gerlitz int mlx4_config_vxlan_port(struct mlx4_dev *dev, __be16 udp_port) 2042d18f141aSOr Gerlitz { 2043d18f141aSOr Gerlitz struct mlx4_config_dev config_dev; 2044d18f141aSOr Gerlitz 2045d18f141aSOr Gerlitz memset(&config_dev, 0, sizeof(config_dev)); 2046d18f141aSOr Gerlitz config_dev.update_flags = cpu_to_be32(MLX4_VXLAN_UDP_DPORT); 2047d18f141aSOr Gerlitz config_dev.vxlan_udp_dport = udp_port; 2048d18f141aSOr Gerlitz 2049d475c95bSMatan Barak return mlx4_CONFIG_DEV_set(dev, &config_dev); 2050d18f141aSOr Gerlitz } 2051d18f141aSOr Gerlitz EXPORT_SYMBOL_GPL(mlx4_config_vxlan_port); 2052d18f141aSOr Gerlitz 2053d18f141aSOr Gerlitz 20545a2cc190SJeff Kirsher int mlx4_SET_ICM_SIZE(struct mlx4_dev *dev, u64 icm_size, u64 *aux_pages) 20555a2cc190SJeff Kirsher { 20565a2cc190SJeff Kirsher int ret = mlx4_cmd_imm(dev, icm_size, aux_pages, 0, 0, 20575a2cc190SJeff Kirsher MLX4_CMD_SET_ICM_SIZE, 2058f9baff50SJack Morgenstein MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 20595a2cc190SJeff Kirsher if (ret) 20605a2cc190SJeff Kirsher return ret; 20615a2cc190SJeff Kirsher 20625a2cc190SJeff Kirsher /* 20635a2cc190SJeff Kirsher * Round up number of system pages needed in case 20645a2cc190SJeff Kirsher * MLX4_ICM_PAGE_SIZE < PAGE_SIZE. 20655a2cc190SJeff Kirsher */ 20665a2cc190SJeff Kirsher *aux_pages = ALIGN(*aux_pages, PAGE_SIZE / MLX4_ICM_PAGE_SIZE) >> 20675a2cc190SJeff Kirsher (PAGE_SHIFT - MLX4_ICM_PAGE_SHIFT); 20685a2cc190SJeff Kirsher 20695a2cc190SJeff Kirsher return 0; 20705a2cc190SJeff Kirsher } 20715a2cc190SJeff Kirsher 20725a2cc190SJeff Kirsher int mlx4_NOP(struct mlx4_dev *dev) 20735a2cc190SJeff Kirsher { 20745a2cc190SJeff Kirsher /* Input modifier of 0x1f means "finish as soon as possible." */ 2075f9baff50SJack Morgenstein return mlx4_cmd(dev, 0, 0x1f, 0, MLX4_CMD_NOP, 100, MLX4_CMD_NATIVE); 20765a2cc190SJeff Kirsher } 20775a2cc190SJeff Kirsher 20788e1a28e8SHadar Hen Zion int mlx4_get_phys_port_id(struct mlx4_dev *dev) 20798e1a28e8SHadar Hen Zion { 20808e1a28e8SHadar Hen Zion u8 port; 20818e1a28e8SHadar Hen Zion u32 *outbox; 20828e1a28e8SHadar Hen Zion struct mlx4_cmd_mailbox *mailbox; 20838e1a28e8SHadar Hen Zion u32 in_mod; 20848e1a28e8SHadar Hen Zion u32 guid_hi, guid_lo; 20858e1a28e8SHadar Hen Zion int err, ret = 0; 20868e1a28e8SHadar Hen Zion #define MOD_STAT_CFG_PORT_OFFSET 8 20878e1a28e8SHadar Hen Zion #define MOD_STAT_CFG_GUID_H 0X14 20888e1a28e8SHadar Hen Zion #define MOD_STAT_CFG_GUID_L 0X1c 20898e1a28e8SHadar Hen Zion 20908e1a28e8SHadar Hen Zion mailbox = mlx4_alloc_cmd_mailbox(dev); 20918e1a28e8SHadar Hen Zion if (IS_ERR(mailbox)) 20928e1a28e8SHadar Hen Zion return PTR_ERR(mailbox); 20938e1a28e8SHadar Hen Zion outbox = mailbox->buf; 20948e1a28e8SHadar Hen Zion 20958e1a28e8SHadar Hen Zion for (port = 1; port <= dev->caps.num_ports; port++) { 20968e1a28e8SHadar Hen Zion in_mod = port << MOD_STAT_CFG_PORT_OFFSET; 20978e1a28e8SHadar Hen Zion err = mlx4_cmd_box(dev, 0, mailbox->dma, in_mod, 0x2, 20988e1a28e8SHadar Hen Zion MLX4_CMD_MOD_STAT_CFG, MLX4_CMD_TIME_CLASS_A, 20998e1a28e8SHadar Hen Zion MLX4_CMD_NATIVE); 21008e1a28e8SHadar Hen Zion if (err) { 21018e1a28e8SHadar Hen Zion mlx4_err(dev, "Fail to get port %d uplink guid\n", 21028e1a28e8SHadar Hen Zion port); 21038e1a28e8SHadar Hen Zion ret = err; 21048e1a28e8SHadar Hen Zion } else { 21058e1a28e8SHadar Hen Zion MLX4_GET(guid_hi, outbox, MOD_STAT_CFG_GUID_H); 21068e1a28e8SHadar Hen Zion MLX4_GET(guid_lo, outbox, MOD_STAT_CFG_GUID_L); 21078e1a28e8SHadar Hen Zion dev->caps.phys_port_id[port] = (u64)guid_lo | 21088e1a28e8SHadar Hen Zion (u64)guid_hi << 32; 21098e1a28e8SHadar Hen Zion } 21108e1a28e8SHadar Hen Zion } 21118e1a28e8SHadar Hen Zion mlx4_free_cmd_mailbox(dev, mailbox); 21128e1a28e8SHadar Hen Zion return ret; 21138e1a28e8SHadar Hen Zion } 21148e1a28e8SHadar Hen Zion 21155a2cc190SJeff Kirsher #define MLX4_WOL_SETUP_MODE (5 << 28) 21165a2cc190SJeff Kirsher int mlx4_wol_read(struct mlx4_dev *dev, u64 *config, int port) 21175a2cc190SJeff Kirsher { 21185a2cc190SJeff Kirsher u32 in_mod = MLX4_WOL_SETUP_MODE | port << 8; 21195a2cc190SJeff Kirsher 21205a2cc190SJeff Kirsher return mlx4_cmd_imm(dev, 0, config, in_mod, 0x3, 2121f9baff50SJack Morgenstein MLX4_CMD_MOD_STAT_CFG, MLX4_CMD_TIME_CLASS_A, 2122f9baff50SJack Morgenstein MLX4_CMD_NATIVE); 21235a2cc190SJeff Kirsher } 21245a2cc190SJeff Kirsher EXPORT_SYMBOL_GPL(mlx4_wol_read); 21255a2cc190SJeff Kirsher 21265a2cc190SJeff Kirsher int mlx4_wol_write(struct mlx4_dev *dev, u64 config, int port) 21275a2cc190SJeff Kirsher { 21285a2cc190SJeff Kirsher u32 in_mod = MLX4_WOL_SETUP_MODE | port << 8; 21295a2cc190SJeff Kirsher 21305a2cc190SJeff Kirsher return mlx4_cmd(dev, config, in_mod, 0x1, MLX4_CMD_MOD_STAT_CFG, 2131f9baff50SJack Morgenstein MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); 21325a2cc190SJeff Kirsher } 21335a2cc190SJeff Kirsher EXPORT_SYMBOL_GPL(mlx4_wol_write); 2134fe6f700dSYevgeny Petrilin 2135fe6f700dSYevgeny Petrilin enum { 2136fe6f700dSYevgeny Petrilin ADD_TO_MCG = 0x26, 2137fe6f700dSYevgeny Petrilin }; 2138fe6f700dSYevgeny Petrilin 2139fe6f700dSYevgeny Petrilin 2140fe6f700dSYevgeny Petrilin void mlx4_opreq_action(struct work_struct *work) 2141fe6f700dSYevgeny Petrilin { 2142fe6f700dSYevgeny Petrilin struct mlx4_priv *priv = container_of(work, struct mlx4_priv, 2143fe6f700dSYevgeny Petrilin opreq_task); 2144fe6f700dSYevgeny Petrilin struct mlx4_dev *dev = &priv->dev; 2145fe6f700dSYevgeny Petrilin int num_tasks = atomic_read(&priv->opreq_count); 2146fe6f700dSYevgeny Petrilin struct mlx4_cmd_mailbox *mailbox; 2147fe6f700dSYevgeny Petrilin struct mlx4_mgm *mgm; 2148fe6f700dSYevgeny Petrilin u32 *outbox; 2149fe6f700dSYevgeny Petrilin u32 modifier; 2150fe6f700dSYevgeny Petrilin u16 token; 2151fe6f700dSYevgeny Petrilin u16 type; 2152fe6f700dSYevgeny Petrilin int err; 2153fe6f700dSYevgeny Petrilin u32 num_qps; 2154fe6f700dSYevgeny Petrilin struct mlx4_qp qp; 2155fe6f700dSYevgeny Petrilin int i; 2156fe6f700dSYevgeny Petrilin u8 rem_mcg; 2157fe6f700dSYevgeny Petrilin u8 prot; 2158fe6f700dSYevgeny Petrilin 2159fe6f700dSYevgeny Petrilin #define GET_OP_REQ_MODIFIER_OFFSET 0x08 2160fe6f700dSYevgeny Petrilin #define GET_OP_REQ_TOKEN_OFFSET 0x14 2161fe6f700dSYevgeny Petrilin #define GET_OP_REQ_TYPE_OFFSET 0x1a 2162fe6f700dSYevgeny Petrilin #define GET_OP_REQ_DATA_OFFSET 0x20 2163fe6f700dSYevgeny Petrilin 2164fe6f700dSYevgeny Petrilin mailbox = mlx4_alloc_cmd_mailbox(dev); 2165fe6f700dSYevgeny Petrilin if (IS_ERR(mailbox)) { 2166fe6f700dSYevgeny Petrilin mlx4_err(dev, "Failed to allocate mailbox for GET_OP_REQ\n"); 2167fe6f700dSYevgeny Petrilin return; 2168fe6f700dSYevgeny Petrilin } 2169fe6f700dSYevgeny Petrilin outbox = mailbox->buf; 2170fe6f700dSYevgeny Petrilin 2171fe6f700dSYevgeny Petrilin while (num_tasks) { 2172fe6f700dSYevgeny Petrilin err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, 2173fe6f700dSYevgeny Petrilin MLX4_CMD_GET_OP_REQ, MLX4_CMD_TIME_CLASS_A, 2174fe6f700dSYevgeny Petrilin MLX4_CMD_NATIVE); 2175fe6f700dSYevgeny Petrilin if (err) { 21766d3be300SMasanari Iida mlx4_err(dev, "Failed to retrieve required operation: %d\n", 2177fe6f700dSYevgeny Petrilin err); 2178fe6f700dSYevgeny Petrilin return; 2179fe6f700dSYevgeny Petrilin } 2180fe6f700dSYevgeny Petrilin MLX4_GET(modifier, outbox, GET_OP_REQ_MODIFIER_OFFSET); 2181fe6f700dSYevgeny Petrilin MLX4_GET(token, outbox, GET_OP_REQ_TOKEN_OFFSET); 2182fe6f700dSYevgeny Petrilin MLX4_GET(type, outbox, GET_OP_REQ_TYPE_OFFSET); 2183fe6f700dSYevgeny Petrilin type &= 0xfff; 2184fe6f700dSYevgeny Petrilin 2185fe6f700dSYevgeny Petrilin switch (type) { 2186fe6f700dSYevgeny Petrilin case ADD_TO_MCG: 2187fe6f700dSYevgeny Petrilin if (dev->caps.steering_mode == 2188fe6f700dSYevgeny Petrilin MLX4_STEERING_MODE_DEVICE_MANAGED) { 2189fe6f700dSYevgeny Petrilin mlx4_warn(dev, "ADD MCG operation is not supported in DEVICE_MANAGED steering mode\n"); 2190fe6f700dSYevgeny Petrilin err = EPERM; 2191fe6f700dSYevgeny Petrilin break; 2192fe6f700dSYevgeny Petrilin } 2193fe6f700dSYevgeny Petrilin mgm = (struct mlx4_mgm *)((u8 *)(outbox) + 2194fe6f700dSYevgeny Petrilin GET_OP_REQ_DATA_OFFSET); 2195fe6f700dSYevgeny Petrilin num_qps = be32_to_cpu(mgm->members_count) & 2196fe6f700dSYevgeny Petrilin MGM_QPN_MASK; 2197fe6f700dSYevgeny Petrilin rem_mcg = ((u8 *)(&mgm->members_count))[0] & 1; 2198fe6f700dSYevgeny Petrilin prot = ((u8 *)(&mgm->members_count))[0] >> 6; 2199fe6f700dSYevgeny Petrilin 2200fe6f700dSYevgeny Petrilin for (i = 0; i < num_qps; i++) { 2201fe6f700dSYevgeny Petrilin qp.qpn = be32_to_cpu(mgm->qp[i]); 2202fe6f700dSYevgeny Petrilin if (rem_mcg) 2203fe6f700dSYevgeny Petrilin err = mlx4_multicast_detach(dev, &qp, 2204fe6f700dSYevgeny Petrilin mgm->gid, 2205fe6f700dSYevgeny Petrilin prot, 0); 2206fe6f700dSYevgeny Petrilin else 2207fe6f700dSYevgeny Petrilin err = mlx4_multicast_attach(dev, &qp, 2208fe6f700dSYevgeny Petrilin mgm->gid, 2209fe6f700dSYevgeny Petrilin mgm->gid[5] 2210fe6f700dSYevgeny Petrilin , 0, prot, 2211fe6f700dSYevgeny Petrilin NULL); 2212fe6f700dSYevgeny Petrilin if (err) 2213fe6f700dSYevgeny Petrilin break; 2214fe6f700dSYevgeny Petrilin } 2215fe6f700dSYevgeny Petrilin break; 2216fe6f700dSYevgeny Petrilin default: 2217fe6f700dSYevgeny Petrilin mlx4_warn(dev, "Bad type for required operation\n"); 2218fe6f700dSYevgeny Petrilin err = EINVAL; 2219fe6f700dSYevgeny Petrilin break; 2220fe6f700dSYevgeny Petrilin } 222128d222bbSEyal Perry err = mlx4_cmd(dev, 0, ((u32) err | 222228d222bbSEyal Perry (__force u32)cpu_to_be32(token) << 16), 2223fe6f700dSYevgeny Petrilin 1, MLX4_CMD_GET_OP_REQ, MLX4_CMD_TIME_CLASS_A, 2224fe6f700dSYevgeny Petrilin MLX4_CMD_NATIVE); 2225fe6f700dSYevgeny Petrilin if (err) { 2226fe6f700dSYevgeny Petrilin mlx4_err(dev, "Failed to acknowledge required request: %d\n", 2227fe6f700dSYevgeny Petrilin err); 2228fe6f700dSYevgeny Petrilin goto out; 2229fe6f700dSYevgeny Petrilin } 2230fe6f700dSYevgeny Petrilin memset(outbox, 0, 0xffc); 2231fe6f700dSYevgeny Petrilin num_tasks = atomic_dec_return(&priv->opreq_count); 2232fe6f700dSYevgeny Petrilin } 2233fe6f700dSYevgeny Petrilin 2234fe6f700dSYevgeny Petrilin out: 2235fe6f700dSYevgeny Petrilin mlx4_free_cmd_mailbox(dev, mailbox); 2236fe6f700dSYevgeny Petrilin } 2237114840c3SJack Morgenstein 2238114840c3SJack Morgenstein static int mlx4_check_smp_firewall_active(struct mlx4_dev *dev, 2239114840c3SJack Morgenstein struct mlx4_cmd_mailbox *mailbox) 2240114840c3SJack Morgenstein { 2241114840c3SJack Morgenstein #define MLX4_CMD_MAD_DEMUX_SET_ATTR_OFFSET 0x10 2242114840c3SJack Morgenstein #define MLX4_CMD_MAD_DEMUX_GETRESP_ATTR_OFFSET 0x20 2243114840c3SJack Morgenstein #define MLX4_CMD_MAD_DEMUX_TRAP_ATTR_OFFSET 0x40 2244114840c3SJack Morgenstein #define MLX4_CMD_MAD_DEMUX_TRAP_REPRESS_ATTR_OFFSET 0x70 2245114840c3SJack Morgenstein 2246114840c3SJack Morgenstein u32 set_attr_mask, getresp_attr_mask; 2247114840c3SJack Morgenstein u32 trap_attr_mask, traprepress_attr_mask; 2248114840c3SJack Morgenstein 2249114840c3SJack Morgenstein MLX4_GET(set_attr_mask, mailbox->buf, 2250114840c3SJack Morgenstein MLX4_CMD_MAD_DEMUX_SET_ATTR_OFFSET); 2251114840c3SJack Morgenstein mlx4_dbg(dev, "SMP firewall set_attribute_mask = 0x%x\n", 2252114840c3SJack Morgenstein set_attr_mask); 2253114840c3SJack Morgenstein 2254114840c3SJack Morgenstein MLX4_GET(getresp_attr_mask, mailbox->buf, 2255114840c3SJack Morgenstein MLX4_CMD_MAD_DEMUX_GETRESP_ATTR_OFFSET); 2256114840c3SJack Morgenstein mlx4_dbg(dev, "SMP firewall getresp_attribute_mask = 0x%x\n", 2257114840c3SJack Morgenstein getresp_attr_mask); 2258114840c3SJack Morgenstein 2259114840c3SJack Morgenstein MLX4_GET(trap_attr_mask, mailbox->buf, 2260114840c3SJack Morgenstein MLX4_CMD_MAD_DEMUX_TRAP_ATTR_OFFSET); 2261114840c3SJack Morgenstein mlx4_dbg(dev, "SMP firewall trap_attribute_mask = 0x%x\n", 2262114840c3SJack Morgenstein trap_attr_mask); 2263114840c3SJack Morgenstein 2264114840c3SJack Morgenstein MLX4_GET(traprepress_attr_mask, mailbox->buf, 2265114840c3SJack Morgenstein MLX4_CMD_MAD_DEMUX_TRAP_REPRESS_ATTR_OFFSET); 2266114840c3SJack Morgenstein mlx4_dbg(dev, "SMP firewall traprepress_attribute_mask = 0x%x\n", 2267114840c3SJack Morgenstein traprepress_attr_mask); 2268114840c3SJack Morgenstein 2269114840c3SJack Morgenstein if (set_attr_mask && getresp_attr_mask && trap_attr_mask && 2270114840c3SJack Morgenstein traprepress_attr_mask) 2271114840c3SJack Morgenstein return 1; 2272114840c3SJack Morgenstein 2273114840c3SJack Morgenstein return 0; 2274114840c3SJack Morgenstein } 2275114840c3SJack Morgenstein 2276114840c3SJack Morgenstein int mlx4_config_mad_demux(struct mlx4_dev *dev) 2277114840c3SJack Morgenstein { 2278114840c3SJack Morgenstein struct mlx4_cmd_mailbox *mailbox; 2279114840c3SJack Morgenstein int secure_host_active; 2280114840c3SJack Morgenstein int err; 2281114840c3SJack Morgenstein 2282114840c3SJack Morgenstein /* Check if mad_demux is supported */ 2283114840c3SJack Morgenstein if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_MAD_DEMUX)) 2284114840c3SJack Morgenstein return 0; 2285114840c3SJack Morgenstein 2286114840c3SJack Morgenstein mailbox = mlx4_alloc_cmd_mailbox(dev); 2287114840c3SJack Morgenstein if (IS_ERR(mailbox)) { 2288114840c3SJack Morgenstein mlx4_warn(dev, "Failed to allocate mailbox for cmd MAD_DEMUX"); 2289114840c3SJack Morgenstein return -ENOMEM; 2290114840c3SJack Morgenstein } 2291114840c3SJack Morgenstein 2292114840c3SJack Morgenstein /* Query mad_demux to find out which MADs are handled by internal sma */ 2293114840c3SJack Morgenstein err = mlx4_cmd_box(dev, 0, mailbox->dma, 0x01 /* subn mgmt class */, 2294114840c3SJack Morgenstein MLX4_CMD_MAD_DEMUX_QUERY_RESTR, MLX4_CMD_MAD_DEMUX, 2295114840c3SJack Morgenstein MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 2296114840c3SJack Morgenstein if (err) { 2297114840c3SJack Morgenstein mlx4_warn(dev, "MLX4_CMD_MAD_DEMUX: query restrictions failed (%d)\n", 2298114840c3SJack Morgenstein err); 2299114840c3SJack Morgenstein goto out; 2300114840c3SJack Morgenstein } 2301114840c3SJack Morgenstein 2302114840c3SJack Morgenstein secure_host_active = mlx4_check_smp_firewall_active(dev, mailbox); 2303114840c3SJack Morgenstein 2304114840c3SJack Morgenstein /* Config mad_demux to handle all MADs returned by the query above */ 2305114840c3SJack Morgenstein err = mlx4_cmd(dev, mailbox->dma, 0x01 /* subn mgmt class */, 2306114840c3SJack Morgenstein MLX4_CMD_MAD_DEMUX_CONFIG, MLX4_CMD_MAD_DEMUX, 2307114840c3SJack Morgenstein MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 2308114840c3SJack Morgenstein if (err) { 2309114840c3SJack Morgenstein mlx4_warn(dev, "MLX4_CMD_MAD_DEMUX: configure failed (%d)\n", err); 2310114840c3SJack Morgenstein goto out; 2311114840c3SJack Morgenstein } 2312114840c3SJack Morgenstein 2313114840c3SJack Morgenstein if (secure_host_active) 2314114840c3SJack Morgenstein mlx4_warn(dev, "HCA operating in secure-host mode. SMP firewall activated.\n"); 2315114840c3SJack Morgenstein out: 2316114840c3SJack Morgenstein mlx4_free_cmd_mailbox(dev, mailbox); 2317114840c3SJack Morgenstein return err; 2318114840c3SJack Morgenstein } 2319adbc7ac5SSaeed Mahameed 2320adbc7ac5SSaeed Mahameed /* Access Reg commands */ 2321adbc7ac5SSaeed Mahameed enum mlx4_access_reg_masks { 2322adbc7ac5SSaeed Mahameed MLX4_ACCESS_REG_STATUS_MASK = 0x7f, 2323adbc7ac5SSaeed Mahameed MLX4_ACCESS_REG_METHOD_MASK = 0x7f, 2324adbc7ac5SSaeed Mahameed MLX4_ACCESS_REG_LEN_MASK = 0x7ff 2325adbc7ac5SSaeed Mahameed }; 2326adbc7ac5SSaeed Mahameed 2327adbc7ac5SSaeed Mahameed struct mlx4_access_reg { 2328adbc7ac5SSaeed Mahameed __be16 constant1; 2329adbc7ac5SSaeed Mahameed u8 status; 2330adbc7ac5SSaeed Mahameed u8 resrvd1; 2331adbc7ac5SSaeed Mahameed __be16 reg_id; 2332adbc7ac5SSaeed Mahameed u8 method; 2333adbc7ac5SSaeed Mahameed u8 constant2; 2334adbc7ac5SSaeed Mahameed __be32 resrvd2[2]; 2335adbc7ac5SSaeed Mahameed __be16 len_const; 2336adbc7ac5SSaeed Mahameed __be16 resrvd3; 2337adbc7ac5SSaeed Mahameed #define MLX4_ACCESS_REG_HEADER_SIZE (20) 2338adbc7ac5SSaeed Mahameed u8 reg_data[MLX4_MAILBOX_SIZE-MLX4_ACCESS_REG_HEADER_SIZE]; 2339adbc7ac5SSaeed Mahameed } __attribute__((__packed__)); 2340adbc7ac5SSaeed Mahameed 2341adbc7ac5SSaeed Mahameed /** 2342adbc7ac5SSaeed Mahameed * mlx4_ACCESS_REG - Generic access reg command. 2343adbc7ac5SSaeed Mahameed * @dev: mlx4_dev. 2344adbc7ac5SSaeed Mahameed * @reg_id: register ID to access. 2345adbc7ac5SSaeed Mahameed * @method: Access method Read/Write. 2346adbc7ac5SSaeed Mahameed * @reg_len: register length to Read/Write in bytes. 2347adbc7ac5SSaeed Mahameed * @reg_data: reg_data pointer to Read/Write From/To. 2348adbc7ac5SSaeed Mahameed * 2349adbc7ac5SSaeed Mahameed * Access ConnectX registers FW command. 2350adbc7ac5SSaeed Mahameed * Returns 0 on success and copies outbox mlx4_access_reg data 2351adbc7ac5SSaeed Mahameed * field into reg_data or a negative error code. 2352adbc7ac5SSaeed Mahameed */ 2353adbc7ac5SSaeed Mahameed static int mlx4_ACCESS_REG(struct mlx4_dev *dev, u16 reg_id, 2354adbc7ac5SSaeed Mahameed enum mlx4_access_reg_method method, 2355adbc7ac5SSaeed Mahameed u16 reg_len, void *reg_data) 2356adbc7ac5SSaeed Mahameed { 2357adbc7ac5SSaeed Mahameed struct mlx4_cmd_mailbox *inbox, *outbox; 2358adbc7ac5SSaeed Mahameed struct mlx4_access_reg *inbuf, *outbuf; 2359adbc7ac5SSaeed Mahameed int err; 2360adbc7ac5SSaeed Mahameed 2361adbc7ac5SSaeed Mahameed inbox = mlx4_alloc_cmd_mailbox(dev); 2362adbc7ac5SSaeed Mahameed if (IS_ERR(inbox)) 2363adbc7ac5SSaeed Mahameed return PTR_ERR(inbox); 2364adbc7ac5SSaeed Mahameed 2365adbc7ac5SSaeed Mahameed outbox = mlx4_alloc_cmd_mailbox(dev); 2366adbc7ac5SSaeed Mahameed if (IS_ERR(outbox)) { 2367adbc7ac5SSaeed Mahameed mlx4_free_cmd_mailbox(dev, inbox); 2368adbc7ac5SSaeed Mahameed return PTR_ERR(outbox); 2369adbc7ac5SSaeed Mahameed } 2370adbc7ac5SSaeed Mahameed 2371adbc7ac5SSaeed Mahameed inbuf = inbox->buf; 2372adbc7ac5SSaeed Mahameed outbuf = outbox->buf; 2373adbc7ac5SSaeed Mahameed 2374adbc7ac5SSaeed Mahameed inbuf->constant1 = cpu_to_be16(0x1<<11 | 0x4); 2375adbc7ac5SSaeed Mahameed inbuf->constant2 = 0x1; 2376adbc7ac5SSaeed Mahameed inbuf->reg_id = cpu_to_be16(reg_id); 2377adbc7ac5SSaeed Mahameed inbuf->method = method & MLX4_ACCESS_REG_METHOD_MASK; 2378adbc7ac5SSaeed Mahameed 2379adbc7ac5SSaeed Mahameed reg_len = min(reg_len, (u16)(sizeof(inbuf->reg_data))); 2380adbc7ac5SSaeed Mahameed inbuf->len_const = 2381adbc7ac5SSaeed Mahameed cpu_to_be16(((reg_len/4 + 1) & MLX4_ACCESS_REG_LEN_MASK) | 2382adbc7ac5SSaeed Mahameed ((0x3) << 12)); 2383adbc7ac5SSaeed Mahameed 2384adbc7ac5SSaeed Mahameed memcpy(inbuf->reg_data, reg_data, reg_len); 2385adbc7ac5SSaeed Mahameed err = mlx4_cmd_box(dev, inbox->dma, outbox->dma, 0, 0, 2386adbc7ac5SSaeed Mahameed MLX4_CMD_ACCESS_REG, MLX4_CMD_TIME_CLASS_C, 23876e806699SSaeed Mahameed MLX4_CMD_WRAPPED); 2388adbc7ac5SSaeed Mahameed if (err) 2389adbc7ac5SSaeed Mahameed goto out; 2390adbc7ac5SSaeed Mahameed 2391adbc7ac5SSaeed Mahameed if (outbuf->status & MLX4_ACCESS_REG_STATUS_MASK) { 2392adbc7ac5SSaeed Mahameed err = outbuf->status & MLX4_ACCESS_REG_STATUS_MASK; 2393adbc7ac5SSaeed Mahameed mlx4_err(dev, 2394adbc7ac5SSaeed Mahameed "MLX4_CMD_ACCESS_REG(%x) returned REG status (%x)\n", 2395adbc7ac5SSaeed Mahameed reg_id, err); 2396adbc7ac5SSaeed Mahameed goto out; 2397adbc7ac5SSaeed Mahameed } 2398adbc7ac5SSaeed Mahameed 2399adbc7ac5SSaeed Mahameed memcpy(reg_data, outbuf->reg_data, reg_len); 2400adbc7ac5SSaeed Mahameed out: 2401adbc7ac5SSaeed Mahameed mlx4_free_cmd_mailbox(dev, inbox); 2402adbc7ac5SSaeed Mahameed mlx4_free_cmd_mailbox(dev, outbox); 2403adbc7ac5SSaeed Mahameed return err; 2404adbc7ac5SSaeed Mahameed } 2405adbc7ac5SSaeed Mahameed 2406adbc7ac5SSaeed Mahameed /* ConnectX registers IDs */ 2407adbc7ac5SSaeed Mahameed enum mlx4_reg_id { 2408adbc7ac5SSaeed Mahameed MLX4_REG_ID_PTYS = 0x5004, 2409adbc7ac5SSaeed Mahameed }; 2410adbc7ac5SSaeed Mahameed 2411adbc7ac5SSaeed Mahameed /** 2412adbc7ac5SSaeed Mahameed * mlx4_ACCESS_PTYS_REG - Access PTYs (Port Type and Speed) 2413adbc7ac5SSaeed Mahameed * register 2414adbc7ac5SSaeed Mahameed * @dev: mlx4_dev. 2415adbc7ac5SSaeed Mahameed * @method: Access method Read/Write. 2416adbc7ac5SSaeed Mahameed * @ptys_reg: PTYS register data pointer. 2417adbc7ac5SSaeed Mahameed * 2418adbc7ac5SSaeed Mahameed * Access ConnectX PTYS register, to Read/Write Port Type/Speed 2419adbc7ac5SSaeed Mahameed * configuration 2420adbc7ac5SSaeed Mahameed * Returns 0 on success or a negative error code. 2421adbc7ac5SSaeed Mahameed */ 2422adbc7ac5SSaeed Mahameed int mlx4_ACCESS_PTYS_REG(struct mlx4_dev *dev, 2423adbc7ac5SSaeed Mahameed enum mlx4_access_reg_method method, 2424adbc7ac5SSaeed Mahameed struct mlx4_ptys_reg *ptys_reg) 2425adbc7ac5SSaeed Mahameed { 2426adbc7ac5SSaeed Mahameed return mlx4_ACCESS_REG(dev, MLX4_REG_ID_PTYS, 2427adbc7ac5SSaeed Mahameed method, sizeof(*ptys_reg), ptys_reg); 2428adbc7ac5SSaeed Mahameed } 2429adbc7ac5SSaeed Mahameed EXPORT_SYMBOL_GPL(mlx4_ACCESS_PTYS_REG); 24306e806699SSaeed Mahameed 24316e806699SSaeed Mahameed int mlx4_ACCESS_REG_wrapper(struct mlx4_dev *dev, int slave, 24326e806699SSaeed Mahameed struct mlx4_vhcr *vhcr, 24336e806699SSaeed Mahameed struct mlx4_cmd_mailbox *inbox, 24346e806699SSaeed Mahameed struct mlx4_cmd_mailbox *outbox, 24356e806699SSaeed Mahameed struct mlx4_cmd_info *cmd) 24366e806699SSaeed Mahameed { 24376e806699SSaeed Mahameed struct mlx4_access_reg *inbuf = inbox->buf; 24386e806699SSaeed Mahameed u8 method = inbuf->method & MLX4_ACCESS_REG_METHOD_MASK; 24396e806699SSaeed Mahameed u16 reg_id = be16_to_cpu(inbuf->reg_id); 24406e806699SSaeed Mahameed 24416e806699SSaeed Mahameed if (slave != mlx4_master_func_num(dev) && 24426e806699SSaeed Mahameed method == MLX4_ACCESS_REG_WRITE) 24436e806699SSaeed Mahameed return -EPERM; 24446e806699SSaeed Mahameed 24456e806699SSaeed Mahameed if (reg_id == MLX4_REG_ID_PTYS) { 24466e806699SSaeed Mahameed struct mlx4_ptys_reg *ptys_reg = 24476e806699SSaeed Mahameed (struct mlx4_ptys_reg *)inbuf->reg_data; 24486e806699SSaeed Mahameed 24496e806699SSaeed Mahameed ptys_reg->local_port = 24506e806699SSaeed Mahameed mlx4_slave_convert_port(dev, slave, 24516e806699SSaeed Mahameed ptys_reg->local_port); 24526e806699SSaeed Mahameed } 24536e806699SSaeed Mahameed 24546e806699SSaeed Mahameed return mlx4_cmd_box(dev, inbox->dma, outbox->dma, vhcr->in_modifier, 24556e806699SSaeed Mahameed 0, MLX4_CMD_ACCESS_REG, MLX4_CMD_TIME_CLASS_C, 24566e806699SSaeed Mahameed MLX4_CMD_NATIVE); 24576e806699SSaeed Mahameed } 2458