@@ -200,6 +200,196 @@ static void mlx4_slave_event(struct mlx4_dev *dev, int slave,
200
200
slave_event (dev , slave , eqe );
201
201
}
202
202
203
+ int mlx4_gen_pkey_eqe (struct mlx4_dev * dev , int slave , u8 port )
204
+ {
205
+ struct mlx4_eqe eqe ;
206
+
207
+ struct mlx4_priv * priv = mlx4_priv (dev );
208
+ struct mlx4_slave_state * s_slave = & priv -> mfunc .master .slave_state [slave ];
209
+
210
+ if (!s_slave -> active )
211
+ return 0 ;
212
+
213
+ memset (& eqe , 0 , sizeof eqe );
214
+
215
+ eqe .type = MLX4_EVENT_TYPE_PORT_MNG_CHG_EVENT ;
216
+ eqe .subtype = MLX4_DEV_PMC_SUBTYPE_PKEY_TABLE ;
217
+ eqe .event .port_mgmt_change .port = port ;
218
+
219
+ return mlx4_GEN_EQE (dev , slave , & eqe );
220
+ }
221
+ EXPORT_SYMBOL (mlx4_gen_pkey_eqe );
222
+
223
+ int mlx4_gen_guid_change_eqe (struct mlx4_dev * dev , int slave , u8 port )
224
+ {
225
+ struct mlx4_eqe eqe ;
226
+
227
+ /*don't send if we don't have the that slave */
228
+ if (dev -> num_vfs < slave )
229
+ return 0 ;
230
+ memset (& eqe , 0 , sizeof eqe );
231
+
232
+ eqe .type = MLX4_EVENT_TYPE_PORT_MNG_CHG_EVENT ;
233
+ eqe .subtype = MLX4_DEV_PMC_SUBTYPE_GUID_INFO ;
234
+ eqe .event .port_mgmt_change .port = port ;
235
+
236
+ return mlx4_GEN_EQE (dev , slave , & eqe );
237
+ }
238
+ EXPORT_SYMBOL (mlx4_gen_guid_change_eqe );
239
+
240
+ int mlx4_gen_port_state_change_eqe (struct mlx4_dev * dev , int slave , u8 port ,
241
+ u8 port_subtype_change )
242
+ {
243
+ struct mlx4_eqe eqe ;
244
+
245
+ /*don't send if we don't have the that slave */
246
+ if (dev -> num_vfs < slave )
247
+ return 0 ;
248
+ memset (& eqe , 0 , sizeof eqe );
249
+
250
+ eqe .type = MLX4_EVENT_TYPE_PORT_CHANGE ;
251
+ eqe .subtype = port_subtype_change ;
252
+ eqe .event .port_change .port = cpu_to_be32 (port << 28 );
253
+
254
+ mlx4_dbg (dev , "%s: sending: %d to slave: %d on port: %d\n" , __func__ ,
255
+ port_subtype_change , slave , port );
256
+ return mlx4_GEN_EQE (dev , slave , & eqe );
257
+ }
258
+ EXPORT_SYMBOL (mlx4_gen_port_state_change_eqe );
259
+
260
+ enum slave_port_state mlx4_get_slave_port_state (struct mlx4_dev * dev , int slave , u8 port )
261
+ {
262
+ struct mlx4_priv * priv = mlx4_priv (dev );
263
+ struct mlx4_slave_state * s_state = priv -> mfunc .master .slave_state ;
264
+ if (slave >= dev -> num_slaves || port > MLX4_MAX_PORTS ) {
265
+ pr_err ("%s: Error: asking for slave:%d, port:%d\n" ,
266
+ __func__ , slave , port );
267
+ return SLAVE_PORT_DOWN ;
268
+ }
269
+ return s_state [slave ].port_state [port ];
270
+ }
271
+ EXPORT_SYMBOL (mlx4_get_slave_port_state );
272
+
273
+ static int mlx4_set_slave_port_state (struct mlx4_dev * dev , int slave , u8 port ,
274
+ enum slave_port_state state )
275
+ {
276
+ struct mlx4_priv * priv = mlx4_priv (dev );
277
+ struct mlx4_slave_state * s_state = priv -> mfunc .master .slave_state ;
278
+
279
+ if (slave >= dev -> num_slaves || port > MLX4_MAX_PORTS || port == 0 ) {
280
+ pr_err ("%s: Error: asking for slave:%d, port:%d\n" ,
281
+ __func__ , slave , port );
282
+ return -1 ;
283
+ }
284
+ s_state [slave ].port_state [port ] = state ;
285
+
286
+ return 0 ;
287
+ }
288
+
289
+ static void set_all_slave_state (struct mlx4_dev * dev , u8 port , int event )
290
+ {
291
+ int i ;
292
+ enum slave_port_gen_event gen_event ;
293
+
294
+ for (i = 0 ; i < dev -> num_slaves ; i ++ )
295
+ set_and_calc_slave_port_state (dev , i , port , event , & gen_event );
296
+ }
297
+ /**************************************************************************
298
+ The function get as input the new event to that port,
299
+ and according to the prev state change the slave's port state.
300
+ The events are:
301
+ MLX4_PORT_STATE_DEV_EVENT_PORT_DOWN,
302
+ MLX4_PORT_STATE_DEV_EVENT_PORT_UP
303
+ MLX4_PORT_STATE_IB_EVENT_GID_VALID
304
+ MLX4_PORT_STATE_IB_EVENT_GID_INVALID
305
+ ***************************************************************************/
306
+ int set_and_calc_slave_port_state (struct mlx4_dev * dev , int slave ,
307
+ u8 port , int event ,
308
+ enum slave_port_gen_event * gen_event )
309
+ {
310
+ struct mlx4_priv * priv = mlx4_priv (dev );
311
+ struct mlx4_slave_state * ctx = NULL ;
312
+ unsigned long flags ;
313
+ int ret = -1 ;
314
+ enum slave_port_state cur_state =
315
+ mlx4_get_slave_port_state (dev , slave , port );
316
+
317
+ * gen_event = SLAVE_PORT_GEN_EVENT_NONE ;
318
+
319
+ if (slave >= dev -> num_slaves || port > MLX4_MAX_PORTS || port == 0 ) {
320
+ pr_err ("%s: Error: asking for slave:%d, port:%d\n" ,
321
+ __func__ , slave , port );
322
+ return ret ;
323
+ }
324
+
325
+ ctx = & priv -> mfunc .master .slave_state [slave ];
326
+ spin_lock_irqsave (& ctx -> lock , flags );
327
+
328
+ mlx4_dbg (dev , "%s: slave: %d, current state: %d new event :%d\n" ,
329
+ __func__ , slave , cur_state , event );
330
+
331
+ switch (cur_state ) {
332
+ case SLAVE_PORT_DOWN :
333
+ if (MLX4_PORT_STATE_DEV_EVENT_PORT_UP == event )
334
+ mlx4_set_slave_port_state (dev , slave , port ,
335
+ SLAVE_PENDING_UP );
336
+ break ;
337
+ case SLAVE_PENDING_UP :
338
+ if (MLX4_PORT_STATE_DEV_EVENT_PORT_DOWN == event )
339
+ mlx4_set_slave_port_state (dev , slave , port ,
340
+ SLAVE_PORT_DOWN );
341
+ else if (MLX4_PORT_STATE_IB_PORT_STATE_EVENT_GID_VALID == event ) {
342
+ mlx4_set_slave_port_state (dev , slave , port ,
343
+ SLAVE_PORT_UP );
344
+ * gen_event = SLAVE_PORT_GEN_EVENT_UP ;
345
+ }
346
+ break ;
347
+ case SLAVE_PORT_UP :
348
+ if (MLX4_PORT_STATE_DEV_EVENT_PORT_DOWN == event ) {
349
+ mlx4_set_slave_port_state (dev , slave , port ,
350
+ SLAVE_PORT_DOWN );
351
+ * gen_event = SLAVE_PORT_GEN_EVENT_DOWN ;
352
+ } else if (MLX4_PORT_STATE_IB_EVENT_GID_INVALID ==
353
+ event ) {
354
+ mlx4_set_slave_port_state (dev , slave , port ,
355
+ SLAVE_PENDING_UP );
356
+ * gen_event = SLAVE_PORT_GEN_EVENT_DOWN ;
357
+ }
358
+ break ;
359
+ default :
360
+ pr_err ("%s: BUG!!! UNKNOWN state: "
361
+ "slave:%d, port:%d\n" , __func__ , slave , port );
362
+ goto out ;
363
+ }
364
+ ret = mlx4_get_slave_port_state (dev , slave , port );
365
+ mlx4_dbg (dev , "%s: slave: %d, current state: %d new event"
366
+ " :%d gen_event: %d\n" ,
367
+ __func__ , slave , cur_state , event , * gen_event );
368
+
369
+ out :
370
+ spin_unlock_irqrestore (& ctx -> lock , flags );
371
+ return ret ;
372
+ }
373
+
374
+ EXPORT_SYMBOL (set_and_calc_slave_port_state );
375
+
376
+ int mlx4_gen_slaves_port_mgt_ev (struct mlx4_dev * dev , u8 port , int attr )
377
+ {
378
+ struct mlx4_eqe eqe ;
379
+
380
+ memset (& eqe , 0 , sizeof eqe );
381
+
382
+ eqe .type = MLX4_EVENT_TYPE_PORT_MNG_CHG_EVENT ;
383
+ eqe .subtype = MLX4_DEV_PMC_SUBTYPE_PORT_INFO ;
384
+ eqe .event .port_mgmt_change .port = port ;
385
+ eqe .event .port_mgmt_change .params .port_info .changed_attr =
386
+ cpu_to_be32 ((u32 ) attr );
387
+
388
+ slave_event (dev , ALL_SLAVES , & eqe );
389
+ return 0 ;
390
+ }
391
+ EXPORT_SYMBOL (mlx4_gen_slaves_port_mgt_ev );
392
+
203
393
void mlx4_master_handle_slave_flr (struct work_struct * work )
204
394
{
205
395
struct mlx4_mfunc_master_ctx * master =
@@ -251,6 +441,7 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
251
441
u32 flr_slave ;
252
442
u8 update_slave_state ;
253
443
int i ;
444
+ enum slave_port_gen_event gen_event ;
254
445
255
446
while ((eqe = next_eqe_sw (eq ))) {
256
447
/*
@@ -347,35 +538,49 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
347
538
case MLX4_EVENT_TYPE_PORT_CHANGE :
348
539
port = be32_to_cpu (eqe -> event .port_change .port ) >> 28 ;
349
540
if (eqe -> subtype == MLX4_PORT_CHANGE_SUBTYPE_DOWN ) {
350
- mlx4_dispatch_event (dev ,
351
- MLX4_DEV_EVENT_PORT_DOWN ,
541
+ mlx4_dispatch_event (dev , MLX4_DEV_EVENT_PORT_DOWN ,
352
542
port );
353
543
mlx4_priv (dev )-> sense .do_sense_port [port ] = 1 ;
354
- if (mlx4_is_master (dev ))
355
- /*change the state of all slave's port
356
- * to down:*/
357
- for (i = 0 ; i < dev -> num_slaves ; i ++ ) {
358
- mlx4_dbg (dev , "%s: Sending "
359
- "MLX4_PORT_CHANGE_SUBTYPE_DOWN"
544
+ if (!mlx4_is_master (dev ))
545
+ break ;
546
+ for (i = 0 ; i < dev -> num_slaves ; i ++ ) {
547
+ if (dev -> caps .port_type [port ] == MLX4_PORT_TYPE_ETH ) {
548
+ if (i == mlx4_master_func_num (dev ))
549
+ continue ;
550
+ mlx4_dbg (dev , "%s: Sending MLX4_PORT_CHANGE_SUBTYPE_DOWN"
360
551
" to slave: %d, port:%d\n" ,
361
552
__func__ , i , port );
362
- if (i == dev -> caps .function )
363
- continue ;
364
553
mlx4_slave_event (dev , i , eqe );
554
+ } else { /* IB port */
555
+ set_and_calc_slave_port_state (dev , i , port ,
556
+ MLX4_PORT_STATE_DEV_EVENT_PORT_DOWN ,
557
+ & gen_event );
558
+ /*we can be in pending state, then do not send port_down event*/
559
+ if (SLAVE_PORT_GEN_EVENT_DOWN == gen_event ) {
560
+ if (i == mlx4_master_func_num (dev ))
561
+ continue ;
562
+ mlx4_slave_event (dev , i , eqe );
563
+ }
365
564
}
565
+ }
366
566
} else {
367
- mlx4_dispatch_event (dev ,
368
- MLX4_DEV_EVENT_PORT_UP ,
369
- port );
567
+ mlx4_dispatch_event (dev , MLX4_DEV_EVENT_PORT_UP , port );
568
+
370
569
mlx4_priv (dev )-> sense .do_sense_port [port ] = 0 ;
371
570
372
- if (mlx4_is_master (dev )) {
571
+ if (!mlx4_is_master (dev ))
572
+ break ;
573
+ if (dev -> caps .port_type [port ] == MLX4_PORT_TYPE_ETH )
373
574
for (i = 0 ; i < dev -> num_slaves ; i ++ ) {
374
- if (i == dev -> caps . function )
575
+ if (i == mlx4_master_func_num ( dev ) )
375
576
continue ;
376
577
mlx4_slave_event (dev , i , eqe );
377
578
}
378
- }
579
+ else /* IB port */
580
+ /* port-up event will be sent to a slave when the
581
+ * slave's alias-guid is set. This is done in alias_GUID.c
582
+ */
583
+ set_all_slave_state (dev , port , MLX4_DEV_EVENT_PORT_UP );
379
584
}
380
585
break ;
381
586
0 commit comments