RDMA/core: Add common iWARP query port
authorKamal Heib <kamalheib1@gmail.com>
Wed, 7 Aug 2019 10:31:37 +0000 (13:31 +0300)
committerDoug Ledford <dledford@redhat.com>
Mon, 12 Aug 2019 14:19:43 +0000 (10:19 -0400)
Add support for a common iWARP query port function, the new function
includes a common code that is used by the iWARP devices to update the
port attributes like max_mtu, active_mtu, state, and phys_state, the
function also includes a call for the driver-specific query_port callback
to query the device-specific port attributes.

Signed-off-by: Kamal Heib <kamalheib1@gmail.com>
Link: https://lore.kernel.org/r/20190807103138.17219-4-kamalheib1@gmail.com
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/core/device.c

index c3576c7..8892862 100644 (file)
@@ -1939,31 +1939,64 @@ void ib_dispatch_event(struct ib_event *event)
 }
 EXPORT_SYMBOL(ib_dispatch_event);
 
-/**
- * ib_query_port - Query IB port attributes
- * @device:Device to query
- * @port_num:Port number to query
- * @port_attr:Port attributes
- *
- * ib_query_port() returns the attributes of a port through the
- * @port_attr pointer.
- */
-int ib_query_port(struct ib_device *device,
-                 u8 port_num,
-                 struct ib_port_attr *port_attr)
+static int iw_query_port(struct ib_device *device,
+                          u8 port_num,
+                          struct ib_port_attr *port_attr)
 {
-       union ib_gid gid;
+       struct in_device *inetdev;
+       struct net_device *netdev;
        int err;
 
-       if (!rdma_is_port_valid(device, port_num))
-               return -EINVAL;
+       memset(port_attr, 0, sizeof(*port_attr));
+
+       netdev = ib_device_get_netdev(device, port_num);
+       if (!netdev)
+               return -ENODEV;
+
+       dev_put(netdev);
+
+       port_attr->max_mtu = IB_MTU_4096;
+       port_attr->active_mtu = ib_mtu_int_to_enum(netdev->mtu);
+
+       if (!netif_carrier_ok(netdev)) {
+               port_attr->state = IB_PORT_DOWN;
+               port_attr->phys_state = IB_PORT_PHYS_STATE_DISABLED;
+       } else {
+               inetdev = in_dev_get(netdev);
+
+               if (inetdev && inetdev->ifa_list) {
+                       port_attr->state = IB_PORT_ACTIVE;
+                       port_attr->phys_state = IB_PORT_PHYS_STATE_LINK_UP;
+                       in_dev_put(inetdev);
+               } else {
+                       port_attr->state = IB_PORT_INIT;
+                       port_attr->phys_state =
+                               IB_PORT_PHYS_STATE_PORT_CONFIGURATION_TRAINING;
+               }
+       }
+
+       err = device->ops.query_port(device, port_num, port_attr);
+       if (err)
+               return err;
+
+       return 0;
+}
+
+static int __ib_query_port(struct ib_device *device,
+                          u8 port_num,
+                          struct ib_port_attr *port_attr)
+{
+       union ib_gid gid = {};
+       int err;
 
        memset(port_attr, 0, sizeof(*port_attr));
+
        err = device->ops.query_port(device, port_num, port_attr);
        if (err || port_attr->subnet_prefix)
                return err;
 
-       if (rdma_port_get_link_layer(device, port_num) != IB_LINK_LAYER_INFINIBAND)
+       if (rdma_port_get_link_layer(device, port_num) !=
+           IB_LINK_LAYER_INFINIBAND)
                return 0;
 
        err = device->ops.query_gid(device, port_num, 0, &gid);
@@ -1973,6 +2006,28 @@ int ib_query_port(struct ib_device *device,
        port_attr->subnet_prefix = be64_to_cpu(gid.global.subnet_prefix);
        return 0;
 }
+
+/**
+ * ib_query_port - Query IB port attributes
+ * @device:Device to query
+ * @port_num:Port number to query
+ * @port_attr:Port attributes
+ *
+ * ib_query_port() returns the attributes of a port through the
+ * @port_attr pointer.
+ */
+int ib_query_port(struct ib_device *device,
+                 u8 port_num,
+                 struct ib_port_attr *port_attr)
+{
+       if (!rdma_is_port_valid(device, port_num))
+               return -EINVAL;
+
+       if (rdma_protocol_iwarp(device, port_num))
+               return iw_query_port(device, port_num, port_attr);
+       else
+               return __ib_query_port(device, port_num, port_attr);
+}
 EXPORT_SYMBOL(ib_query_port);
 
 static void add_ndev_hash(struct ib_port_data *pdata)