aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2012-06-19 04:21:40 -0400
committerRoland Dreier <roland@purestorage.com>2012-07-10 12:47:10 -0400
commit00f5ce99dc6ee46c3113393cc8fa12173f9bbcd7 (patch)
treecbcd8e2afcd492b3677bf3eedec29b34f249129c /drivers/net/ethernet
parent3045f0920367e625bbec7d66fadb444e673515af (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.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/eq.c22
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/intf.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h63
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
133static void mlx4_en_event(struct mlx4_dev *dev, void *endev_ptr, 133static 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
85static 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
85static void eq_set_ci(struct mlx4_eq *eq, int req_not) 94static 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}
116EXPORT_SYMBOL_GPL(mlx4_unregister_interface); 116EXPORT_SYMBOL_GPL(mlx4_unregister_interface);
117 117
118void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_dev_event type, int port) 118void 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
341struct 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
401struct mlx4_eq { 341struct 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);
887int mlx4_restart_one(struct pci_dev *pdev); 827int mlx4_restart_one(struct pci_dev *pdev);
888int mlx4_register_device(struct mlx4_dev *dev); 828int mlx4_register_device(struct mlx4_dev *dev);
889void mlx4_unregister_device(struct mlx4_dev *dev); 829void mlx4_unregister_device(struct mlx4_dev *dev);
890void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_dev_event type, int port); 830void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_dev_event type,
831 unsigned long param);
891 832
892struct mlx4_dev_cap; 833struct mlx4_dev_cap;
893struct mlx4_init_hca_param; 834struct mlx4_init_hca_param;