16
16
CONFIG_SUCCESSFUL = 100
17
17
CONFIG_FAIL = 1
18
18
19
+ VENDOR_NAME = "Credo"
20
+ VENDOR_MODEL = "CAC125321P2PA0MS"
19
21
20
22
# Helper functions
21
23
@@ -146,7 +148,7 @@ def mode(state, port, json_output):
146
148
147
149
if per_npu_statedb [asic_index ] is not None :
148
150
y_cable_asic_table_keys = port_table_keys [asic_index ]
149
- logical_key = "MUX_CABLE_TABLE" + "|" + port
151
+ logical_key = "MUX_CABLE_TABLE|{}" . format ( port )
150
152
if logical_key in y_cable_asic_table_keys :
151
153
port_status_dict = {}
152
154
lookup_statedb_and_update_configdb (
@@ -188,11 +190,13 @@ def mode(state, port, json_output):
188
190
189
191
sys .exit (CONFIG_SUCCESSFUL )
190
192
193
+
191
194
@muxcable .group (cls = clicommon .AbbreviationGroup )
192
195
def prbs ():
193
196
"""Enable/disable PRBS mode on a port"""
194
197
pass
195
198
199
+
196
200
@prbs .command ()
197
201
@click .argument ('port' , required = True , default = None , type = click .INT )
198
202
@click .argument ('target' , required = True , default = None , type = click .INT )
@@ -209,6 +213,7 @@ def enable(port, target, mode_value, lane_map):
209
213
click .echo ("PRBS config sucessful" )
210
214
sys .exit (CONFIG_SUCCESSFUL )
211
215
216
+
212
217
@prbs .command ()
213
218
@click .argument ('port' , required = True , default = None , type = click .INT )
214
219
@click .argument ('target' , required = True , default = None , type = click .INT )
@@ -223,6 +228,7 @@ def disable(port, target):
223
228
click .echo ("PRBS disable sucessful" )
224
229
sys .exit (CONFIG_SUCCESSFUL )
225
230
231
+
226
232
@muxcable .group (cls = clicommon .AbbreviationGroup )
227
233
def loopback ():
228
234
"""Enable/disable loopback mode on a port"""
@@ -244,6 +250,7 @@ def enable(port, target, lane_map):
244
250
click .echo ("loopback config sucessful" )
245
251
sys .exit (CONFIG_SUCCESSFUL )
246
252
253
+
247
254
@loopback .command ()
248
255
@click .argument ('port' , required = True , default = None , type = click .INT )
249
256
@click .argument ('target' , required = True , default = None , type = click .INT )
@@ -257,3 +264,208 @@ def disable(port, target):
257
264
sys .exit (CONFIG_FAIL )
258
265
click .echo ("loopback disable sucessful" )
259
266
sys .exit (CONFIG_SUCCESSFUL )
267
+
268
+
269
+ @muxcable .group (cls = clicommon .AbbreviationGroup )
270
+ def hwmode ():
271
+ """Configure muxcable hardware directly"""
272
+ pass
273
+
274
+
275
+ @hwmode .command ()
276
+ @click .argument ('state' , metavar = '<operation_status>' , required = True , type = click .Choice (["active" , "standby" ]))
277
+ @click .argument ('port' , metavar = '<port_name>' , required = True , default = None )
278
+ def state (state , port ):
279
+ """Configure the muxcable mux state {active/standby}"""
280
+
281
+ per_npu_statedb = {}
282
+ transceiver_table_keys = {}
283
+ transceiver_dict = {}
284
+
285
+ # Getting all front asic namespace and correspding config and state DB connector
286
+
287
+ namespaces = multi_asic .get_front_end_namespaces ()
288
+ for namespace in namespaces :
289
+ asic_id = multi_asic .get_asic_index_from_namespace (namespace )
290
+ per_npu_statedb [asic_id ] = SonicV2Connector (use_unix_socket_path = False , namespace = namespace )
291
+ per_npu_statedb [asic_id ].connect (per_npu_statedb [asic_id ].STATE_DB )
292
+
293
+ transceiver_table_keys [asic_id ] = per_npu_statedb [asic_id ].keys (
294
+ per_npu_statedb [asic_id ].STATE_DB , 'TRANSCEIVER_INFO|*' )
295
+
296
+ if port is not None and port != "all" :
297
+ click .confirm (('Muxcable at port {} will be changed to {} state. Continue?' .format (port , state )), abort = True )
298
+ logical_port_list = platform_sfputil_helper .get_logical_list ()
299
+ if port not in logical_port_list :
300
+ click .echo ("ERR: This is not a valid port, valid ports ({})" .format (", " .join (logical_port_list )))
301
+ sys .exit (CONFIG_FAIL )
302
+
303
+ asic_index = None
304
+ if platform_sfputil is not None :
305
+ asic_index = platform_sfputil_helper .get_asic_id_for_logical_port (port )
306
+ if asic_index is None :
307
+ # TODO this import is only for unit test purposes, and should be removed once sonic_platform_base
308
+ # is fully mocked
309
+ import sonic_platform_base .sonic_sfp .sfputilhelper
310
+ asic_index = sonic_platform_base .sonic_sfp .sfputilhelper .SfpUtilHelper ().get_asic_id_for_logical_port (port )
311
+ if asic_index is None :
312
+ click .echo ("Got invalid asic index for port {}, cant retreive mux status" .format (port ))
313
+ sys .exit (CONFIG_FAIL )
314
+
315
+ if platform_sfputil is not None :
316
+ physical_port_list = platform_sfputil_helper .logical_port_name_to_physical_port_list (port )
317
+
318
+ if not isinstance (physical_port_list , list ):
319
+ click .echo (("ERR: Unable to locate physical port information for {}" .format (port )))
320
+ sys .exit (CONFIG_FAIL )
321
+ if len (physical_port_list ) != 1 :
322
+ click .echo ("ERR: Found multiple physical ports ({}) associated with {}" .format (
323
+ ", " .join (physical_port_list ), port ))
324
+ sys .exit (CONFIG_FAIL )
325
+
326
+ transceiver_dict [asic_index ] = per_npu_statedb [asic_index ].get_all (
327
+ per_npu_statedb [asic_index ].STATE_DB , 'TRANSCEIVER_INFO|{}' .format (port ))
328
+
329
+ vendor_value = get_value_for_key_in_dict (transceiver_dict [asic_index ], port , "manufacturer" , "TRANSCEIVER_INFO" )
330
+ model_value = get_value_for_key_in_dict (transceiver_dict [asic_index ], port , "model" , "TRANSCEIVER_INFO" )
331
+
332
+ """ This check is required for checking whether or not this port is connected to a Y cable
333
+ or not. The check gives a way to differentiate between non Y cable ports and Y cable ports.
334
+ TODO: this should be removed once their is support for multiple vendors on Y cable"""
335
+
336
+ if vendor_value != VENDOR_NAME or model_value != VENDOR_MODEL :
337
+ click .echo ("ERR: Got invalid vendor value and model for port {}" .format (port ))
338
+ sys .exit (CONFIG_FAIL )
339
+
340
+ physical_port = physical_port_list [0 ]
341
+
342
+ logical_port_list_for_physical_port = platform_sfputil_helper .get_physical_to_logical ()
343
+
344
+ logical_port_list_per_port = logical_port_list_for_physical_port .get (physical_port , None )
345
+
346
+ """ This check is required for checking whether or not this logical port is the one which is
347
+ actually mapped to physical port and by convention it is always the first port.
348
+ TODO: this should be removed with more logic to check which logical port maps to actual physical port
349
+ being used"""
350
+
351
+ if port != logical_port_list_per_port [0 ]:
352
+ click .echo ("ERR: This logical Port {} is not on a muxcable" .format (port ))
353
+ sys .exit (CONFIG_FAIL )
354
+
355
+ import sonic_y_cable .y_cable
356
+ read_side = sonic_y_cable .y_cable .check_read_side (physical_port )
357
+ if read_side == False or read_side == - 1 :
358
+ click .echo (("ERR: Unable to get read_side for the cable port {}" .format (port )))
359
+ sys .exit (CONFIG_FAIL )
360
+
361
+ mux_direction = sonic_y_cable .y_cable .check_mux_direction (physical_port )
362
+ if mux_direction == False or mux_direction == - 1 :
363
+ click .echo (("ERR: Unable to get mux direction for the cable port {}" .format (port )))
364
+ sys .exit (CONFIG_FAIL )
365
+
366
+ if int (read_side ) == 1 :
367
+ if state == "active" :
368
+ res = sonic_y_cable .y_cable .toggle_mux_to_torA (physical_port )
369
+ elif state == "standby" :
370
+ res = sonic_y_cable .y_cable .toggle_mux_to_torB (physical_port )
371
+ click .echo ("Success in toggling port {} to {}" .format (port , state ))
372
+ elif int (read_side ) == 2 :
373
+ if state == "active" :
374
+ res = sonic_y_cable .y_cable .toggle_mux_to_torB (physical_port )
375
+ elif state == "standby" :
376
+ res = sonic_y_cable .y_cable .toggle_mux_to_torA (physical_port )
377
+ click .echo ("Success in toggling port {} to {}" .format (port , state ))
378
+
379
+ if res == False :
380
+ click .echo ("ERR: Unable to toggle port {} to {}" .format (port , state ))
381
+ sys .exit (CONFIG_FAIL )
382
+
383
+ elif port == "all" and port is not None :
384
+
385
+ click .confirm (('Muxcables at all ports will be changed to {} state. Continue?' .format (state )), abort = True )
386
+ logical_port_list = platform_sfputil_helper .get_logical_list ()
387
+
388
+ rc = True
389
+ for port in logical_port_list :
390
+ if platform_sfputil is not None :
391
+ physical_port_list = platform_sfputil_helper .logical_port_name_to_physical_port_list (port )
392
+
393
+ asic_index = None
394
+ if platform_sfputil is not None :
395
+ asic_index = platform_sfputil_helper .get_asic_id_for_logical_port (port )
396
+ if asic_index is None :
397
+ # TODO this import is only for unit test purposes, and should be removed once sonic_platform_base
398
+ # is fully mocked
399
+ import sonic_platform_base .sonic_sfp .sfputilhelper
400
+ asic_index = sonic_platform_base .sonic_sfp .sfputilhelper .SfpUtilHelper ().get_asic_id_for_logical_port (port )
401
+ if asic_index is None :
402
+ click .echo ("Got invalid asic index for port {}, cant retreive mux status" .format (port ))
403
+
404
+ if not isinstance (physical_port_list , list ):
405
+ click .echo (("ERR: Unable to locate physical port information for {}" .format (port )))
406
+ continue
407
+
408
+ if len (physical_port_list ) != 1 :
409
+ click .echo ("ERR: Found multiple physical ports ({}) associated with {}" .format (
410
+ ", " .join (physical_port_list ), port ))
411
+ continue
412
+
413
+ transceiver_dict [asic_index ] = per_npu_statedb [asic_index ].get_all (
414
+ per_npu_statedb [asic_index ].STATE_DB , 'TRANSCEIVER_INFO|{}' .format (port ))
415
+ vendor_value = transceiver_dict [asic_index ].get ("manufacturer" , None )
416
+ model_value = transceiver_dict [asic_index ].get ("model" , None )
417
+
418
+ """ This check is required for checking whether or not this port is connected to a Y cable
419
+ or not. The check gives a way to differentiate between non Y cable ports and Y cable ports.
420
+ TODO: this should be removed once their is support for multiple vendors on Y cable"""
421
+
422
+ if vendor_value != VENDOR_NAME or model_value != VENDOR_MODEL :
423
+ continue
424
+
425
+ physical_port = physical_port_list [0 ]
426
+
427
+ logical_port_list_for_physical_port = platform_sfputil_helper .get_physical_to_logical ()
428
+
429
+ logical_port_list_per_port = logical_port_list_for_physical_port .get (physical_port , None )
430
+
431
+ """ This check is required for checking whether or not this logical port is the one which is
432
+ actually mapped to physical port and by convention it is always the first port.
433
+ TODO: this should be removed with more logic to check which logical port maps to actual physical port
434
+ being used"""
435
+
436
+ if port != logical_port_list_per_port [0 ]:
437
+ continue
438
+
439
+ import sonic_y_cable .y_cable
440
+ read_side = sonic_y_cable .y_cable .check_read_side (physical_port )
441
+ if read_side == False or read_side == - 1 :
442
+ click .echo (("ERR: Unable to get read side for the cable port {}" .format (port )))
443
+ rc = False
444
+ continue
445
+
446
+ mux_direction = sonic_y_cable .y_cable .check_mux_direction (physical_port )
447
+ if mux_direction == False or mux_direction == - 1 :
448
+ click .echo (("ERR: Unable to get mux direction for the cable port {}" .format (port )))
449
+ rc = False
450
+ continue
451
+
452
+ if int (read_side ) == 1 :
453
+ if state == "active" :
454
+ res = sonic_y_cable .y_cable .toggle_mux_to_torA (physical_port )
455
+ elif state == "standby" :
456
+ res = sonic_y_cable .y_cable .toggle_mux_to_torB (physical_port )
457
+ click .echo ("Success in toggling port {} to {}" .format (port , state ))
458
+ elif int (read_side ) == 2 :
459
+ if state == "active" :
460
+ res = sonic_y_cable .y_cable .toggle_mux_to_torB (physical_port )
461
+ elif state == "standby" :
462
+ res = sonic_y_cable .y_cable .toggle_mux_to_torA (physical_port )
463
+ click .echo ("Success in toggling port {} to {}" .format (port , state ))
464
+
465
+ if res == False :
466
+ rc = False
467
+ click .echo ("ERR: Unable to toggle port {} to {}" .format (port , state ))
468
+
469
+ if rc == False :
470
+ click .echo ("ERR: Unable to toggle one or more ports to {}" .format (state ))
471
+ sys .exit (CONFIG_FAIL )
0 commit comments