[PATCH 07/30] IB/core: Report gid_type and gid_ndev through sysfs

2015-02-18 Thread Somnath Kotur
From: Matan Barak 

Since we've added GID attributes to the RoCE GID table,
the users need a convenient way to query them.
Adding the GID type and relate net device to IB's sysfs.

The new attributes are available in:
/sys/class/infiniband//ports//gid_attrs/ndevs/
/sys/class/infiniband//ports//gid_attrs/types/

The  corresponds to the index of the respective GID in:
/sys/class/infiniband//ports//gids/

Signed-off-by: Matan Barak 
Signed-off-by: Somnath Kotur 
---
 drivers/infiniband/core/core_priv.h  |2 +
 drivers/infiniband/core/roce_gid_cache.c |   13 ++
 drivers/infiniband/core/sysfs.c  |  185 +-
 3 files changed, 198 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/core/core_priv.h 
b/drivers/infiniband/core/core_priv.h
index 6ab40a9..411672f 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -71,6 +71,8 @@ void ib_enum_roce_ports_of_netdev(roce_netdev_filter filter,
  roce_netdev_callback cb,
  void *cookie);
 
+const char *roce_gid_cache_type_str(enum ib_gid_type gid_type);
+
 int roce_gid_cache_get_gid(struct ib_device *ib_dev, u8 port, int index,
   union ib_gid *gid, struct ib_gid_attr *attr);
 
diff --git a/drivers/infiniband/core/roce_gid_cache.c 
b/drivers/infiniband/core/roce_gid_cache.c
index fc6a4e6..895b9c1 100644
--- a/drivers/infiniband/core/roce_gid_cache.c
+++ b/drivers/infiniband/core/roce_gid_cache.c
@@ -48,6 +48,11 @@ enum gid_attr_find_mask {
GID_ATTR_FIND_MASK_NETDEV   = 1UL << 1,
 };
 
