@@ -999,6 +999,11 @@ def on_port_update_event(self, port_change_event):
999999 # We dont have better way to check if 'admin_status' is from APPL_DB or STATE_DB so this
10001000 # check is put temporarily to listen only to APPL_DB's admin_status and ignore that of STATE_DB
10011001 self .port_dict [lport ]['admin_status' ] = port_change_event .port_dict ['admin_status' ]
1002+ if 'laser_freq' in port_change_event .port_dict :
1003+ self .port_dict [lport ]['laser_freq' ] = int (port_change_event .port_dict ['laser_freq' ])
1004+ if 'tx_power' in port_change_event .port_dict :
1005+ self .port_dict [lport ]['tx_power' ] = float (port_change_event .port_dict ['tx_power' ])
1006+
10021007 self .force_cmis_reinit (lport , 0 )
10031008 else :
10041009 self .port_dict [lport ]['cmis_state' ] = self .CMIS_STATE_REMOVED
@@ -1121,7 +1126,6 @@ def is_cmis_application_update_required(self, api, channel, speed):
11211126 skip = False
11221127 break
11231128 return (not skip )
1124-
11251129 return True
11261130
11271131 def force_cmis_reinit (self , lport , retries = 0 ):
@@ -1203,6 +1207,32 @@ def check_datapath_state(self, api, channel, states):
12031207
12041208 return done
12051209
1210+ def get_configured_laser_freq_from_db (self , lport ):
1211+ """
1212+ Return the Tx power configured by user in CONFIG_DB's PORT table
1213+ """
1214+ freq = 0
1215+ asic_index = self .port_mapping .get_asic_id_for_logical_port (lport )
1216+ port_tbl = self .xcvr_table_helper .get_cfg_port_tbl (asic_index )
1217+
1218+ found , port_info = port_tbl .get (lport )
1219+ if found and 'laser_freq' in dict (port_info ):
1220+ freq = dict (port_info )['laser_freq' ]
1221+ return int (freq )
1222+
1223+ def get_configured_tx_power_from_db (self , lport ):
1224+ """
1225+ Return the Tx power configured by user in CONFIG_DB's PORT table
1226+ """
1227+ power = 0
1228+ asic_index = self .port_mapping .get_asic_id_for_logical_port (lport )
1229+ port_tbl = self .xcvr_table_helper .get_cfg_port_tbl (asic_index )
1230+
1231+ found , port_info = port_tbl .get (lport )
1232+ if found and 'tx_power' in dict (port_info ):
1233+ power = dict (port_info )['tx_power' ]
1234+ return float (power )
1235+
12061236 def get_host_tx_status (self , lport ):
12071237 host_tx_ready = 'false'
12081238
@@ -1226,11 +1256,31 @@ def get_port_admin_status(self, lport):
12261256 admin_status = dict (port_info )['admin_status' ]
12271257 return admin_status
12281258
1259+ def configure_tx_output_power (self , api , lport , tx_power ):
1260+ min_p , max_p = api .get_supported_power_config ()
1261+ if tx_power < min_p :
1262+ self .log_error ("{} configured tx power {} < minimum power {} supported" .format (lport , tx_power , min_p ))
1263+ if tx_power > max_p :
1264+ self .log_error ("{} configured tx power {} > maximum power {} supported" .format (lport , tx_power , max_p ))
1265+ return api .set_tx_power (tx_power )
1266+
1267+ def configure_laser_frequency (self , api , lport , freq ):
1268+ _ , _ , _ , lowf , highf = api .get_supported_freq_config ()
1269+ if freq < lowf :
1270+ self .log_error ("{} configured freq:{} GHz is lower than the supported freq:{} GHz" .format (lport , freq , lowf ))
1271+ if freq > highf :
1272+ self .log_error ("{} configured freq:{} GHz is higher than the supported freq:{} GHz" .format (lport , freq , highf ))
1273+ chan = int (round ((freq - 193100 )/ 25 ))
1274+ if chan % 3 != 0 :
1275+ self .log_error ("{} configured freq:{} GHz is NOT in 75GHz grid" .format (lport , freq ))
1276+ if api .get_tuning_in_progress ():
1277+ self .log_error ("{} Tuning in progress, channel selection may fail!" .format (lport ))
1278+ return api .set_laser_freq (freq )
1279+
12291280 def task_worker (self ):
12301281 self .xcvr_table_helper = XcvrTableHelper (self .namespaces )
12311282
12321283 self .log_notice ("Starting..." )
1233- print ("Starting" )
12341284
12351285 # APPL_DB for CONFIG updates, and STATE_DB for insertion/removal
12361286 sel , asic_context = port_mapping .subscribe_port_update_event (self .namespaces )
@@ -1309,6 +1359,12 @@ def task_worker(self):
13091359 if (type is None ) or (type not in self .CMIS_MODULE_TYPES ):
13101360 self .port_dict [lport ]['cmis_state' ] = self .CMIS_STATE_READY
13111361 continue
1362+
1363+ if api .is_coherent_module ():
1364+ if 'tx_power' not in self .port_dict [lport ]:
1365+ self .port_dict [lport ]['tx_power' ] = self .get_configured_tx_power_from_db (lport )
1366+ if 'laser_freq' not in self .port_dict [lport ]:
1367+ self .port_dict [lport ]['laser_freq' ] = self .get_configured_laser_freq_from_db (lport )
13121368 except AttributeError :
13131369 # Skip if these essential routines are not available
13141370 self .port_dict [lport ]['cmis_state' ] = self .CMIS_STATE_READY
@@ -1339,20 +1395,38 @@ def task_worker(self):
13391395 api .tx_disable_channel (host_lanes , True )
13401396 self .port_dict [lport ]['cmis_state' ] = self .CMIS_STATE_READY
13411397 continue
1398+ # Configure the target output power if ZR module
1399+ if api .is_coherent_module ():
1400+ tx_power = self .port_dict [lport ]['tx_power' ]
1401+ # Prevent configuring same tx power multiple times
1402+ if 0 != tx_power and tx_power != api .get_tx_config_power ():
1403+ if 1 != self .configure_tx_output_power (api , lport , tx_power ):
1404+ self .log_error ("{} failed to configure Tx power = {}" .format (lport , tx_power ))
1405+ else :
1406+ self .log_notice ("{} Successfully configured Tx power = {}" .format (lport , tx_power ))
13421407
13431408 appl = self .get_cmis_application_desired (api , host_lanes , host_speed )
13441409 if appl < 1 :
13451410 self .log_error ("{}: no suitable app for the port" .format (lport ))
13461411 self .port_dict [lport ]['cmis_state' ] = self .CMIS_STATE_FAILED
13471412 continue
13481413
1349- has_update = self .is_cmis_application_update_required (api , host_lanes , host_speed )
1350- if not has_update :
1414+ need_update = self .is_cmis_application_update_required (api , host_lanes , host_speed )
1415+
1416+ # For ZR module, Datapath needes to be re-initlialized on new channel selection
1417+ if api .is_coherent_module ():
1418+ freq = self .port_dict [lport ]['laser_freq' ]
1419+ # If user requested frequency is NOT the same as configured on the module
1420+ # force datapath re-initialization
1421+ if 0 != freq and freq != api .get_laser_config_freq ():
1422+ need_update = True
1423+
1424+ if not need_update :
13511425 # No application updates
13521426 self .log_notice ("{}: no CMIS application update required...READY" .format (lport ))
13531427 self .port_dict [lport ]['cmis_state' ] = self .CMIS_STATE_READY
13541428 continue
1355-
1429+ self . log_notice ( "{}: force Datapath reinit" . format ( lport ))
13561430 self .port_dict [lport ]['cmis_state' ] = self .CMIS_STATE_DP_DEINIT
13571431 elif state == self .CMIS_STATE_DP_DEINIT :
13581432 # D.2.2 Software Deinitialization
@@ -1382,6 +1456,15 @@ def task_worker(self):
13821456 self .force_cmis_reinit (lport , retries + 1 )
13831457 continue
13841458
1459+ if api .is_coherent_module ():
1460+ # For ZR module, configure the laser frequency when Datapath is in Deactivated state
1461+ freq = self .port_dict [lport ]['laser_freq' ]
1462+ if 0 != freq :
1463+ if 1 != self .configure_laser_frequency (api , lport , freq ):
1464+ self .log_error ("{} failed to configure laser frequency {} GHz" .format (lport , freq ))
1465+ else :
1466+ self .log_notice ("{} configured laser frequency {} GHz" .format (lport , freq ))
1467+
13851468 # D.1.3 Software Configuration and Initialization
13861469 appl = self .get_cmis_application_desired (api , host_lanes , host_speed )
13871470 if appl < 1 :
@@ -2080,7 +2163,7 @@ def init(self):
20802163 if multi_asic .is_multi_asic ():
20812164 # Load the namespace details first from the database_global.json file.
20822165 swsscommon .SonicDBConfig .initializeGlobalConfig ()
2083- # To prevent race condition in get_all_namespaces() we cache the namespaces before
2166+ # To prevent race condition in get_all_namespaces() we cache the namespaces before
20842167 # creating any worker threads
20852168 self .namespaces = multi_asic .get_front_end_namespaces ()
20862169
0 commit comments