diff options
author | Eyal Perry <eyalpe@mellanox.com> | 2013-10-15 10:55:24 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-10-17 15:10:50 -0400 |
commit | b046ffe54dc13ff8ae918c83bedb71aa7919d63b (patch) | |
tree | c0de954cd9f65b6c6368215261992f0b7c3b7337 | |
parent | 39e210fd23d45cf2521aaf0855c838bc5e37fbd6 (diff) |
net/mlx4_core: Load higher level modules according to ports type
Mellanox ConnectX architecture is: mlx4_core is the lower level
PCI driver which register on the PCI id, and protocol specific drivers
are depended on it: mlx4_en - for Ethernet and mlx4_ib for Infiniband.
NIC could have multiple ports which can change their type dynamically.
We use the request_module() call to load the relevant protocol driver
when needed: on loading time or at port type change event.
Signed-off-by: Eyal Perry <eyalpe@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 60c9f4f103fc..179d26709c94 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/io-mapping.h> | 42 | #include <linux/io-mapping.h> |
43 | #include <linux/delay.h> | 43 | #include <linux/delay.h> |
44 | #include <linux/netdevice.h> | 44 | #include <linux/netdevice.h> |
45 | #include <linux/kmod.h> | ||
45 | 46 | ||
46 | #include <linux/mlx4/device.h> | 47 | #include <linux/mlx4/device.h> |
47 | #include <linux/mlx4/doorbell.h> | 48 | #include <linux/mlx4/doorbell.h> |
@@ -650,6 +651,27 @@ err_mem: | |||
650 | return err; | 651 | return err; |
651 | } | 652 | } |
652 | 653 | ||
654 | static void mlx4_request_modules(struct mlx4_dev *dev) | ||
655 | { | ||
656 | int port; | ||
657 | int has_ib_port = false; | ||
658 | int has_eth_port = false; | ||
659 | #define EN_DRV_NAME "mlx4_en" | ||
660 | #define IB_DRV_NAME "mlx4_ib" | ||
661 | |||
662 | for (port = 1; port <= dev->caps.num_ports; port++) { | ||
663 | if (dev->caps.port_type[port] == MLX4_PORT_TYPE_IB) | ||
664 | has_ib_port = true; | ||
665 | else if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) | ||
666 | has_eth_port = true; | ||
667 | } | ||
668 | |||
669 | if (has_ib_port) | ||
670 | request_module_nowait(IB_DRV_NAME); | ||
671 | if (has_eth_port) | ||
672 | request_module_nowait(EN_DRV_NAME); | ||
673 | } | ||
674 | |||
653 | /* | 675 | /* |
654 | * Change the port configuration of the device. | 676 | * Change the port configuration of the device. |
655 | * Every user of this function must hold the port mutex. | 677 | * Every user of this function must hold the port mutex. |
@@ -681,6 +703,11 @@ int mlx4_change_port_types(struct mlx4_dev *dev, | |||
681 | } | 703 | } |
682 | mlx4_set_port_mask(dev); | 704 | mlx4_set_port_mask(dev); |
683 | err = mlx4_register_device(dev); | 705 | err = mlx4_register_device(dev); |
706 | if (err) { | ||
707 | mlx4_err(dev, "Failed to register device\n"); | ||
708 | goto out; | ||
709 | } | ||
710 | mlx4_request_modules(dev); | ||
684 | } | 711 | } |
685 | 712 | ||
686 | out: | 713 | out: |
@@ -2305,6 +2332,8 @@ slave_start: | |||
2305 | if (err) | 2332 | if (err) |
2306 | goto err_port; | 2333 | goto err_port; |
2307 | 2334 | ||
2335 | mlx4_request_modules(dev); | ||
2336 | |||
2308 | mlx4_sense_init(dev); | 2337 | mlx4_sense_init(dev); |
2309 | mlx4_start_sense(dev); | 2338 | mlx4_start_sense(dev); |
2310 | 2339 | ||