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 */ |