port.c revision 322165
1/* 2 * Copyright (c) 2007, 2014 Mellanox Technologies. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 */ 32 33#include <linux/errno.h> 34#include <linux/if_ether.h> 35#include <linux/module.h> 36#include <linux/err.h> 37 38#include <linux/mlx4/cmd.h> 39#include <linux/moduleparam.h> 40#include "mlx4.h" 41#include "mlx4_stats.h" 42 43 44int mlx4_set_4k_mtu = -1; 45module_param_named(set_4k_mtu, mlx4_set_4k_mtu, int, 0444); 46MODULE_PARM_DESC(set_4k_mtu, 47 "(Obsolete) attempt to set 4K MTU to all ConnectX ports"); 48 49 50#define MLX4_MAC_VALID (1ull << 63) 51 52#define MLX4_VLAN_VALID (1u << 31) 53#define MLX4_VLAN_MASK 0xfff 54 55void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table) 56{ 57 int i; 58 59 mutex_init(&table->mutex); 60 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) { 61 table->entries[i] = 0; 62 table->refs[i] = 0; 63 } 64 table->max = 1 << dev->caps.log_num_macs; 65 table->total = 0; 66} 67 68void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table) 69{ 70 int i; 71 72 mutex_init(&table->mutex); 73 for (i = 0; i < MLX4_MAX_VLAN_NUM; i++) { 74 table->entries[i] = 0; 75 table->refs[i] = 0; 76 } 77 table->max = (1 << dev->caps.log_num_vlans) - MLX4_VLAN_REGULAR; 78 table->total = 0; 79} 80 81static int validate_index(struct mlx4_dev *dev, 82 struct mlx4_mac_table *table, int index) 83{ 84 int err = 0; 85 86 if (index < 0 || index >= table->max || !table->refs[index]) { 87 mlx4_warn(dev, "No valid Mac entry for the given index\n"); 88 err = -EINVAL; 89 } 90 return err; 91} 92 93static int find_index(struct mlx4_dev *dev, 94 struct mlx4_mac_table *table, u64 mac) 95{ 96 int i; 97 98 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) { 99 if ((mac & MLX4_MAC_MASK) == 100 (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) 101 return i; 102 } 103 /* Mac not found */ 104 return -EINVAL; 105} 106 107static int mlx4_set_port_mac_table(struct mlx4_dev *dev, u8 port, 108 __be64 *entries) 109{ 110 struct mlx4_cmd_mailbox *mailbox; 111 u32 in_mod; 112 int err; 113 114 mailbox = mlx4_alloc_cmd_mailbox(dev); 115 if (IS_ERR(mailbox)) 116 return PTR_ERR(mailbox); 117 118 memcpy(mailbox->buf, entries, MLX4_MAC_TABLE_SIZE); 119 120 in_mod = MLX4_SET_PORT_MAC_TABLE << 8 | port; 121 122 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, 123 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 124 125 mlx4_free_cmd_mailbox(dev, mailbox); 126 return err; 127} 128 129int __mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac) 130{ 131 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port]; 132 struct mlx4_mac_table *table = &info->mac_table; 133 int i, err = 0; 134 int free = -1; 135 136 mlx4_dbg(dev, "Registering MAC: 0x%llx for port %d\n", 137 (unsigned long long) mac, port); 138 139 mutex_lock(&table->mutex); 140 for (i = 0; i < MLX4_MAX_MAC_NUM; i++) { 141 if (free < 0 && !table->refs[i]) { 142 free = i; 143 continue; 144 } 145 146 if ((mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) && 147 table->refs[i]) { 148 /* MAC already registered, Must not have duplicates */ 149 err = i; 150 ++table->refs[i]; 151 goto out; 152 } 153 } 154 155 mlx4_dbg(dev, "Free MAC index is %d\n", free); 156 157 if (table->total == table->max) { 158 /* No free mac entries */ 159 err = -ENOSPC; 160 goto out; 161 } 162 163 /* Register new MAC */ 164 table->entries[free] = cpu_to_be64(mac | MLX4_MAC_VALID); 165 166 err = mlx4_set_port_mac_table(dev, port, table->entries); 167 if (unlikely(err)) { 168 mlx4_err(dev, "Failed adding MAC: 0x%llx\n", 169 (unsigned long long) mac); 170 table->entries[free] = 0; 171 goto out; 172 } 173 table->refs[free] = 1; 174 175 err = free; 176 ++table->total; 177out: 178 mutex_unlock(&table->mutex); 179 return err; 180} 181EXPORT_SYMBOL_GPL(__mlx4_register_mac); 182 183int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac) 184{ 185 u64 out_param = 0; 186 int err = -EINVAL; 187 188 if (mlx4_is_mfunc(dev)) { 189 if (!(dev->flags & MLX4_FLAG_OLD_REG_MAC)) { 190 err = mlx4_cmd_imm(dev, mac, &out_param, 191 ((u32) port) << 8 | (u32) RES_MAC, 192 RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES, 193 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); 194 } 195 if (err && err == -EINVAL && mlx4_is_slave(dev)) { 196 /* retry using old REG_MAC format */ 197 set_param_l(&out_param, port); 198 err = mlx4_cmd_imm(dev, mac, &out_param, RES_MAC, 199 RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES, 200 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); 201 if (!err) 202 dev->flags |= MLX4_FLAG_OLD_REG_MAC; 203 } 204 if (err) 205 return err; 206 207 return get_param_l(&out_param); 208 } 209 return __mlx4_register_mac(dev, port, mac); 210} 211EXPORT_SYMBOL_GPL(mlx4_register_mac); 212 213int mlx4_get_base_qpn(struct mlx4_dev *dev, u8 port) 214{ 215 return dev->caps.reserved_qps_base[MLX4_QP_REGION_ETH_ADDR] + 216 (port - 1) * (1 << dev->caps.log_num_macs); 217} 218EXPORT_SYMBOL_GPL(mlx4_get_base_qpn); 219 220void __mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac) 221{ 222 struct mlx4_port_info *info; 223 struct mlx4_mac_table *table; 224 int index; 225 226 if (port < 1 || port > dev->caps.num_ports) { 227 mlx4_warn(dev, "invalid port number (%d), aborting...\n", port); 228 return; 229 } 230 info = &mlx4_priv(dev)->port[port]; 231 table = &info->mac_table; 232 mutex_lock(&table->mutex); 233 234 index = find_index(dev, table, mac); 235 236 if (validate_index(dev, table, index)) 237 goto out; 238 239 if (--table->refs[index]) { 240 mlx4_dbg(dev, "Have more references for index %d," 241 "no need to modify mac table\n", index); 242 goto out; 243 } 244 245 table->entries[index] = 0; 246 mlx4_set_port_mac_table(dev, port, table->entries); 247 --table->total; 248out: 249 mutex_unlock(&table->mutex); 250} 251EXPORT_SYMBOL_GPL(__mlx4_unregister_mac); 252 253void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac) 254{ 255 u64 out_param = 0; 256 257 if (mlx4_is_mfunc(dev)) { 258 if (!(dev->flags & MLX4_FLAG_OLD_REG_MAC)) { 259 (void) mlx4_cmd_imm(dev, mac, &out_param, 260 ((u32) port) << 8 | (u32) RES_MAC, 261 RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES, 262 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); 263 } else { 264 /* use old unregister mac format */ 265 set_param_l(&out_param, port); 266 (void) mlx4_cmd_imm(dev, mac, &out_param, RES_MAC, 267 RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES, 268 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); 269 } 270 return; 271 } 272 __mlx4_unregister_mac(dev, port, mac); 273 return; 274} 275EXPORT_SYMBOL_GPL(mlx4_unregister_mac); 276 277int __mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac) 278{ 279 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port]; 280 struct mlx4_mac_table *table = &info->mac_table; 281 int index = qpn - info->base_qpn; 282 int err = 0; 283 284 /* CX1 doesn't support multi-functions */ 285 mutex_lock(&table->mutex); 286 287 err = validate_index(dev, table, index); 288 if (err) 289 goto out; 290 291 table->entries[index] = cpu_to_be64(new_mac | MLX4_MAC_VALID); 292 293 err = mlx4_set_port_mac_table(dev, port, table->entries); 294 if (unlikely(err)) { 295 mlx4_err(dev, "Failed adding MAC: 0x%llx\n", 296 (unsigned long long) new_mac); 297 table->entries[index] = 0; 298 } 299out: 300 mutex_unlock(&table->mutex); 301 return err; 302} 303EXPORT_SYMBOL_GPL(__mlx4_replace_mac); 304 305static int mlx4_set_port_vlan_table(struct mlx4_dev *dev, u8 port, 306 __be32 *entries) 307{ 308 struct mlx4_cmd_mailbox *mailbox; 309 u32 in_mod; 310 int err; 311 312 mailbox = mlx4_alloc_cmd_mailbox(dev); 313 if (IS_ERR(mailbox)) 314 return PTR_ERR(mailbox); 315 316 memcpy(mailbox->buf, entries, MLX4_VLAN_TABLE_SIZE); 317 in_mod = MLX4_SET_PORT_VLAN_TABLE << 8 | port; 318 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, 319 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 320 321 mlx4_free_cmd_mailbox(dev, mailbox); 322 323 return err; 324} 325 326int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx) 327{ 328 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table; 329 int i; 330 331 for (i = 0; i < MLX4_MAX_VLAN_NUM; ++i) { 332 if (table->refs[i] && 333 (vid == (MLX4_VLAN_MASK & 334 be32_to_cpu(table->entries[i])))) { 335 /* VLAN already registered, increase reference count */ 336 *idx = i; 337 return 0; 338 } 339 } 340 341 return -ENOENT; 342} 343EXPORT_SYMBOL_GPL(mlx4_find_cached_vlan); 344 345int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, 346 int *index) 347{ 348 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table; 349 int i, err = 0; 350 int free = -1; 351 352 mutex_lock(&table->mutex); 353 354 if (table->total == table->max) { 355 /* No free vlan entries */ 356 err = -ENOSPC; 357 goto out; 358 } 359 360 for (i = MLX4_VLAN_REGULAR; i < MLX4_MAX_VLAN_NUM; i++) { 361 if (free < 0 && (table->refs[i] == 0)) { 362 free = i; 363 continue; 364 } 365 366 if (table->refs[i] && 367 (vlan == (MLX4_VLAN_MASK & 368 be32_to_cpu(table->entries[i])))) { 369 /* Vlan already registered, increase references count */ 370 *index = i; 371 ++table->refs[i]; 372 goto out; 373 } 374 } 375 376 if (free < 0) { 377 err = -ENOMEM; 378 goto out; 379 } 380 381 /* Register new VLAN */ 382 table->refs[free] = 1; 383 table->entries[free] = cpu_to_be32(vlan | MLX4_VLAN_VALID); 384 385 err = mlx4_set_port_vlan_table(dev, port, table->entries); 386 if (unlikely(err)) { 387 mlx4_warn(dev, "Failed adding vlan: %u\n", vlan); 388 table->refs[free] = 0; 389 table->entries[free] = 0; 390 goto out; 391 } 392 393 *index = free; 394 ++table->total; 395out: 396 mutex_unlock(&table->mutex); 397 return err; 398} 399 400int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index) 401{ 402 u64 out_param = 0; 403 int err; 404 405 if (vlan > 4095) 406 return -EINVAL; 407 408 if (mlx4_is_mfunc(dev)) { 409 err = mlx4_cmd_imm(dev, vlan, &out_param, 410 ((u32) port) << 8 | (u32) RES_VLAN, 411 RES_OP_RESERVE_AND_MAP, MLX4_CMD_ALLOC_RES, 412 MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); 413 if (!err) 414 *index = get_param_l(&out_param); 415 416 return err; 417 } 418 return __mlx4_register_vlan(dev, port, vlan, index); 419} 420EXPORT_SYMBOL_GPL(mlx4_register_vlan); 421 422void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan) 423{ 424 struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table; 425 int index; 426 427 mutex_lock(&table->mutex); 428 if (mlx4_find_cached_vlan(dev, port, vlan, &index)) { 429 mlx4_warn(dev, "vlan 0x%x is not in the vlan table\n", vlan); 430 goto out; 431 } 432 433 if (index < MLX4_VLAN_REGULAR) { 434 mlx4_warn(dev, "Trying to free special vlan index %d\n", index); 435 goto out; 436 } 437 438 if (--table->refs[index]) { 439 mlx4_dbg(dev, "Have %d more references for index %d, " 440 "no need to modify vlan table\n", table->refs[index], 441 index); 442 goto out; 443 } 444 table->entries[index] = 0; 445 mlx4_set_port_vlan_table(dev, port, table->entries); 446 --table->total; 447out: 448 mutex_unlock(&table->mutex); 449} 450 451void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan) 452{ 453 u64 out_param = 0; 454 455 if (mlx4_is_mfunc(dev)) { 456 (void) mlx4_cmd_imm(dev, vlan, &out_param, 457 ((u32) port) << 8 | (u32) RES_VLAN, 458 RES_OP_RESERVE_AND_MAP, 459 MLX4_CMD_FREE_RES, MLX4_CMD_TIME_CLASS_A, 460 MLX4_CMD_WRAPPED); 461 return; 462 } 463 __mlx4_unregister_vlan(dev, port, vlan); 464} 465EXPORT_SYMBOL_GPL(mlx4_unregister_vlan); 466 467int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps) 468{ 469 struct mlx4_cmd_mailbox *inmailbox, *outmailbox; 470 u8 *inbuf, *outbuf; 471 int err; 472 473 inmailbox = mlx4_alloc_cmd_mailbox(dev); 474 if (IS_ERR(inmailbox)) 475 return PTR_ERR(inmailbox); 476 477 outmailbox = mlx4_alloc_cmd_mailbox(dev); 478 if (IS_ERR(outmailbox)) { 479 mlx4_free_cmd_mailbox(dev, inmailbox); 480 return PTR_ERR(outmailbox); 481 } 482 483 inbuf = inmailbox->buf; 484 outbuf = outmailbox->buf; 485 memset(inbuf, 0, 256); 486 memset(outbuf, 0, 256); 487 inbuf[0] = 1; 488 inbuf[1] = 1; 489 inbuf[2] = 1; 490 inbuf[3] = 1; 491 *(__be16 *) (&inbuf[16]) = cpu_to_be16(0x0015); 492 *(__be32 *) (&inbuf[20]) = cpu_to_be32(port); 493 494 err = mlx4_cmd_box(dev, inmailbox->dma, outmailbox->dma, port, 3, 495 MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C, 496 MLX4_CMD_NATIVE); 497 if (!err) 498 *caps = *(__be32 *) (outbuf + 84); 499 mlx4_free_cmd_mailbox(dev, inmailbox); 500 mlx4_free_cmd_mailbox(dev, outmailbox); 501 return err; 502} 503static struct mlx4_roce_gid_entry zgid_entry; 504 505int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave) 506{ 507 if (slave == 0) 508 return MLX4_ROCE_PF_GIDS; 509 if (slave <= ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) % dev->num_vfs)) 510 return ((MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / dev->num_vfs) + 1; 511 return (MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS) / dev->num_vfs; 512} 513 514int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave) 515{ 516 int gids; 517 int vfs; 518 519 gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS; 520 vfs = dev->num_vfs; 521 522 if (slave == 0) 523 return 0; 524 if (slave <= gids % vfs) 525 return MLX4_ROCE_PF_GIDS + ((gids / vfs) + 1) * (slave - 1); 526 527 return MLX4_ROCE_PF_GIDS + (gids % vfs) + ((gids / vfs) * (slave - 1)); 528} 529 530static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, 531 u8 op_mod, struct mlx4_cmd_mailbox *inbox) 532{ 533 struct mlx4_priv *priv = mlx4_priv(dev); 534 struct mlx4_port_info *port_info; 535 struct mlx4_mfunc_master_ctx *master = &priv->mfunc.master; 536 struct mlx4_slave_state *slave_st = &master->slave_state[slave]; 537 struct mlx4_set_port_rqp_calc_context *qpn_context; 538 struct mlx4_set_port_general_context *gen_context; 539 struct mlx4_roce_gid_entry *gid_entry_tbl, *gid_entry_mbox, *gid_entry_mb1; 540 int reset_qkey_viols; 541 int port; 542 int is_eth; 543 int num_gids; 544 int base; 545 u32 in_modifier; 546 u32 promisc; 547 u16 mtu, prev_mtu; 548 int err; 549 int i, j; 550 int offset; 551 __be32 agg_cap_mask; 552 __be32 slave_cap_mask; 553 __be32 new_cap_mask; 554 555 port = in_mod & 0xff; 556 in_modifier = (in_mod >> 8) & 0xff; 557 is_eth = op_mod; 558 port_info = &priv->port[port]; 559 560 if (op_mod > 1) 561 return -EINVAL; 562 563 /* Slaves cannot perform SET_PORT operations except changing MTU */ 564 if (is_eth) { 565 if (slave != dev->caps.function && 566 in_modifier != MLX4_SET_PORT_GENERAL && 567 in_modifier != MLX4_SET_PORT_GID_TABLE) { 568 mlx4_warn(dev, "denying SET_PORT for slave:%d," 569 "port %d, config_select 0x%x\n", 570 slave, port, in_modifier); 571 return -EINVAL; 572 } 573 switch (in_modifier) { 574 case MLX4_SET_PORT_RQP_CALC: 575 qpn_context = inbox->buf; 576 qpn_context->base_qpn = 577 cpu_to_be32(port_info->base_qpn); 578 qpn_context->n_mac = 0x7; 579 promisc = be32_to_cpu(qpn_context->promisc) >> 580 SET_PORT_PROMISC_SHIFT; 581 qpn_context->promisc = cpu_to_be32( 582 promisc << SET_PORT_PROMISC_SHIFT | 583 port_info->base_qpn); 584 promisc = be32_to_cpu(qpn_context->mcast) >> 585 SET_PORT_MC_PROMISC_SHIFT; 586 qpn_context->mcast = cpu_to_be32( 587 promisc << SET_PORT_MC_PROMISC_SHIFT | 588 port_info->base_qpn); 589 break; 590 case MLX4_SET_PORT_GENERAL: 591 gen_context = inbox->buf; 592 /* Mtu is configured as the max MTU among all the 593 * the functions on the port. */ 594 mtu = be16_to_cpu(gen_context->mtu); 595 mtu = min_t(int, mtu, dev->caps.eth_mtu_cap[port] + 596 ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN); 597 prev_mtu = slave_st->mtu[port]; 598 slave_st->mtu[port] = mtu; 599 if (mtu > master->max_mtu[port]) 600 master->max_mtu[port] = mtu; 601 if (mtu < prev_mtu && prev_mtu == 602 master->max_mtu[port]) { 603 slave_st->mtu[port] = mtu; 604 master->max_mtu[port] = mtu; 605 for (i = 0; i < dev->num_slaves; i++) { 606 master->max_mtu[port] = 607 max(master->max_mtu[port], 608 master->slave_state[i].mtu[port]); 609 } 610 } 611 612 gen_context->mtu = cpu_to_be16(master->max_mtu[port]); 613 break; 614 case MLX4_SET_PORT_GID_TABLE: 615 /* change to MULTIPLE entries: number of guest's gids 616 * need a FOR-loop here over number of gids the guest has. 617 * 1. Check no duplicates in gids passed by slave 618 */ 619 num_gids = mlx4_get_slave_num_gids(dev, slave); 620 base = mlx4_get_base_gid_ix(dev, slave); 621 gid_entry_mbox = (struct mlx4_roce_gid_entry *) (inbox->buf); 622 for (i = 0; i < num_gids; gid_entry_mbox++, i++) { 623 if (!memcmp(gid_entry_mbox->raw, zgid_entry.raw, 624 sizeof(zgid_entry))) 625 continue; 626 gid_entry_mb1 = gid_entry_mbox + 1; 627 for (j = i + 1; j < num_gids; gid_entry_mb1++, j++) { 628 if (!memcmp(gid_entry_mb1->raw, 629 zgid_entry.raw, sizeof(zgid_entry))) 630 continue; 631 if (!memcmp(gid_entry_mb1->raw, gid_entry_mbox->raw, 632 sizeof(gid_entry_mbox->raw))) { 633 /* found duplicate */ 634 return -EINVAL; 635 } 636 } 637 } 638 639 /* 2. Check that do not have duplicates in OTHER 640 * entries in the port GID table 641 */ 642 for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) { 643 if (i >= base && i < base + num_gids) 644 continue; /* don't compare to slave's current gids */ 645 gid_entry_tbl = &priv->roce_gids[port - 1][i]; 646 if (!memcmp(gid_entry_tbl->raw, zgid_entry.raw, sizeof(zgid_entry))) 647 continue; 648 gid_entry_mbox = (struct mlx4_roce_gid_entry *) (inbox->buf); 649 for (j = 0; j < num_gids; gid_entry_mbox++, j++) { 650 if (!memcmp(gid_entry_mbox->raw, zgid_entry.raw, 651 sizeof(zgid_entry))) 652 continue; 653 if (!memcmp(gid_entry_mbox->raw, gid_entry_tbl->raw, 654 sizeof(gid_entry_tbl->raw))) { 655 /* found duplicate */ 656 mlx4_warn(dev, "requested gid entry for slave:%d " 657 "is a duplicate of gid at index %d\n", 658 slave, i); 659 return -EINVAL; 660 } 661 } 662 } 663 664 /* insert slave GIDs with memcpy, starting at slave's base index */ 665 gid_entry_mbox = (struct mlx4_roce_gid_entry *) (inbox->buf); 666 for (i = 0, offset = base; i < num_gids; gid_entry_mbox++, offset++, i++) 667 memcpy(priv->roce_gids[port - 1][offset].raw, gid_entry_mbox->raw, 16); 668 669 /* Now, copy roce port gids table to current mailbox for passing to FW */ 670 gid_entry_mbox = (struct mlx4_roce_gid_entry *) (inbox->buf); 671 for (i = 0; i < MLX4_ROCE_MAX_GIDS; gid_entry_mbox++, i++) 672 memcpy(gid_entry_mbox->raw, priv->roce_gids[port - 1][i].raw, 16); 673 674 break; 675 } 676 return mlx4_cmd(dev, inbox->dma, in_mod & 0xffff, op_mod, 677 MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B, 678 MLX4_CMD_NATIVE); 679 } 680 681 /* For IB, we only consider: 682 * - The capability mask, which is set to the aggregate of all 683 * slave function capabilities 684 * - The QKey violatin counter - reset according to each request. 685 */ 686 687 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { 688 reset_qkey_viols = (*(u8 *) inbox->buf) & 0x40; 689 new_cap_mask = ((__be32 *) inbox->buf)[2]; 690 } else { 691 reset_qkey_viols = ((u8 *) inbox->buf)[3] & 0x1; 692 new_cap_mask = ((__be32 *) inbox->buf)[1]; 693 } 694 695 /* slave may not set the IS_SM capability for the port */ 696 if (slave != mlx4_master_func_num(dev) && 697 (be32_to_cpu(new_cap_mask) & MLX4_PORT_CAP_IS_SM)) 698 return -EINVAL; 699 700 /* No DEV_MGMT in multifunc mode */ 701 if (mlx4_is_mfunc(dev) && 702 (be32_to_cpu(new_cap_mask) & MLX4_PORT_CAP_DEV_MGMT_SUP)) 703 return -EINVAL; 704 705 agg_cap_mask = 0; 706 slave_cap_mask = 707 priv->mfunc.master.slave_state[slave].ib_cap_mask[port]; 708 priv->mfunc.master.slave_state[slave].ib_cap_mask[port] = new_cap_mask; 709 for (i = 0; i < dev->num_slaves; i++) 710 agg_cap_mask |= 711 priv->mfunc.master.slave_state[i].ib_cap_mask[port]; 712 713 /* only clear mailbox for guests. Master may be setting 714 * MTU or PKEY table size 715 */ 716 if (slave != dev->caps.function) 717 memset(inbox->buf, 0, 256); 718 if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) { 719 *(u8 *) inbox->buf |= !!reset_qkey_viols << 6; 720 ((__be32 *) inbox->buf)[2] = agg_cap_mask; 721 } else { 722 ((u8 *) inbox->buf)[3] |= !!reset_qkey_viols; 723 ((__be32 *) inbox->buf)[1] = agg_cap_mask; 724 } 725 726 err = mlx4_cmd(dev, inbox->dma, port, is_eth, MLX4_CMD_SET_PORT, 727 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 728 if (err) 729 priv->mfunc.master.slave_state[slave].ib_cap_mask[port] = 730 slave_cap_mask; 731 return err; 732} 733 734int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave, 735 struct mlx4_vhcr *vhcr, 736 struct mlx4_cmd_mailbox *inbox, 737 struct mlx4_cmd_mailbox *outbox, 738 struct mlx4_cmd_info *cmd) 739{ 740 return mlx4_common_set_port(dev, slave, vhcr->in_modifier, 741 vhcr->op_modifier, inbox); 742} 743 744/* bit locations for set port command with zero op modifier */ 745enum { 746 MLX4_SET_PORT_VL_CAP = 4, /* bits 7:4 */ 747 MLX4_SET_PORT_MTU_CAP = 12, /* bits 15:12 */ 748 MLX4_CHANGE_PORT_PKEY_TBL_SZ = 20, 749 MLX4_CHANGE_PORT_VL_CAP = 21, 750 MLX4_CHANGE_PORT_MTU_CAP = 22, 751}; 752 753int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, int pkey_tbl_sz) 754{ 755 struct mlx4_cmd_mailbox *mailbox; 756 int err = -EINVAL, vl_cap, pkey_tbl_flag = 0; 757 u32 in_mod; 758 759 if (dev->caps.port_type[port] == MLX4_PORT_TYPE_NONE) 760 return 0; 761 762 mailbox = mlx4_alloc_cmd_mailbox(dev); 763 if (IS_ERR(mailbox)) 764 return PTR_ERR(mailbox); 765 766 memset(mailbox->buf, 0, 256); 767 768 if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) { 769 in_mod = MLX4_SET_PORT_GENERAL << 8 | port; 770 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, 771 MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B, 772 MLX4_CMD_WRAPPED); 773 } else { 774 ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port]; 775 776 if (pkey_tbl_sz >= 0 && mlx4_is_master(dev)) { 777 pkey_tbl_flag = 1; 778 ((__be16 *) mailbox->buf)[20] = cpu_to_be16(pkey_tbl_sz); 779 } 780 781 /* IB VL CAP enum isn't used by the firmware, just numerical values */ 782 for (vl_cap = dev->caps.vl_cap[port]; 783 vl_cap >= 1; vl_cap >>= 1) { 784 ((__be32 *) mailbox->buf)[0] = cpu_to_be32( 785 (1 << MLX4_CHANGE_PORT_MTU_CAP) | 786 (1 << MLX4_CHANGE_PORT_VL_CAP) | 787 (pkey_tbl_flag << MLX4_CHANGE_PORT_PKEY_TBL_SZ) | 788 (dev->caps.port_ib_mtu[port] << MLX4_SET_PORT_MTU_CAP) | 789 (vl_cap << MLX4_SET_PORT_VL_CAP)); 790 err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT, 791 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); 792 if (err != -ENOMEM) 793 break; 794 } 795 } 796 797 mlx4_free_cmd_mailbox(dev, mailbox); 798 return err; 799} 800 801int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu, 802 u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx) 803{ 804 struct mlx4_cmd_mailbox *mailbox; 805 struct mlx4_set_port_general_context *context; 806 int err; 807 u32 in_mod; 808 809 mailbox = mlx4_alloc_cmd_mailbox(dev); 810 if (IS_ERR(mailbox)) 811 return PTR_ERR(mailbox); 812 context = mailbox->buf; 813 memset(context, 0, sizeof *context); 814 815 context->flags = SET_PORT_GEN_ALL_VALID; 816 context->mtu = cpu_to_be16(mtu); 817 context->pptx = (pptx * (!pfctx)) << 7; 818 context->pfctx = pfctx; 819 context->pprx = (pprx * (!pfcrx)) << 7; 820 context->pfcrx = pfcrx; 821 822 in_mod = MLX4_SET_PORT_GENERAL << 8 | port; 823 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, 824 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); 825 826 mlx4_free_cmd_mailbox(dev, mailbox); 827 return err; 828} 829EXPORT_SYMBOL(mlx4_SET_PORT_general); 830 831int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, 832 u8 promisc) 833{ 834 struct mlx4_cmd_mailbox *mailbox; 835 struct mlx4_set_port_rqp_calc_context *context; 836 int err; 837 u32 in_mod; 838 u32 m_promisc = (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) ? 839 MCAST_DIRECT : MCAST_DEFAULT; 840 841 if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0) 842 return 0; 843 844 mailbox = mlx4_alloc_cmd_mailbox(dev); 845 if (IS_ERR(mailbox)) 846 return PTR_ERR(mailbox); 847 context = mailbox->buf; 848 memset(context, 0, sizeof *context); 849 850 context->base_qpn = cpu_to_be32(base_qpn); 851 context->n_mac = dev->caps.log_num_macs; 852 context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT | 853 base_qpn); 854 context->mcast = cpu_to_be32(m_promisc << SET_PORT_MC_PROMISC_SHIFT | 855 base_qpn); 856 context->intra_no_vlan = 0; 857 context->no_vlan = MLX4_NO_VLAN_IDX; 858 context->intra_vlan_miss = 0; 859 context->vlan_miss = MLX4_VLAN_MISS_IDX; 860 861 in_mod = MLX4_SET_PORT_RQP_CALC << 8 | port; 862 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, 863 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); 864 865 mlx4_free_cmd_mailbox(dev, mailbox); 866 return err; 867} 868EXPORT_SYMBOL(mlx4_SET_PORT_qpn_calc); 869 870int mlx4_SET_PORT_PRIO2TC(struct mlx4_dev *dev, u8 port, u8 *prio2tc) 871{ 872 struct mlx4_cmd_mailbox *mailbox; 873 struct mlx4_set_port_prio2tc_context *context; 874 int err; 875 u32 in_mod; 876 int i; 877 878 mailbox = mlx4_alloc_cmd_mailbox(dev); 879 if (IS_ERR(mailbox)) 880 return PTR_ERR(mailbox); 881 context = mailbox->buf; 882 memset(context, 0, sizeof *context); 883 884 for (i = 0; i < MLX4_NUM_UP; i += 2) 885 context->prio2tc[i >> 1] = prio2tc[i] << 4 | prio2tc[i + 1]; 886 887 in_mod = MLX4_SET_PORT_PRIO2TC << 8 | port; 888 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, 889 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 890 891 mlx4_free_cmd_mailbox(dev, mailbox); 892 return err; 893} 894EXPORT_SYMBOL(mlx4_SET_PORT_PRIO2TC); 895 896int mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw, 897 u8 *pg, u16 *ratelimit) 898{ 899 struct mlx4_cmd_mailbox *mailbox; 900 struct mlx4_set_port_scheduler_context *context; 901 int err; 902 u32 in_mod; 903 int i; 904 905 mailbox = mlx4_alloc_cmd_mailbox(dev); 906 if (IS_ERR(mailbox)) 907 return PTR_ERR(mailbox); 908 context = mailbox->buf; 909 memset(context, 0, sizeof *context); 910 911 for (i = 0; i < MLX4_NUM_TC; i++) { 912 struct mlx4_port_scheduler_tc_cfg_be *tc = &context->tc[i]; 913 u16 r; 914 if (ratelimit && ratelimit[i]) { 915 if (ratelimit[i] <= MLX4_MAX_100M_UNITS_VAL) { 916 r = ratelimit[i]; 917 tc->max_bw_units = 918 htons(MLX4_RATELIMIT_100M_UNITS); 919 } else { 920 r = ratelimit[i]/10; 921 tc->max_bw_units = 922 htons(MLX4_RATELIMIT_1G_UNITS); 923 } 924 tc->max_bw_value = htons(r); 925 } else { 926 tc->max_bw_value = htons(MLX4_RATELIMIT_DEFAULT); 927 tc->max_bw_units = htons(MLX4_RATELIMIT_1G_UNITS); 928 } 929 930 tc->pg = htons(pg[i]); 931 tc->bw_precentage = htons(tc_tx_bw[i]); 932 } 933 934 in_mod = MLX4_SET_PORT_SCHEDULER << 8 | port; 935 err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, 936 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 937 938 mlx4_free_cmd_mailbox(dev, mailbox); 939 return err; 940} 941EXPORT_SYMBOL(mlx4_SET_PORT_SCHEDULER); 942 943int mlx4_SET_MCAST_FLTR_wrapper(struct mlx4_dev *dev, int slave, 944 struct mlx4_vhcr *vhcr, 945 struct mlx4_cmd_mailbox *inbox, 946 struct mlx4_cmd_mailbox *outbox, 947 struct mlx4_cmd_info *cmd) 948{ 949 int err = 0; 950 951 return err; 952} 953 954int mlx4_SET_MCAST_FLTR(struct mlx4_dev *dev, u8 port, 955 u64 mac, u64 clear, u8 mode) 956{ 957 return mlx4_cmd(dev, (mac | (clear << 63)), port, mode, 958 MLX4_CMD_SET_MCAST_FLTR, MLX4_CMD_TIME_CLASS_B, 959 MLX4_CMD_WRAPPED); 960} 961EXPORT_SYMBOL(mlx4_SET_MCAST_FLTR); 962 963int mlx4_SET_VLAN_FLTR_wrapper(struct mlx4_dev *dev, int slave, 964 struct mlx4_vhcr *vhcr, 965 struct mlx4_cmd_mailbox *inbox, 966 struct mlx4_cmd_mailbox *outbox, 967 struct mlx4_cmd_info *cmd) 968{ 969 int err = 0; 970 971 return err; 972} 973 974int mlx4_DUMP_ETH_STATS_wrapper(struct mlx4_dev *dev, int slave, 975 struct mlx4_vhcr *vhcr, 976 struct mlx4_cmd_mailbox *inbox, 977 struct mlx4_cmd_mailbox *outbox, 978 struct mlx4_cmd_info *cmd) 979{ 980 return 0; 981} 982 983int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid, int *slave_id) 984{ 985 struct mlx4_priv *priv = mlx4_priv(dev); 986 int i, found_ix = -1; 987 int vf_gids = MLX4_ROCE_MAX_GIDS - MLX4_ROCE_PF_GIDS; 988 989 if (!mlx4_is_mfunc(dev)) 990 return -EINVAL; 991 992 for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) { 993 if (!memcmp(priv->roce_gids[port - 1][i].raw, gid, 16)) { 994 found_ix = i; 995 break; 996 } 997 } 998 999 if (found_ix >= 0) { 1000 if (found_ix < MLX4_ROCE_PF_GIDS) 1001 *slave_id = 0; 1002 else if (found_ix < MLX4_ROCE_PF_GIDS + (vf_gids % dev->num_vfs) * 1003 (vf_gids / dev->num_vfs + 1)) 1004 *slave_id = ((found_ix - MLX4_ROCE_PF_GIDS) / 1005 (vf_gids / dev->num_vfs + 1)) + 1; 1006 else 1007 *slave_id = 1008 ((found_ix - MLX4_ROCE_PF_GIDS - 1009 ((vf_gids % dev->num_vfs) * ((vf_gids / dev->num_vfs + 1)))) / 1010 (vf_gids / dev->num_vfs)) + vf_gids % dev->num_vfs + 1; 1011 } 1012 1013 return (found_ix >= 0) ? 0 : -EINVAL; 1014} 1015EXPORT_SYMBOL(mlx4_get_slave_from_roce_gid); 1016 1017int mlx4_get_roce_gid_from_slave(struct mlx4_dev *dev, int port, int slave_id, u8 *gid) 1018{ 1019 struct mlx4_priv *priv = mlx4_priv(dev); 1020 1021 if (!mlx4_is_master(dev)) 1022 return -EINVAL; 1023 1024 memcpy(gid, priv->roce_gids[port - 1][slave_id].raw, 16); 1025 return 0; 1026} 1027EXPORT_SYMBOL(mlx4_get_roce_gid_from_slave); 1028 1029/* Cable Module Info */ 1030#define MODULE_INFO_MAX_READ 48 1031 1032#define I2C_ADDR_LOW 0x50 1033#define I2C_ADDR_HIGH 0x51 1034#define I2C_PAGE_SIZE 256 1035 1036/* Module Info Data */ 1037struct mlx4_cable_info { 1038 u8 i2c_addr; 1039 u8 page_num; 1040 __be16 dev_mem_address; 1041 __be16 reserved1; 1042 __be16 size; 1043 __be32 reserved2[2]; 1044 u8 data[MODULE_INFO_MAX_READ]; 1045}; 1046 1047enum cable_info_err { 1048 CABLE_INF_INV_PORT = 0x1, 1049 CABLE_INF_OP_NOSUP = 0x2, 1050 CABLE_INF_NOT_CONN = 0x3, 1051 CABLE_INF_NO_EEPRM = 0x4, 1052 CABLE_INF_PAGE_ERR = 0x5, 1053 CABLE_INF_INV_ADDR = 0x6, 1054 CABLE_INF_I2C_ADDR = 0x7, 1055 CABLE_INF_QSFP_VIO = 0x8, 1056 CABLE_INF_I2C_BUSY = 0x9, 1057}; 1058 1059#define MAD_STATUS_2_CABLE_ERR(mad_status) ((mad_status >> 8) & 0xFF) 1060 1061#ifdef DEBUG 1062static inline const char *cable_info_mad_err_str(u16 mad_status) 1063{ 1064 u8 err = MAD_STATUS_2_CABLE_ERR(mad_status); 1065 1066 switch (err) { 1067 case CABLE_INF_INV_PORT: 1068 return "invalid port selected"; 1069 case CABLE_INF_OP_NOSUP: 1070 return "operation not supported for this port (the port is of type CX4 or internal)"; 1071 case CABLE_INF_NOT_CONN: 1072 return "cable is not connected"; 1073 case CABLE_INF_NO_EEPRM: 1074 return "the connected cable has no EPROM (passive copper cable)"; 1075 case CABLE_INF_PAGE_ERR: 1076 return "page number is greater than 15"; 1077 case CABLE_INF_INV_ADDR: 1078 return "invalid device_address or size (that is, size equals 0 or address+size is greater than 256)"; 1079 case CABLE_INF_I2C_ADDR: 1080 return "invalid I2C slave address"; 1081 case CABLE_INF_QSFP_VIO: 1082 return "at least one cable violates the QSFP specification and ignores the modsel signal"; 1083 case CABLE_INF_I2C_BUSY: 1084 return "I2C bus is constantly busy"; 1085 } 1086 return "Unknown Error"; 1087} 1088#endif /* DEBUG */ 1089 1090/** 1091 * mlx4_get_module_info - Read cable module eeprom data 1092 * @dev: mlx4_dev. 1093 * @port: port number. 1094 * @offset: byte offset in eeprom to start reading data from. 1095 * @size: num of bytes to read. 1096 * @data: output buffer to put the requested data into. 1097 * 1098 * Reads cable module eeprom data, puts the outcome data into 1099 * data pointer paramer. 1100 * Returns num of read bytes on success or a negative error 1101 * code. 1102 */ 1103int mlx4_get_module_info(struct mlx4_dev *dev, u8 port, u16 offset, 1104 u16 size, u8 *data) 1105{ 1106 struct mlx4_cmd_mailbox *inbox, *outbox; 1107 struct mlx4_mad_ifc *inmad, *outmad; 1108 struct mlx4_cable_info *cable_info; 1109 u16 i2c_addr; 1110 int ret; 1111 1112 if (size > MODULE_INFO_MAX_READ) 1113 size = MODULE_INFO_MAX_READ; 1114 1115 inbox = mlx4_alloc_cmd_mailbox(dev); 1116 if (IS_ERR(inbox)) { 1117 mlx4_err(dev, 1118 "mlx4_alloc_cmd_mailbox returned with error(%lx)", PTR_ERR(inbox)); 1119 return PTR_ERR(inbox); 1120 } 1121 1122 outbox = mlx4_alloc_cmd_mailbox(dev); 1123 if (IS_ERR(outbox)) { 1124 mlx4_free_cmd_mailbox(dev, inbox); 1125 mlx4_err(dev, 1126 "mlx4_alloc_cmd_mailbox returned with error(%lx)", PTR_ERR(outbox)); 1127 return PTR_ERR(outbox); 1128 } 1129 1130 inmad = (struct mlx4_mad_ifc *)(inbox->buf); 1131 outmad = (struct mlx4_mad_ifc *)(outbox->buf); 1132 1133 inmad->method = 0x1; /* Get */ 1134 inmad->class_version = 0x1; 1135 inmad->mgmt_class = 0x1; 1136 inmad->base_version = 0x1; 1137 inmad->attr_id = cpu_to_be16(0xFF60); /* Module Info */ 1138 1139 if (offset < I2C_PAGE_SIZE && offset + size > I2C_PAGE_SIZE) 1140 /* Cross pages reads are not allowed 1141 * read until offset 256 in low page 1142 */ 1143 size -= offset + size - I2C_PAGE_SIZE; 1144 1145 i2c_addr = I2C_ADDR_LOW; 1146 if (offset >= I2C_PAGE_SIZE) { 1147 /* Reset offset to high page */ 1148 i2c_addr = I2C_ADDR_HIGH; 1149 offset -= I2C_PAGE_SIZE; 1150 } 1151 1152 cable_info = (struct mlx4_cable_info *)inmad->data; 1153 cable_info->dev_mem_address = cpu_to_be16(offset); 1154 cable_info->page_num = 0; 1155 cable_info->i2c_addr = i2c_addr; 1156 cable_info->size = cpu_to_be16(size); 1157 1158 ret = mlx4_cmd_box(dev, inbox->dma, outbox->dma, port, 3, 1159 MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE); 1160 if (ret) 1161 goto out; 1162 1163 if (be16_to_cpu(outmad->status)) { 1164 /* Mad returned with bad status */ 1165 ret = be16_to_cpu(outmad->status); 1166#ifdef DEBUG 1167 mlx4_warn(dev, "MLX4_CMD_MAD_IFC Get Module info attr(%x) " 1168 "port(%d) i2c_addr(%x) offset(%d) size(%d): Response " 1169 "Mad Status(%x) - %s\n", 0xFF60, port, i2c_addr, offset, 1170 size, ret, cable_info_mad_err_str(ret)); 1171#endif 1172 if (i2c_addr == I2C_ADDR_HIGH && 1173 MAD_STATUS_2_CABLE_ERR(ret) == CABLE_INF_I2C_ADDR) 1174 /* Some SFP cables do not support i2c slave 1175 * address 0x51 (high page), abort silently. 1176 */ 1177 ret = 0; 1178 else 1179 ret = -ret; 1180 goto out; 1181 } 1182 cable_info = (struct mlx4_cable_info *)outmad->data; 1183 memcpy(data, cable_info->data, size); 1184 ret = size; 1185out: 1186 mlx4_free_cmd_mailbox(dev, inbox); 1187 mlx4_free_cmd_mailbox(dev, outbox); 1188 return ret; 1189} 1190EXPORT_SYMBOL(mlx4_get_module_info); 1191