@@ -4905,6 +4905,119 @@ def interface(ctx, namespace):
49054905 config_db = ConfigDBConnector (use_unix_socket_path = True , namespace = str (namespace ))
49064906 config_db .connect ()
49074907 ctx .obj = {'config_db' : config_db , 'namespace' : str (namespace )}
4908+
4909+
4910+ @config .group (cls = clicommon .AliasedGroup , name = 'switch-fast-linkup' , context_settings = CONTEXT_SETTINGS )
4911+ @click .pass_context
4912+ def switch_fast_linkup_group (ctx ):
4913+ """Configure fast link-up global configuration parameters"""
4914+ pass
4915+
4916+
4917+ # 'global' subcommand
4918+ @switch_fast_linkup_group .command (name = 'global' )
4919+ @click .option ('--polling-time' , type = int , required = False , help = 'Polling time (sec)' )
4920+ @click .option ('--guard-time' , type = int , required = False , help = 'Guard time (sec)' )
4921+ @click .option ('--ber' , '--ber-threshold' , type = int , required = False , help = 'BER threshold exponent (e.g., 12 for 1e-12)' )
4922+ @clicommon .pass_db
4923+ def switch_fast_linkup_global_cmd (db , polling_time , guard_time , ber ):
4924+ """Configure global fast link-up feature parameters"""
4925+ if polling_time is None and guard_time is None and ber is None :
4926+ raise click .UsageError ('Failed to configure fast link-up global: no options are provided' )
4927+ # Read capability and ranges from STATE_DB for validation
4928+ state = db .db
4929+ cap_tbl = state .STATE_DB
4930+ entry = state .get_all (cap_tbl , 'SWITCH_CAPABILITY|switch' ) or {}
4931+ if entry .get ('FAST_LINKUP_CAPABLE' , 'false' ) != 'true' :
4932+ raise click .ClickException ('Fast link-up is not supported on this platform' )
4933+
4934+ def _parse_range (s ):
4935+ try :
4936+ parts = (s or '' ).split (',' )
4937+ return int (parts [0 ]), int (parts [1 ])
4938+ except Exception :
4939+ return None
4940+ poll_range = _parse_range (entry .get ('FAST_LINKUP_POLLING_TIMER_RANGE' ))
4941+ guard_range = _parse_range (entry .get ('FAST_LINKUP_GUARD_TIMER_RANGE' ))
4942+
4943+ # Load existing configuration to preserve unspecified values
4944+ existing = db .cfgdb .get_entry ('SWITCH_FAST_LINKUP' , 'GLOBAL' ) or {}
4945+
4946+ def to_int (val ):
4947+ try :
4948+ return int (val )
4949+ except Exception :
4950+ return None
4951+
4952+ polling_time = polling_time if polling_time is not None else to_int (existing .get ('polling_time' ))
4953+ guard_time = guard_time if guard_time is not None else to_int (existing .get ('guard_time' ))
4954+ ber = ber if ber is not None else to_int (existing .get ('ber_threshold' ))
4955+
4956+ data = {}
4957+ if polling_time is not None :
4958+ if poll_range and not (poll_range [0 ] <= int (polling_time ) <= poll_range [1 ]):
4959+ raise click .ClickException ('polling_time {} out of supported range [{}, {}]' .format (
4960+ polling_time , poll_range [0 ], poll_range [1 ]))
4961+ data ['polling_time' ] = str (polling_time )
4962+ if guard_time is not None :
4963+ if guard_range and not (guard_range [0 ] <= int (guard_time ) <= guard_range [1 ]):
4964+ raise click .ClickException ('guard_time {} out of supported range [{}, {}]' .format (
4965+ guard_time , guard_range [0 ], guard_range [1 ]))
4966+ data ['guard_time' ] = str (guard_time )
4967+ if ber is not None :
4968+ if ber < 1 or ber > 255 :
4969+ raise click .ClickException ('ber_threshold {} out of supported range [1, 255]' .format (ber ))
4970+ data ['ber_threshold' ] = str (ber )
4971+ try :
4972+ db .cfgdb .set_entry ('SWITCH_FAST_LINKUP' , 'GLOBAL' , data )
4973+
4974+ log .log_notice ('Configured fast link-up global: {}' .format (data ))
4975+ except Exception as e :
4976+ log .log_error ('Failed to configure fast link-up global: {}' .format (str (e )))
4977+ raise SystemExit (1 )
4978+
4979+
4980+ # 'fast-linkup' subcommand
4981+ @interface .command ('fast-linkup' )
4982+ @click .argument ('interface_name' , metavar = '<interface_name>' , required = True )
4983+ @click .argument (
4984+ 'mode' ,
4985+ metavar = '<enabled|disabled|true|false|on|off>' ,
4986+ required = True ,
4987+ type = click .Choice (['enabled' , 'disabled' , 'true' , 'false' , 'on' , 'off' ])
4988+ )
4989+ @click .option ('-v' , '--verbose' , is_flag = True , help = 'Enable verbose output' )
4990+ @click .pass_context
4991+ def fast_linkup (ctx , interface_name , mode , verbose ):
4992+ """Enable/disable fast link-up on an interface"""
4993+ config_db = ctx .obj ['config_db' ]
4994+
4995+ if clicommon .get_interface_naming_mode () == 'alias' :
4996+ interface_name = interface_alias_to_name (config_db , interface_name )
4997+ if interface_name is None :
4998+ ctx .fail ("'interface_name' is None!" )
4999+ if not interface_name_is_valid (config_db , interface_name ):
5000+ ctx .fail ('Error: Interface name is invalid. Please enter a valid interface name' )
5001+
5002+ # Read capability from STATE_DB for validation
5003+ if ctx .obj ['namespace' ] is DEFAULT_NAMESPACE :
5004+ state_db = SonicV2Connector (use_unix_socket_path = True )
5005+ else :
5006+ state_db = SonicV2Connector (use_unix_socket_path = True , namespace = ctx .obj ['namespace' ])
5007+ state_db .connect (state_db .STATE_DB , False )
5008+ fast_linkup_capable = state_db .get (state_db .STATE_DB , 'SWITCH_CAPABILITY|switch' , 'FAST_LINKUP_CAPABLE' )
5009+ if fast_linkup_capable != 'true' :
5010+ raise click .ClickException ('Fast link-up is not supported on this platform' )
5011+
5012+ log .log_info ("'interface fast-linkup {} {}' executing..." .format (interface_name , mode ))
5013+ if ctx .obj ['namespace' ] is DEFAULT_NAMESPACE :
5014+ command = ['portconfig' , '-p' , str (interface_name ), '-fl' , str (mode )]
5015+ else :
5016+ command = ['portconfig' , '-p' , str (interface_name ), '-fl' , str (mode ), '-n' , str (ctx .obj ['namespace' ])]
5017+
5018+ if verbose :
5019+ command += ['-vv' ]
5020+ clicommon .run_command (command , display_cmd = verbose )
49085021#
49095022# 'startup' subcommand
49105023#
0 commit comments