Эх сурвалжийг харах

mlx4_core: Allow protocol drivers to find corresponding interfaces

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>
Eli Cohen 14 жил өмнө
parent
commit
33c87f0af6

+ 12 - 3
drivers/net/mlx4/en_main.c

@@ -124,6 +124,13 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
 	return 0;
 	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,
 static void mlx4_en_event(struct mlx4_dev *dev, void *endev_ptr,
 			  enum mlx4_dev_event event, int port)
 			  enum mlx4_dev_event event, int port)
 {
 {
@@ -282,9 +289,11 @@ err_free_res:
 }
 }
 
 
 static struct mlx4_interface mlx4_en_interface = {
 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)
 static int __init mlx4_en_init(void)

+ 21 - 0
drivers/net/mlx4/intf.c

@@ -161,3 +161,24 @@ void mlx4_unregister_device(struct mlx4_dev *dev)
 
 
 	mutex_unlock(&intf_mutex);
 	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);

+ 9 - 0
include/linux/mlx4/driver.h

@@ -44,15 +44,24 @@ enum mlx4_dev_event {
 	MLX4_DEV_EVENT_PORT_REINIT,
 	MLX4_DEV_EVENT_PORT_REINIT,
 };
 };
 
 
+enum mlx4_protocol {
+	MLX4_PROTOCOL_IB,
+	MLX4_PROTOCOL_EN,
+};
+
 struct mlx4_interface {
 struct mlx4_interface {
 	void *			(*add)	 (struct mlx4_dev *dev);
 	void *			(*add)	 (struct mlx4_dev *dev);
 	void			(*remove)(struct mlx4_dev *dev, void *context);
 	void			(*remove)(struct mlx4_dev *dev, void *context);
 	void			(*event) (struct mlx4_dev *dev, void *context,
 	void			(*event) (struct mlx4_dev *dev, void *context,
 					  enum mlx4_dev_event event, int port);
 					  enum mlx4_dev_event event, int port);
+	void *			(*get_dev)(struct mlx4_dev *dev, void *context, u8 port);
 	struct list_head	list;
 	struct list_head	list;
+	enum mlx4_protocol	protocol;
 };
 };
 
 
 int mlx4_register_interface(struct mlx4_interface *intf);
 int mlx4_register_interface(struct mlx4_interface *intf);
 void mlx4_unregister_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 */
 #endif /* MLX4_DRIVER_H */