@@ -107,13 +107,32 @@ static int mlx5_netdev_event(struct notifier_block *this,
107
107
struct mlx5_ib_dev * ibdev = container_of (this , struct mlx5_ib_dev ,
108
108
roce .nb );
109
109
110
- if ((event != NETDEV_UNREGISTER ) && (event != NETDEV_REGISTER ))
111
- return NOTIFY_DONE ;
110
+ switch (event ) {
111
+ case NETDEV_REGISTER :
112
+ case NETDEV_UNREGISTER :
113
+ write_lock (& ibdev -> roce .netdev_lock );
114
+ if (ndev -> dev .parent == & ibdev -> mdev -> pdev -> dev )
115
+ ibdev -> roce .netdev = (event == NETDEV_UNREGISTER ) ?
116
+ NULL : ndev ;
117
+ write_unlock (& ibdev -> roce .netdev_lock );
118
+ break ;
112
119
113
- write_lock (& ibdev -> roce .netdev_lock );
114
- if (ndev -> dev .parent == & ibdev -> mdev -> pdev -> dev )
115
- ibdev -> roce .netdev = (event == NETDEV_UNREGISTER ) ? NULL : ndev ;
116
- write_unlock (& ibdev -> roce .netdev_lock );
120
+ case NETDEV_UP :
121
+ case NETDEV_DOWN :
122
+ if (ndev == ibdev -> roce .netdev && ibdev -> ib_active ) {
123
+ struct ib_event ibev = {0 };
124
+
125
+ ibev .device = & ibdev -> ib_dev ;
126
+ ibev .event = (event == NETDEV_UP ) ?
127
+ IB_EVENT_PORT_ACTIVE : IB_EVENT_PORT_ERR ;
128
+ ibev .element .port_num = 1 ;
129
+ ib_dispatch_event (& ibev );
130
+ }
131
+ break ;
132
+
133
+ default :
134
+ break ;
135
+ }
117
136
118
137
return NOTIFY_DONE ;
119
138
}
@@ -2267,14 +2286,19 @@ static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context,
2267
2286
break ;
2268
2287
2269
2288
case MLX5_DEV_EVENT_PORT_UP :
2270
- ibev .event = IB_EVENT_PORT_ACTIVE ;
2271
- port = (u8 )param ;
2272
- break ;
2273
-
2274
2289
case MLX5_DEV_EVENT_PORT_DOWN :
2275
2290
case MLX5_DEV_EVENT_PORT_INITIALIZED :
2276
- ibev .event = IB_EVENT_PORT_ERR ;
2277
2291
port = (u8 )param ;
2292
+
2293
+ /* In RoCE, port up/down events are handled in
2294
+ * mlx5_netdev_event().
2295
+ */
2296
+ if (mlx5_ib_port_link_layer (& ibdev -> ib_dev , port ) ==
2297
+ IB_LINK_LAYER_ETHERNET )
2298
+ return ;
2299
+
2300
+ ibev .event = (event == MLX5_DEV_EVENT_PORT_UP ) ?
2301
+ IB_EVENT_PORT_ACTIVE : IB_EVENT_PORT_ERR ;
2278
2302
break ;
2279
2303
2280
2304
case MLX5_DEV_EVENT_LID_CHANGE :
@@ -2679,14 +2703,24 @@ static void get_dev_fw_str(struct ib_device *ibdev, char *str,
2679
2703
fw_rev_min (dev -> mdev ), fw_rev_sub (dev -> mdev ));
2680
2704
}
2681
2705
2706
+ static void mlx5_remove_roce_notifier (struct mlx5_ib_dev * dev )
2707
+ {
2708
+ if (dev -> roce .nb .notifier_call ) {
2709
+ unregister_netdevice_notifier (& dev -> roce .nb );
2710
+ dev -> roce .nb .notifier_call = NULL ;
2711
+ }
2712
+ }
2713
+
2682
2714
static int mlx5_enable_roce (struct mlx5_ib_dev * dev )
2683
2715
{
2684
2716
int err ;
2685
2717
2686
2718
dev -> roce .nb .notifier_call = mlx5_netdev_event ;
2687
2719
err = register_netdevice_notifier (& dev -> roce .nb );
2688
- if (err )
2720
+ if (err ) {
2721
+ dev -> roce .nb .notifier_call = NULL ;
2689
2722
return err ;
2723
+ }
2690
2724
2691
2725
err = mlx5_nic_vport_enable_roce (dev -> mdev );
2692
2726
if (err )
@@ -2695,14 +2729,13 @@ static int mlx5_enable_roce(struct mlx5_ib_dev *dev)
2695
2729
return 0 ;
2696
2730
2697
2731
err_unregister_netdevice_notifier :
2698
- unregister_netdevice_notifier ( & dev -> roce . nb );
2732
+ mlx5_remove_roce_notifier ( dev );
2699
2733
return err ;
2700
2734
}
2701
2735
2702
2736
static void mlx5_disable_roce (struct mlx5_ib_dev * dev )
2703
2737
{
2704
2738
mlx5_nic_vport_disable_roce (dev -> mdev );
2705
- unregister_netdevice_notifier (& dev -> roce .nb );
2706
2739
}
2707
2740
2708
2741
static void mlx5_ib_dealloc_q_counters (struct mlx5_ib_dev * dev )
@@ -3051,8 +3084,10 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
3051
3084
destroy_dev_resources (& dev -> devr );
3052
3085
3053
3086
err_disable_roce :
3054
- if (ll == IB_LINK_LAYER_ETHERNET )
3087
+ if (ll == IB_LINK_LAYER_ETHERNET ) {
3055
3088
mlx5_disable_roce (dev );
3089
+ mlx5_remove_roce_notifier (dev );
3090
+ }
3056
3091
3057
3092
err_free_port :
3058
3093
kfree (dev -> port );
@@ -3068,6 +3103,7 @@ static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context)
3068
3103
struct mlx5_ib_dev * dev = context ;
3069
3104
enum rdma_link_layer ll = mlx5_ib_port_link_layer (& dev -> ib_dev , 1 );
3070
3105
3106
+ mlx5_remove_roce_notifier (dev );
3071
3107
ib_unregister_device (& dev -> ib_dev );
3072
3108
mlx5_ib_dealloc_q_counters (dev );
3073
3109
destroy_umrc_res (dev );
0 commit comments