diff options
| author | Jack Morgenstein <jackm@dev.mellanox.co.il> | 2014-05-29 09:31:04 -0400 |
|---|---|---|
| committer | Roland Dreier <roland@purestorage.com> | 2014-05-30 00:13:19 -0400 |
| commit | 65fed8a8c155271cf647651bd62eecb5928ae3a4 (patch) | |
| tree | 786147e4ce5f7a1e5d753a9fbf125f025879cc43 | |
| parent | 99ec41d0a48cb6d14af25765f9449762f9d101f6 (diff) | |
IB/mlx4: Add interface for selecting VFs to enable QP0 via MLX proxy QPs
This commit adds the sysfs interface for enabling QP0 on VFs for
selected VF/port.
By default, no VFs are enabled for QP0 operation.
To enable QP0 operation on a VF/port, under
/sys/class/infiniband/mlx4_x/iov/<b:d:f>/ports/x there are two new entries:
- smi_enabled (read-only). Indicates whether smi is currently
enabled for the indicated VF/port
- enable_smi_admin (rw). Used by the admin to request that smi
capability be enabled or disabled for the indicated VF/port.
0 = disable, 1 = enable.
The requested enablement will occur at the next reset of the
VF (e.g. driver restart on the VM which owns the VF).
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
| -rw-r--r-- | drivers/infiniband/hw/mlx4/sysfs.c | 105 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 34 | ||||
| -rw-r--r-- | include/linux/mlx4/device.h | 3 |
3 files changed, 141 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/mlx4/sysfs.c b/drivers/infiniband/hw/mlx4/sysfs.c index 5a38e43eca65..cb4c66e723b5 100644 --- a/drivers/infiniband/hw/mlx4/sysfs.c +++ b/drivers/infiniband/hw/mlx4/sysfs.c | |||
| @@ -389,8 +389,10 @@ struct mlx4_port { | |||
| 389 | struct mlx4_ib_dev *dev; | 389 | struct mlx4_ib_dev *dev; |
| 390 | struct attribute_group pkey_group; | 390 | struct attribute_group pkey_group; |
| 391 | struct attribute_group gid_group; | 391 | struct attribute_group gid_group; |
| 392 | u8 port_num; | 392 | struct device_attribute enable_smi_admin; |
| 393 | struct device_attribute smi_enabled; | ||
| 393 | int slave; | 394 | int slave; |
| 395 | u8 port_num; | ||
| 394 | }; | 396 | }; |
| 395 | 397 | ||
| 396 | 398 | ||
| @@ -558,6 +560,101 @@ err: | |||
| 558 | return NULL; | 560 | return NULL; |
| 559 | } | 561 | } |
| 560 | 562 | ||
| 563 | static ssize_t sysfs_show_smi_enabled(struct device *dev, | ||
| 564 | struct device_attribute *attr, char *buf) | ||
| 565 | { | ||
| 566 | struct mlx4_port *p = | ||
| 567 | container_of(attr, struct mlx4_port, smi_enabled); | ||
| 568 | ssize_t len = 0; | ||
| 569 | |||
| 570 | if (mlx4_vf_smi_enabled(p->dev->dev, p->slave, p->port_num)) | ||
| 571 | len = sprintf(buf, "%d\n", 1); | ||
| 572 | else | ||
| 573 | len = sprintf(buf, "%d\n", 0); | ||
| 574 | |||
| 575 | return len; | ||
| 576 | } | ||
| 577 | |||
| 578 | static ssize_t sysfs_show_enable_smi_admin(struct device *dev, | ||
| 579 | struct device_attribute *attr, | ||
| 580 | char *buf) | ||
| 581 | { | ||
| 582 | struct mlx4_port *p = | ||
| 583 | container_of(attr, struct mlx4_port, enable_smi_admin); | ||
| 584 | ssize_t len = 0; | ||
| 585 | |||
| 586 | if (mlx4_vf_get_enable_smi_admin(p->dev->dev, p->slave, p->port_num)) | ||
| 587 | len = sprintf(buf, "%d\n", 1); | ||
| 588 | else | ||
| 589 | len = sprintf(buf, "%d\n", 0); | ||
| 590 | |||
| 591 | return len; | ||
| 592 | } | ||
| 593 | |||
| 594 | static ssize_t sysfs_store_enable_smi_admin(struct device *dev, | ||
| 595 | struct device_attribute *attr, | ||
| 596 | const char *buf, size_t count) | ||
| 597 | { | ||
| 598 | struct mlx4_port *p = | ||
| 599 | container_of(attr, struct mlx4_port, enable_smi_admin); | ||
| 600 | int enable; | ||
| 601 | |||
| 602 | if (sscanf(buf, "%i", &enable) != 1 || | ||
| 603 | enable < 0 || enable > 1) | ||
| 604 | return -EINVAL; | ||
| 605 | |||
| 606 | if (mlx4_vf_set_enable_smi_admin(p->dev->dev, p->slave, p->port_num, enable)) | ||
| 607 | return -EINVAL; | ||
| 608 | return count; | ||
| 609 | } | ||
| 610 | |||
| 611 | static int add_vf_smi_entries(struct mlx4_port *p) | ||
| 612 | { | ||
| 613 | int is_eth = rdma_port_get_link_layer(&p->dev->ib_dev, p->port_num) == | ||
| 614 | IB_LINK_LAYER_ETHERNET; | ||
| 615 | int ret; | ||
| 616 | |||
| 617 | /* do not display entries if eth transport, or if master */ | ||
| 618 | if (is_eth || p->slave == mlx4_master_func_num(p->dev->dev)) | ||
| 619 | return 0; | ||
| 620 | |||
| 621 | sysfs_attr_init(&p->smi_enabled.attr); | ||
| 622 | p->smi_enabled.show = sysfs_show_smi_enabled; | ||
| 623 | p->smi_enabled.store = NULL; | ||
| 624 | p->smi_enabled.attr.name = "smi_enabled"; | ||
| 625 | p->smi_enabled.attr.mode = 0444; | ||
| 626 | ret = sysfs_create_file(&p->kobj, &p->smi_enabled.attr); | ||
| 627 | if (ret) { | ||
| 628 | pr_err("failed to create smi_enabled\n"); | ||
| 629 | return ret; | ||
| 630 | } | ||
| 631 | |||
| 632 | sysfs_attr_init(&p->enable_smi_admin.attr); | ||
| 633 | p->enable_smi_admin.show = sysfs_show_enable_smi_admin; | ||
| 634 | p->enable_smi_admin.store = sysfs_store_enable_smi_admin; | ||
| 635 | p->enable_smi_admin.attr.name = "enable_smi_admin"; | ||
| 636 | p->enable_smi_admin.attr.mode = 0644; | ||
| 637 | ret = sysfs_create_file(&p->kobj, &p->enable_smi_admin.attr); | ||
| 638 | if (ret) { | ||
| 639 | pr_err("failed to create enable_smi_admin\n"); | ||
| 640 | sysfs_remove_file(&p->kobj, &p->smi_enabled.attr); | ||
| 641 | return ret; | ||
| 642 | } | ||
| 643 | return 0; | ||
| 644 | } | ||
| 645 | |||
| 646 | static void remove_vf_smi_entries(struct mlx4_port *p) | ||
| 647 | { | ||
| 648 | int is_eth = rdma_port_get_link_layer(&p->dev->ib_dev, p->port_num) == | ||
| 649 | IB_LINK_LAYER_ETHERNET; | ||
| 650 | |||
| 651 | if (is_eth || p->slave == mlx4_master_func_num(p->dev->dev)) | ||
| 652 | return; | ||
| 653 | |||
| 654 | sysfs_remove_file(&p->kobj, &p->smi_enabled.attr); | ||
| 655 | sysfs_remove_file(&p->kobj, &p->enable_smi_admin.attr); | ||
| 656 | } | ||
| 657 | |||
| 561 | static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave) | 658 | static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave) |
| 562 | { | 659 | { |
| 563 | struct mlx4_port *p; | 660 | struct mlx4_port *p; |
| @@ -602,6 +699,10 @@ static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave) | |||
| 602 | if (ret) | 699 | if (ret) |
| 603 | goto err_free_gid; | 700 | goto err_free_gid; |
| 604 | 701 | ||
| 702 | ret = add_vf_smi_entries(p); | ||
| 703 | if (ret) | ||
| 704 | goto err_free_gid; | ||
| 705 | |||
| 605 | list_add_tail(&p->kobj.entry, &dev->pkeys.pkey_port_list[slave]); | 706 | list_add_tail(&p->kobj.entry, &dev->pkeys.pkey_port_list[slave]); |
| 606 | return 0; | 707 | return 0; |
| 607 | 708 | ||
| @@ -669,6 +770,7 @@ err_add: | |||
| 669 | mport = container_of(p, struct mlx4_port, kobj); | 770 | mport = container_of(p, struct mlx4_port, kobj); |
| 670 | sysfs_remove_group(p, &mport->pkey_group); | 771 | sysfs_remove_group(p, &mport->pkey_group); |
| 671 | sysfs_remove_group(p, &mport->gid_group); | 772 | sysfs_remove_group(p, &mport->gid_group); |
| 773 | remove_vf_smi_entries(mport); | ||
| 672 | kobject_put(p); | 774 | kobject_put(p); |
| 673 | } | 775 | } |
| 674 | kobject_put(dev->dev_ports_parent[slave]); | 776 | kobject_put(dev->dev_ports_parent[slave]); |
| @@ -713,6 +815,7 @@ static void unregister_pkey_tree(struct mlx4_ib_dev *device) | |||
| 713 | port = container_of(p, struct mlx4_port, kobj); | 815 | port = container_of(p, struct mlx4_port, kobj); |
| 714 | sysfs_remove_group(p, &port->pkey_group); | 816 | sysfs_remove_group(p, &port->pkey_group); |
| 715 | sysfs_remove_group(p, &port->gid_group); | 817 | sysfs_remove_group(p, &port->gid_group); |
| 818 | remove_vf_smi_entries(port); | ||
| 716 | kobject_put(p); | 819 | kobject_put(p); |
| 717 | kobject_put(device->dev_ports_parent[slave]); | 820 | kobject_put(device->dev_ports_parent[slave]); |
| 718 | } | 821 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 26c3ebaa49d1..3370ecb8c3d2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c | |||
| @@ -2567,3 +2567,37 @@ int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port) | |||
| 2567 | MLX4_VF_SMI_ENABLED; | 2567 | MLX4_VF_SMI_ENABLED; |
| 2568 | } | 2568 | } |
| 2569 | EXPORT_SYMBOL_GPL(mlx4_vf_smi_enabled); | 2569 | EXPORT_SYMBOL_GPL(mlx4_vf_smi_enabled); |
| 2570 | |||
| 2571 | int mlx4_vf_get_enable_smi_admin(struct mlx4_dev *dev, int slave, int port) | ||
| 2572 | { | ||
| 2573 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
| 2574 | |||
| 2575 | if (slave == mlx4_master_func_num(dev)) | ||
| 2576 | return 1; | ||
| 2577 | |||
| 2578 | if (slave < 1 || slave >= dev->num_slaves || | ||
| 2579 | port < 1 || port > MLX4_MAX_PORTS) | ||
| 2580 | return 0; | ||
| 2581 | |||
| 2582 | return priv->mfunc.master.vf_admin[slave].enable_smi[port] == | ||
| 2583 | MLX4_VF_SMI_ENABLED; | ||
| 2584 | } | ||
| 2585 | EXPORT_SYMBOL_GPL(mlx4_vf_get_enable_smi_admin); | ||
| 2586 | |||
| 2587 | int mlx4_vf_set_enable_smi_admin(struct mlx4_dev *dev, int slave, int port, | ||
| 2588 | int enabled) | ||
| 2589 | { | ||
| 2590 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
| 2591 | |||
| 2592 | if (slave == mlx4_master_func_num(dev)) | ||
| 2593 | return 0; | ||
| 2594 | |||
| 2595 | if (slave < 1 || slave >= dev->num_slaves || | ||
| 2596 | port < 1 || port > MLX4_MAX_PORTS || | ||
| 2597 | enabled < 0 || enabled > 1) | ||
| 2598 | return -EINVAL; | ||
| 2599 | |||
| 2600 | priv->mfunc.master.vf_admin[slave].enable_smi[port] = enabled; | ||
| 2601 | return 0; | ||
| 2602 | } | ||
| 2603 | EXPORT_SYMBOL_GPL(mlx4_vf_set_enable_smi_admin); | ||
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index e2fc7011314c..dcabe11f37f7 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
| @@ -1236,4 +1236,7 @@ int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave, int port); | |||
| 1236 | 1236 | ||
| 1237 | int mlx4_config_vxlan_port(struct mlx4_dev *dev, __be16 udp_port); | 1237 | int mlx4_config_vxlan_port(struct mlx4_dev *dev, __be16 udp_port); |
| 1238 | int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port); | 1238 | int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port); |
| 1239 | int mlx4_vf_get_enable_smi_admin(struct mlx4_dev *dev, int slave, int port); | ||
| 1240 | int mlx4_vf_set_enable_smi_admin(struct mlx4_dev *dev, int slave, int port, | ||
| 1241 | int enable); | ||
| 1239 | #endif /* MLX4_DEVICE_H */ | 1242 | #endif /* MLX4_DEVICE_H */ |