+static const char * const gid_type_str[] = {
+   [IB_GID_TYPE_IB]= "IB/RoCE V1\n",
+   [IB_GID_TYPE_ROCE_V2]   = "RoCE V2\n",
+};
+
 static inline int start_port(struct ib_device *ib_dev)
 {
return (ib_dev->node_type == RDMA_NODE_IB_SWITCH) ? 0 : 1;
@@ -58,6 +63,14 @@ struct dev_put_rcu {
struct net_device   *ndev;
 };
 
+const char *roce_gid_cache_type_str(enum ib_gid_type gid_type)
+{
+   if (gid_type < ARRAY_SIZE(gid_type_str) && gid_type_str[gid_type])
+   return gid_type_str[gid_type];
+
+   return "Invalid GID type";
+}
+
 static void put_ndev(struct rcu_head *rcu)
 {
struct dev_put_rcu *put_rcu =
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 5cee246..51f0e32 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -37,12 +37,22 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
+struct ib_port;
+
+struct gid_attr_group {
+   struct ib_port  *port;
+   struct kobject  kobj;
+   struct attribute_group  ndev;
+   struct attribute_group  type;
+};
 struct ib_port {
struct kobject kobj;
struct ib_device  *ibdev;
+   struct gid_attr_group *gid_attr_group;
struct attribute_group gid_group;
struct attribute_group pkey_group;
u8 port_num;
@@ -84,6 +94,24 @@ static const struct sysfs_ops port_sysfs_ops = {
.show = port_attr_show
 };
 
+static ssize_t gid_attr_show(struct kobject *kobj,
+struct attribute *attr, char *buf)
+{
+   struct port_attribute *port_attr =
+   container_of(attr, struct port_attribute, attr);
+   struct ib_port *p = container_of(kobj, struct gid_attr_group,
+kobj)->port;
+
+   if (!port_attr->show)
+   return -EIO;
+
+   return port_attr->show(p, port_attr, buf);
+}
+
+static const struct sysfs_ops gid_attr_sysfs_ops = {
+   .show = gid_attr_show
+};
+
 static ssize_t state_show(struct ib_port *p, struct port_attribute *unused,
  char *buf)
 {
@@ -281,6 +309,46 @@ static struct attribute *port_default_attrs[] = {
NULL
 };
 
+static size_t print_ndev(struct ib_gid_attr *gid_attr, char *buf)
+{
+   if (!gid_attr->ndev)
+   return -EINVAL;
+
+   return sprintf(buf, "%s\n", gid_attr->ndev->name);
+}
+
+static size_t print_gid_type(struct ib_gid_attr *gid_attr, char *buf)
+{
+   return sprintf(buf, "%s", roce_gid_cache_type_str(gid_attr->gid_type));
+}
+
+static ssize_t _show_port_gid_attr(struct ib_port *p,
+  struct port_attribute *attr,
+  char *buf,
+  size_t (*print)(struct ib_gid_attr *gid_attr,
+  char *buf))
+{
+   struct port_table_attribute *tab_attr =
+   container_of(attr, struct port_table_attribute, attr);
+   union ib_gid gid;
+   struct ib_gid_attr gid_attr;
+   ssize_t ret;
+   va_list args;
+
+   rcu_read_lock();
+   ret = ib_query_gid(p->ibdev, p->port_num, tab_attr->index, &gid,
+  &gid_attr);
+   if (ret)
+   goto err;
+
+  

[PATCH 07/30] IB/core: Report gid_type and gid_ndev through sysfs

2015-02-18 Thread Somnath Kotur
From: Matan Barak 

Since we've added GID attributes to the RoCE GID table,
the users need a convenient way to query them.
Adding the GID type and relate net device to IB's sysfs.

The new attributes are available in:
/sys/class/infiniband//ports//gid_attrs/ndevs/
/sys/class/infiniband//ports//gid_attrs/types/

The  corresponds to the index of the respective GID in:
/sys/class/infiniband//ports//gids/

Signed-off-by: Matan Barak 
Signed-off-by: Somnath Kotur 
---
 drivers/infiniband/core/core_priv.h  |2 +
 drivers/infiniband/core/roce_gid_cache.c |   13 ++
 drivers/infiniband/core/sysfs.c  |  185 +-
 3 files changed, 198 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/core/core_priv.h 
b/drivers/infiniband/core/core_priv.h
index 6ab40a9..411672f 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -71,6 +71,8 @@ void ib_enum_roce_ports_of_netdev(roce_netdev_filter filter,
  roce_netdev_callback cb,
  void *cookie);
 
+const char *roce_gid_cache_type_str(enum ib_gid_type gid_type);
+
 int roce_gid_cache_get_gid(struct ib_device *ib_dev, u8 port, int index,
   union ib_gid *gid, struct ib_gid_attr *attr);
 
diff --git a/drivers/infiniband/core/roce_gid_cache.c 
b/drivers/infiniband/core/roce_gid_cache.c
index fc6a4e6..895b9c1 100644
--- a/drivers/infiniband/core/roce_gid_cache.c
+++ b/drivers/infiniband/core/roce_gid_cache.c
@@ -48,6 +48,11 @@ enum gid_attr_find_mask {
GID_ATTR_FIND_MASK_NETDEV   = 1UL << 1,
 };
 
+static const char * const gid_type_str[] = {
+   [IB_GID_TYPE_IB]= "IB/RoCE V1\n",
+   [IB_GID_TYPE_ROCE_V2]   = "RoCE V2\n",
+};
+
 static inline int start_port(struct ib_device *ib_dev)
 {
return (ib_dev->node_type == RDMA_NODE_IB_SWITCH) ? 0 : 1;
@@ -58,6 +63,14 @@ struct dev_put_rcu {
struct net_device   *ndev;
 };
 
+const char *roce_gid_cache_type_str(enum ib_gid_type gid_type)
+{
+   if (gid_type < ARRAY_SIZE(gid_type_str) && gid_type_str[gid_type])
+   return gid_type_str[gid_type];
+
+   return "Invalid GID type";
+}
+
 static void put_ndev(struct rcu_head *rcu)
 {
struct dev_put_rcu *put_rcu =
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 5cee246..51f0e32 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -37,12 +37,22 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
+struct ib_port;
+
+struct gid_attr_group {
+   struct ib_port  *port;
+   struct kobject  kobj;
+   struct attribute_group  ndev;
+   struct attribute_group  type;
+};
 struct ib_port {
struct kobject kobj;
struct ib_device  *ibdev;
+   struct gid_attr_group *gid_attr_group;
struct attribute_group gid_group;
struct attribute_group pkey_group;
u8 port_num;
@@ -84,6 +94,24 @@ static const struct sysfs_ops port_sysfs_ops = {
.show = port_attr_show
 };
 
+static ssize_t gid_attr_show(struct kobject *kobj,
+struct attribute *attr, char *buf)
+{
+   struct port_attribute *port_attr =
+   container_of(attr, struct port_attribute, attr);
+   struct ib_port *p = container_of(kobj, struct gid_attr_group,
+kobj)->port;
+
+   if (!port_attr->show)
+   return -EIO;
+
+   return port_attr->show(p, port_attr, buf);
+}
+
+static const struct sysfs_ops gid_attr_sysfs_ops = {
+   .show = gid_attr_show
+};
+
 static ssize_t state_show(struct ib_port *p, struct port_attribute *unused,
  char *buf)
 {
@@ -281,6 +309,46 @@ static struct attribute *port_default_attrs[] = {
NULL
 };
 
+static size_t print_ndev(struct ib_gid_attr *gid_attr, char *buf)
+{
+   if (!gid_attr->ndev)
+   return -EINVAL;
+
+   return sprintf(buf, "%s\n", gid_attr->ndev->name);
+}
+
+static size_t print_gid_type(struct ib_gid_attr *gid_attr, char *buf)
+{
+   return sprintf(buf, "%s", roce_gid_cache_type_str(gid_attr->gid_type));
+}
+
+static ssize_t _show_port_gid_attr(struct ib_port *p,
+  struct port_attribute *attr,
+  char *buf,
+  size_t (*print)(struct ib_gid_attr *gid_attr,
+  char *buf))
+{
+   struct port_table_attribute *tab_attr =
+   container_of(attr, struct port_table_attribute, attr);
+   union ib_gid gid;
+   struct ib_gid_attr gid_attr;
+   ssize_t ret;
+   va_list args;
+
+   rcu_read_lock();
+   ret = ib_query_gid(p->ibdev, p->port_num, tab_attr->index, &gid,
+  &gid_attr);
+   if (ret)
+   goto err;
+
+