diff options
author | Jack Morgenstein <jackm@dev.mellanox.co.il> | 2012-06-19 04:21:40 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2012-07-10 12:47:10 -0400 |
commit | 00f5ce99dc6ee46c3113393cc8fa12173f9bbcd7 (patch) | |
tree | cbcd8e2afcd492b3677bf3eedec29b34f249129c /drivers/net/ethernet | |
parent | 3045f0920367e625bbec7d66fadb444e673515af (diff) |
mlx4: Use port management change event instead of smp_snoop
The port management change event can replace smp_snoop. If the
capability bit for this event is set in dev-caps, the event is used
(by the driver setting the PORT_MNG_CHG_EVENT bit in the async event
mask in the MAP_EQ fw command). In this case, when the driver passes
incoming SMP PORT_INFO SET mads to the FW, the FW generates port
management change events to signal any changes to the driver.
If the FW generates these events, smp_snoop shouldn't be invoked in
ib_process_mad(), or duplicate events will occur (once from the
FW-generated event, and once from smp_snoop).
In the case where the FW does not generate port management change
events smp_snoop needs to be invoked to create these events. The flow
in smp_snoop has been modified to make use of the same procedures as
in the fw-generated-event event case to generate the port management
events (LID change, Client-rereg, Pkey change, and/or GID change).
Port management change event handling required changing the
mlx4_ib_event and mlx4_dispatch_event prototypes; the "param" argument
(last argument) had to be changed to unsigned long in order to
accomodate passing the EQE pointer.
We also needed to move the definition of struct mlx4_eqe from
net/mlx4.h to file device.h -- to make it available to the IB driver,
to handle port management change events.
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_main.c | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/eq.c | 22 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/intf.c | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 63 |
5 files changed, 27 insertions, 69 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c index 69ba57270481..a52922ed85c1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c | |||
@@ -131,7 +131,7 @@ static void *mlx4_en_get_netdev(struct mlx4_dev *dev, void *ctx, u8 port) | |||
131 | } | 131 | } |
132 | 132 | ||
133 | static void mlx4_en_event(struct mlx4_dev *dev, void *endev_ptr, | 133 | static void mlx4_en_event(struct mlx4_dev *dev, void *endev_ptr, |
134 | enum mlx4_dev_event event, int port) | 134 | enum mlx4_dev_event event, unsigned long port) |
135 | { | 135 | { |
136 | struct mlx4_en_dev *mdev = (struct mlx4_en_dev *) endev_ptr; | 136 | struct mlx4_en_dev *mdev = (struct mlx4_en_dev *) endev_ptr; |
137 | struct mlx4_en_priv *priv; | 137 | struct mlx4_en_priv *priv; |
@@ -156,7 +156,8 @@ static void mlx4_en_event(struct mlx4_dev *dev, void *endev_ptr, | |||
156 | if (port < 1 || port > dev->caps.num_ports || | 156 | if (port < 1 || port > dev->caps.num_ports || |
157 | !mdev->pndev[port]) | 157 | !mdev->pndev[port]) |
158 | return; | 158 | return; |
159 | mlx4_warn(mdev, "Unhandled event %d for port %d\n", event, port); | 159 | mlx4_warn(mdev, "Unhandled event %d for port %d\n", event, |
160 | (int) port); | ||
160 | } | 161 | } |
161 | } | 162 | } |
162 | 163 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index bce98d9c0039..9b15d0219950 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c | |||
@@ -82,6 +82,15 @@ enum { | |||
82 | (1ull << MLX4_EVENT_TYPE_FLR_EVENT) | \ | 82 | (1ull << MLX4_EVENT_TYPE_FLR_EVENT) | \ |
83 | (1ull << MLX4_EVENT_TYPE_FATAL_WARNING)) | 83 | (1ull << MLX4_EVENT_TYPE_FATAL_WARNING)) |
84 | 84 | ||
85 | static u64 get_async_ev_mask(struct mlx4_dev *dev) | ||
86 | { | ||
87 | u64 async_ev_mask = MLX4_ASYNC_EVENT_MASK; | ||
88 | if (dev->caps.flags & MLX4_DEV_CAP_FLAG_PORT_MNG_CHG_EV) | ||
89 | async_ev_mask |= (1ull << MLX4_EVENT_TYPE_PORT_MNG_CHG_EVENT); | ||
90 | |||
91 | return async_ev_mask; | ||
92 | } | ||
93 | |||
85 | static void eq_set_ci(struct mlx4_eq *eq, int req_not) | 94 | static void eq_set_ci(struct mlx4_eq *eq, int req_not) |
86 | { | 95 | { |
87 | __raw_writel((__force u32) cpu_to_be32((eq->cons_index & 0xffffff) | | 96 | __raw_writel((__force u32) cpu_to_be32((eq->cons_index & 0xffffff) | |
@@ -473,6 +482,11 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) | |||
473 | 482 | ||
474 | break; | 483 | break; |
475 | 484 | ||
485 | case MLX4_EVENT_TYPE_PORT_MNG_CHG_EVENT: | ||
486 | mlx4_dispatch_event(dev, MLX4_DEV_EVENT_PORT_MGMT_CHANGE, | ||
487 | (unsigned long) eqe); | ||
488 | break; | ||
489 | |||
476 | case MLX4_EVENT_TYPE_EEC_CATAS_ERROR: | 490 | case MLX4_EVENT_TYPE_EEC_CATAS_ERROR: |
477 | case MLX4_EVENT_TYPE_ECC_DETECT: | 491 | case MLX4_EVENT_TYPE_ECC_DETECT: |
478 | default: | 492 | default: |
@@ -956,7 +970,7 @@ int mlx4_init_eq_table(struct mlx4_dev *dev) | |||
956 | priv->eq_table.have_irq = 1; | 970 | priv->eq_table.have_irq = 1; |
957 | } | 971 | } |
958 | 972 | ||
959 | err = mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0, | 973 | err = mlx4_MAP_EQ(dev, get_async_ev_mask(dev), 0, |
960 | priv->eq_table.eq[dev->caps.num_comp_vectors].eqn); | 974 | priv->eq_table.eq[dev->caps.num_comp_vectors].eqn); |
961 | if (err) | 975 | if (err) |
962 | mlx4_warn(dev, "MAP_EQ for async EQ %d failed (%d)\n", | 976 | mlx4_warn(dev, "MAP_EQ for async EQ %d failed (%d)\n", |
@@ -996,7 +1010,7 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev) | |||
996 | struct mlx4_priv *priv = mlx4_priv(dev); | 1010 | struct mlx4_priv *priv = mlx4_priv(dev); |
997 | int i; | 1011 | int i; |
998 | 1012 | ||
999 | mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 1, | 1013 | mlx4_MAP_EQ(dev, get_async_ev_mask(dev), 1, |
1000 | priv->eq_table.eq[dev->caps.num_comp_vectors].eqn); | 1014 | priv->eq_table.eq[dev->caps.num_comp_vectors].eqn); |
1001 | 1015 | ||
1002 | mlx4_free_irqs(dev); | 1016 | mlx4_free_irqs(dev); |
@@ -1040,7 +1054,7 @@ int mlx4_test_interrupts(struct mlx4_dev *dev) | |||
1040 | mlx4_cmd_use_polling(dev); | 1054 | mlx4_cmd_use_polling(dev); |
1041 | 1055 | ||
1042 | /* Map the new eq to handle all asyncronous events */ | 1056 | /* Map the new eq to handle all asyncronous events */ |
1043 | err = mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0, | 1057 | err = mlx4_MAP_EQ(dev, get_async_ev_mask(dev), 0, |
1044 | priv->eq_table.eq[i].eqn); | 1058 | priv->eq_table.eq[i].eqn); |
1045 | if (err) { | 1059 | if (err) { |
1046 | mlx4_warn(dev, "Failed mapping eq for interrupt test\n"); | 1060 | mlx4_warn(dev, "Failed mapping eq for interrupt test\n"); |
@@ -1054,7 +1068,7 @@ int mlx4_test_interrupts(struct mlx4_dev *dev) | |||
1054 | } | 1068 | } |
1055 | 1069 | ||
1056 | /* Return to default */ | 1070 | /* Return to default */ |
1057 | mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0, | 1071 | mlx4_MAP_EQ(dev, get_async_ev_mask(dev), 0, |
1058 | priv->eq_table.eq[dev->caps.num_comp_vectors].eqn); | 1072 | priv->eq_table.eq[dev->caps.num_comp_vectors].eqn); |
1059 | return err; | 1073 | return err; |
1060 | } | 1074 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 4281ce09add8..ee9d6b0b4d20 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -109,6 +109,7 @@ static void dump_dev_cap_flags(struct mlx4_dev *dev, u64 flags) | |||
109 | [41] = "Unicast VEP steering support", | 109 | [41] = "Unicast VEP steering support", |
110 | [42] = "Multicast VEP steering support", | 110 | [42] = "Multicast VEP steering support", |
111 | [48] = "Counters support", | 111 | [48] = "Counters support", |
112 | [59] = "Port management change event support", | ||
112 | }; | 113 | }; |
113 | int i; | 114 | int i; |
114 | 115 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/intf.c b/drivers/net/ethernet/mellanox/mlx4/intf.c index b4e9f6f5cc04..116895ac8b35 100644 --- a/drivers/net/ethernet/mellanox/mlx4/intf.c +++ b/drivers/net/ethernet/mellanox/mlx4/intf.c | |||
@@ -115,7 +115,8 @@ void mlx4_unregister_interface(struct mlx4_interface *intf) | |||
115 | } | 115 | } |
116 | EXPORT_SYMBOL_GPL(mlx4_unregister_interface); | 116 | EXPORT_SYMBOL_GPL(mlx4_unregister_interface); |
117 | 117 | ||
118 | void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_dev_event type, int port) | 118 | void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_dev_event type, |
119 | unsigned long param) | ||
119 | { | 120 | { |
120 | struct mlx4_priv *priv = mlx4_priv(dev); | 121 | struct mlx4_priv *priv = mlx4_priv(dev); |
121 | struct mlx4_device_context *dev_ctx; | 122 | struct mlx4_device_context *dev_ctx; |
@@ -125,7 +126,7 @@ void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_dev_event type, int por | |||
125 | 126 | ||
126 | list_for_each_entry(dev_ctx, &priv->ctx_list, list) | 127 | list_for_each_entry(dev_ctx, &priv->ctx_list, list) |
127 | if (dev_ctx->intf->event) | 128 | if (dev_ctx->intf->event) |
128 | dev_ctx->intf->event(dev, dev_ctx->context, type, port); | 129 | dev_ctx->intf->event(dev, dev_ctx->context, type, param); |
129 | 130 | ||
130 | spin_unlock_irqrestore(&priv->ctx_lock, flags); | 131 | spin_unlock_irqrestore(&priv->ctx_lock, flags); |
131 | } | 132 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index e5d20220762c..4d11d12b9db4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -338,66 +338,6 @@ struct mlx4_srq_context { | |||
338 | __be64 db_rec_addr; | 338 | __be64 db_rec_addr; |
339 | }; | 339 | }; |
340 | 340 | ||
341 | struct mlx4_eqe { | ||
342 | u8 reserved1; | ||
343 | u8 type; | ||
344 | u8 reserved2; | ||
345 | u8 subtype; | ||
346 | union { | ||
347 | u32 raw[6]; | ||
348 | struct { | ||
349 | __be32 cqn; | ||
350 | } __packed comp; | ||
351 | struct { | ||
352 | u16 reserved1; | ||
353 | __be16 token; | ||
354 | u32 reserved2; | ||
355 | u8 reserved3[3]; | ||
356 | u8 status; | ||
357 | __be64 out_param; | ||
358 | } __packed cmd; | ||
359 | struct { | ||
360 | __be32 qpn; | ||
361 | } __packed qp; | ||
362 | struct { | ||
363 | __be32 srqn; | ||
364 | } __packed srq; | ||
365 | struct { | ||
366 | __be32 cqn; | ||
367 | u32 reserved1; | ||
368 | u8 reserved2[3]; | ||
369 | u8 syndrome; | ||
370 | } __packed cq_err; | ||
371 | struct { | ||
372 | u32 reserved1[2]; | ||
373 | __be32 port; | ||
374 | } __packed port_change; | ||
375 | struct { | ||
376 | #define COMM_CHANNEL_BIT_ARRAY_SIZE 4 | ||
377 | u32 reserved; | ||
378 | u32 bit_vec[COMM_CHANNEL_BIT_ARRAY_SIZE]; | ||
379 | } __packed comm_channel_arm; | ||
380 | struct { | ||
381 | u8 port; | ||
382 | u8 reserved[3]; | ||
383 | __be64 mac; | ||
384 | } __packed mac_update; | ||
385 | struct { | ||
386 | u8 port; | ||
387 | } __packed sw_event; | ||
388 | struct { | ||
389 | __be32 slave_id; | ||
390 | } __packed flr_event; | ||
391 | struct { | ||
392 | __be16 current_temperature; | ||
393 | __be16 warning_threshold; | ||
394 | } __packed warming; | ||
395 | } event; | ||
396 | u8 slave_id; | ||
397 | u8 reserved3[2]; | ||
398 | u8 owner; | ||
399 | } __packed; | ||
400 | |||
401 | struct mlx4_eq { | 341 | struct mlx4_eq { |
402 | struct mlx4_dev *dev; | 342 | struct mlx4_dev *dev; |
403 | void __iomem *doorbell; | 343 | void __iomem *doorbell; |
@@ -887,7 +827,8 @@ void mlx4_catas_init(void); | |||
887 | int mlx4_restart_one(struct pci_dev *pdev); | 827 | int mlx4_restart_one(struct pci_dev *pdev); |
888 | int mlx4_register_device(struct mlx4_dev *dev); | 828 | int mlx4_register_device(struct mlx4_dev *dev); |
889 | void mlx4_unregister_device(struct mlx4_dev *dev); | 829 | void mlx4_unregister_device(struct mlx4_dev *dev); |
890 | void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_dev_event type, int port); | 830 | void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_dev_event type, |
831 | unsigned long param); | ||
891 | 832 | ||
892 | struct mlx4_dev_cap; | 833 | struct mlx4_dev_cap; |
893 | struct mlx4_init_hca_param; | 834 | struct mlx4_init_hca_param; |