mlx4_core: Allow protocol drivers to find corresponding interfaces
authorEli Cohen <eli@dev.mellanox.co.il>
Thu, 26 Aug 2010 14:18:43 +0000 (14:18 +0000)
committerRoland Dreier <rolandd@cisco.com>
Mon, 25 Oct 2010 17:20:39 +0000 (10:20 -0700)
Add a mechanism for mlx4 protocol drivers to get a pointer to other
drivers's device objects.  For this, an exported function,
mlx4_get_protocol_dev() is added, which allows a driver to get some
other driver's device based on the protocol that the driver
implements.  Two protocols are added: MLX4_PROTOCOL_IB and
MLX4_PROTOCOL_EN.

This will be used in mlx4 IBoE support so that mlx4_ib can find the
corresponding mlx4_en netdev.

Signed-off-by: Eli Cohen <eli@mellanox.co.il>
[ Clean up and rename a few things.  - Roland ]

Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/net/mlx4/en_main.c
drivers/net/mlx4/intf.c
include/linux/mlx4/driver.h

index 97934f1ec53af83c0dfe40e3b9e8730c83ae1c1e..b2df3eeb1598e88cb8f18f466917fcfc7638110b 100644 (file)
@@ -124,6 +124,13 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
        return 0;
 }
 
+static void *mlx4_en_get_netdev(struct mlx4_dev *dev, void *ctx, u8 port)
+{
+       struct mlx4_en_dev *endev = ctx;
+
+       return endev->pndev[port];
+}
+
 static void mlx4_en_event(struct mlx4_dev *dev, void *endev_ptr,
                          enum mlx4_dev_event event, int port)
 {
@@ -282,9 +289,11 @@ err_free_res:
 }
 
 static struct mlx4_interface mlx4_en_interface = {
-       .add    = mlx4_en_add,
-       .remove = mlx4_en_remove,
-       .event  = mlx4_en_event,
+       .add            = mlx4_en_add,
+       .remove         = mlx4_en_remove,
+       .event          = mlx4_en_event,
+       .get_dev        = mlx4_en_get_netdev,
+       .protocol       = MLX4_PROTOCOL_EN,
 };
 
 static int __init mlx4_en_init(void)
index 5550678027513fa6f7b443bffe63e72198f4ec1c..73c94fcdfddf0096318e4db7649a4c5a858e9f20 100644 (file)
@@ -161,3 +161,24 @@ void mlx4_unregister_device(struct mlx4_dev *dev)
 
        mutex_unlock(&intf_mutex);
 }
+
+void *mlx4_get_protocol_dev(struct mlx4_dev *dev, enum mlx4_protocol proto, int port)
+{
+       struct mlx4_priv *priv = mlx4_priv(dev);
+       struct mlx4_device_context *dev_ctx;
+       unsigned long flags;
+       void *result = NULL;
+
+       spin_lock_irqsave(&priv->ctx_lock, flags);
+
+       list_for_each_entry(dev_ctx, &priv->ctx_list, list)
+               if (dev_ctx->intf->protocol == proto && dev_ctx->intf->get_dev) {
+                       result = dev_ctx->intf->get_dev(dev, dev_ctx->context, port);
+                       break;
+               }
+
+       spin_unlock_irqrestore(&priv->ctx_lock, flags);
+
+       return result;
+}
+EXPORT_SYMBOL_GPL(mlx4_get_protocol_dev);
index 53c5fdb6eac48cae01caa030700d3817538de7f0..f407cd4bfb341d7a2ac0a6f624130fa8430f6d51 100644 (file)
@@ -44,15 +44,24 @@ enum mlx4_dev_event {
        MLX4_DEV_EVENT_PORT_REINIT,
 };
 
+enum mlx4_protocol {
+       MLX4_PROTOCOL_IB,
+       MLX4_PROTOCOL_EN,
+};
+
 struct mlx4_interface {
        void *                  (*add)   (struct mlx4_dev *dev);
        void                    (*remove)(struct mlx4_dev *dev, void *context);
        void                    (*event) (struct mlx4_dev *dev, void *context,
                                          enum mlx4_dev_event event, int port);
+       void *                  (*get_dev)(struct mlx4_dev *dev, void *context, u8 port);
        struct list_head        list;
+       enum mlx4_protocol      protocol;
 };
 
 int mlx4_register_interface(struct mlx4_interface *intf);
 void mlx4_unregister_interface(struct mlx4_interface *intf);
 
+void *mlx4_get_protocol_dev(struct mlx4_dev *dev, enum mlx4_protocol proto, int port);
+
 #endif /* MLX4_DRIVER_H */