40
40
except ImportError as e :
41
41
raise ImportError (str (e ) + "- required module not found" )
42
42
43
- try :
44
- # python_sdk_api does not support python3 for now. Daemons like thermalctld or psud
45
- # also import this file without actually use the sdk lib. So we catch the ImportError
46
- # and ignore it here. Meanwhile, we have to trigger xcvrd using python2 now because it
47
- # uses the sdk lib.
48
- from python_sdk_api .sxd_api import *
49
- from python_sdk_api .sx_api import *
50
- except ImportError as e :
51
- pass
52
-
53
43
# Define the sdk constants
54
44
SX_PORT_MODULE_STATUS_INITIALIZING = 0
55
45
SX_PORT_MODULE_STATUS_PLUGGED = 1
56
46
SX_PORT_MODULE_STATUS_UNPLUGGED = 2
57
47
SX_PORT_MODULE_STATUS_PLUGGED_WITH_ERROR = 3
58
48
SX_PORT_MODULE_STATUS_PLUGGED_DISABLED = 4
59
49
60
- try :
61
- if os .environ ["PLATFORM_API_UNIT_TESTING" ] == "1" :
62
- # Unable to import SDK constants under unit test
63
- # Define them here
64
- SX_PORT_ADMIN_STATUS_UP = True
65
- SX_PORT_ADMIN_STATUS_DOWN = False
66
- except KeyError :
67
- pass
68
-
69
50
# identifier value of xSFP module which is in the first byte of the EEPROM
70
51
# if the identifier value falls into SFP_TYPE_CODE_LIST the module is treated as a SFP module and parsed according to 8472
71
52
# for QSFP_TYPE_CODE_LIST the module is treated as a QSFP module and parsed according to 8436/8636
185
166
SFP_SYSFS_POWER_MODE = 'power_mode'
186
167
SFP_SYSFS_POWER_MODE_POLICY = 'power_mode_policy'
187
168
POWER_MODE_POLICY_HIGH = 1
188
- POWER_MODE_POLICY_AUTO = 2
169
+ POWER_MODE_POLICY_LOW = 3
189
170
POWER_MODE_LOW = 1
190
171
# POWER_MODE_HIGH = 2 # not used
191
172
288
269
logger = Logger ()
289
270
290
271
291
- # SDK initializing stuff, called from chassis
292
- def initialize_sdk_handle ():
293
- rc , sdk_handle = sx_api_open (None )
294
- if (rc != SX_STATUS_SUCCESS ):
295
- logger .log_warning ("Failed to open api handle, please check whether SDK is running." )
296
- sdk_handle = None
297
-
298
- return sdk_handle
299
-
300
-
301
- def deinitialize_sdk_handle (sdk_handle ):
302
- if sdk_handle is not None :
303
- rc = sx_api_close (sdk_handle )
304
- if (rc != SX_STATUS_SUCCESS ):
305
- logger .log_warning ("Failed to close api handle." )
306
-
307
- return rc == SXD_STATUS_SUCCESS
308
- else :
309
- logger .log_warning ("Sdk handle is none" )
310
- return False
311
-
312
- class SdkHandleContext (object ):
313
- def __init__ (self ):
314
- self .sdk_handle = None
315
-
316
- def __enter__ (self ):
317
- self .sdk_handle = initialize_sdk_handle ()
318
- return self .sdk_handle
319
-
320
- def __exit__ (self , exc_type , exc_val , exc_tb ):
321
- deinitialize_sdk_handle (self .sdk_handle )
322
-
323
272
class NvidiaSFPCommon (SfpOptoeBase ):
324
273
sfp_index_to_logical_port_dict = {}
325
274
sfp_index_to_logical_lock = threading .Lock ()
@@ -361,14 +310,6 @@ def __init__(self, sfp_index):
361
310
self .index = sfp_index + 1
362
311
self .sdk_index = sfp_index
363
312
364
- @property
365
- def sdk_handle (self ):
366
- if not SFP .shared_sdk_handle :
367
- SFP .shared_sdk_handle = initialize_sdk_handle ()
368
- if not SFP .shared_sdk_handle :
369
- logger .log_error ('Failed to open SDK handle' )
370
- return SFP .shared_sdk_handle
371
-
372
313
@classmethod
373
314
def _get_module_info (self , sdk_index ):
374
315
"""
@@ -620,24 +561,6 @@ def write_eeprom(self, offset, num_bytes, write_buffer):
620
561
return False
621
562
return True
622
563
623
- @classmethod
624
- def mgmt_phy_mod_pwr_attr_get (cls , power_attr_type , sdk_handle , sdk_index , slot_id ):
625
- sx_mgmt_phy_mod_pwr_attr_p = new_sx_mgmt_phy_mod_pwr_attr_t_p ()
626
- sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t ()
627
- sx_mgmt_phy_mod_pwr_attr .power_attr_type = power_attr_type
628
- sx_mgmt_phy_mod_pwr_attr_t_p_assign (sx_mgmt_phy_mod_pwr_attr_p , sx_mgmt_phy_mod_pwr_attr )
629
- module_id_info = sx_mgmt_module_id_info_t ()
630
- module_id_info .slot_id = slot_id
631
- module_id_info .module_id = sdk_index
632
- try :
633
- rc = sx_mgmt_phy_module_pwr_attr_get (sdk_handle , module_id_info , sx_mgmt_phy_mod_pwr_attr_p )
634
- assert SX_STATUS_SUCCESS == rc , "sx_mgmt_phy_module_pwr_attr_get failed {}" .format (rc )
635
- sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t_p_value (sx_mgmt_phy_mod_pwr_attr_p )
636
- pwr_mode_attr = sx_mgmt_phy_mod_pwr_attr .pwr_mode_attr
637
- return pwr_mode_attr .admin_pwr_mode_e , pwr_mode_attr .oper_pwr_mode_e
638
- finally :
639
- delete_sx_mgmt_phy_mod_pwr_attr_t_p (sx_mgmt_phy_mod_pwr_attr_p )
640
-
641
564
def get_lpmode (self ):
642
565
"""
643
566
Retrieves the lpmode (low power mode) status of this SFP
@@ -649,44 +572,13 @@ def get_lpmode(self):
649
572
if self .is_sw_control ():
650
573
api = self .get_xcvr_api ()
651
574
return api .get_lpmode () if api else False
652
- elif DeviceDataManager .is_module_host_management_mode ():
653
- file_path = SFP_SDK_MODULE_SYSFS_ROOT_TEMPLATE .format (self .sdk_index ) + SFP_SYSFS_POWER_MODE
654
- power_mode = utils .read_int_from_file (file_path )
655
- return power_mode == POWER_MODE_LOW
656
575
except Exception as e :
657
576
print (e )
658
577
return False
659
578
660
- if utils .is_host ():
661
- # To avoid performance issue,
662
- # call class level method to avoid initialize the whole sonic platform API
663
- get_lpmode_code = 'from sonic_platform import sfp;\n ' \
664
- 'with sfp.SdkHandleContext() as sdk_handle:' \
665
- 'print(sfp.SFP._get_lpmode(sdk_handle, {}, {}))' .format (self .sdk_index , self .slot_id )
666
- lpm_cmd = ["docker" , "exec" , "pmon" , "python3" , "-c" , get_lpmode_code ]
667
- try :
668
- output = subprocess .check_output (lpm_cmd , universal_newlines = True )
669
- return 'True' in output
670
- except subprocess .CalledProcessError as e :
671
- print ("Error! Unable to get LPM for {}, rc = {}, err msg: {}" .format (self .sdk_index , e .returncode , e .output ))
672
- return False
673
- else :
674
- return self ._get_lpmode (self .sdk_handle , self .sdk_index , self .slot_id )
675
-
676
- @classmethod
677
- def _get_lpmode (cls , sdk_handle , sdk_index , slot_id ):
678
- """Class level method to get low power mode.
679
-
680
- Args:
681
- sdk_handle: SDK handle
682
- sdk_index (integer): SDK port index
683
- slot_id (integer): Slot ID
684
-
685
- Returns:
686
- [boolean]: True if low power mode is on else off
687
- """
688
- _ , oper_pwr_mode = cls .mgmt_phy_mod_pwr_attr_get (SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E , sdk_handle , sdk_index , slot_id )
689
- return oper_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E
579
+ file_path = SFP_SDK_MODULE_SYSFS_ROOT_TEMPLATE .format (self .sdk_index ) + SFP_SYSFS_POWER_MODE
580
+ power_mode = utils .read_int_from_file (file_path )
581
+ return power_mode == POWER_MODE_LOW
690
582
691
583
def reset (self ):
692
584
"""
@@ -709,128 +601,6 @@ def reset(self):
709
601
logger .log_error (f'Failed to reset module - { e } ' )
710
602
return False
711
603
712
-
713
- @classmethod
714
- def is_nve (cls , port ):
715
- return (port & NVE_MASK ) != 0
716
-
717
-
718
- @classmethod
719
- def is_cpu (cls , port ):
720
- return (port & CPU_MASK ) != 0
721
-
722
-
723
- @classmethod
724
- def _fetch_port_status (cls , sdk_handle , log_port ):
725
- oper_state_p = new_sx_port_oper_state_t_p ()
726
- admin_state_p = new_sx_port_admin_state_t_p ()
727
- module_state_p = new_sx_port_module_state_t_p ()
728
- rc = sx_api_port_state_get (sdk_handle , log_port , oper_state_p , admin_state_p , module_state_p )
729
- assert rc == SXD_STATUS_SUCCESS , "sx_api_port_state_get failed, rc = %d" % rc
730
-
731
- admin_state = sx_port_admin_state_t_p_value (admin_state_p )
732
- oper_state = sx_port_oper_state_t_p_value (oper_state_p )
733
-
734
- delete_sx_port_oper_state_t_p (oper_state_p )
735
- delete_sx_port_admin_state_t_p (admin_state_p )
736
- delete_sx_port_module_state_t_p (module_state_p )
737
-
738
- return oper_state , admin_state
739
-
740
-
741
- @classmethod
742
- def is_port_admin_status_up (cls , sdk_handle , log_port ):
743
- _ , admin_state = cls ._fetch_port_status (sdk_handle , log_port );
744
- return admin_state == SX_PORT_ADMIN_STATUS_UP
745
-
746
-
747
- @classmethod
748
- def set_port_admin_status_by_log_port (cls , sdk_handle , log_port , admin_status ):
749
- rc = sx_api_port_state_set (sdk_handle , log_port , admin_status )
750
- if SX_STATUS_SUCCESS != rc :
751
- logger .log_error ("sx_api_port_state_set failed, rc = %d" % rc )
752
-
753
- return SX_STATUS_SUCCESS == rc
754
-
755
-
756
- @classmethod
757
- def get_logical_ports (cls , sdk_handle , sdk_index , slot_id ):
758
- # Get all the ports related to the sfp, if port admin status is up, put it to list
759
- port_cnt_p = new_uint32_t_p ()
760
- uint32_t_p_assign (port_cnt_p , 0 )
761
- rc = sx_api_port_device_get (sdk_handle , DEVICE_ID , SWITCH_ID , None , port_cnt_p )
762
-
763
- assert rc == SX_STATUS_SUCCESS , "sx_api_port_device_get failed, rc = %d" % rc
764
- port_cnt = uint32_t_p_value (port_cnt_p )
765
- port_attributes_list = new_sx_port_attributes_t_arr (port_cnt )
766
-
767
- rc = sx_api_port_device_get (sdk_handle , DEVICE_ID , SWITCH_ID , port_attributes_list , port_cnt_p )
768
- assert rc == SX_STATUS_SUCCESS , "sx_api_port_device_get failed, rc = %d" % rc
769
-
770
- port_cnt = uint32_t_p_value (port_cnt_p )
771
- log_port_list = []
772
- for i in range (0 , port_cnt ):
773
- port_attributes = sx_port_attributes_t_arr_getitem (port_attributes_list , i )
774
- if not cls .is_nve (int (port_attributes .log_port )) \
775
- and not cls .is_cpu (int (port_attributes .log_port )) \
776
- and port_attributes .port_mapping .module_port == sdk_index \
777
- and port_attributes .port_mapping .slot == slot_id \
778
- and cls .is_port_admin_status_up (sdk_handle , port_attributes .log_port ):
779
- log_port_list .append (port_attributes .log_port )
780
-
781
- delete_sx_port_attributes_t_arr (port_attributes_list )
782
- delete_uint32_t_p (port_cnt_p )
783
- return log_port_list
784
-
785
-
786
- @classmethod
787
- def mgmt_phy_mod_pwr_attr_set (cls , sdk_handle , sdk_index , slot_id , power_attr_type , admin_pwr_mode ):
788
- result = False
789
- sx_mgmt_phy_mod_pwr_attr = sx_mgmt_phy_mod_pwr_attr_t ()
790
- sx_mgmt_phy_mod_pwr_mode_attr = sx_mgmt_phy_mod_pwr_mode_attr_t ()
791
- sx_mgmt_phy_mod_pwr_attr .power_attr_type = power_attr_type
792
- sx_mgmt_phy_mod_pwr_mode_attr .admin_pwr_mode_e = admin_pwr_mode
793
- sx_mgmt_phy_mod_pwr_attr .pwr_mode_attr = sx_mgmt_phy_mod_pwr_mode_attr
794
- sx_mgmt_phy_mod_pwr_attr_p = new_sx_mgmt_phy_mod_pwr_attr_t_p ()
795
- sx_mgmt_phy_mod_pwr_attr_t_p_assign (sx_mgmt_phy_mod_pwr_attr_p , sx_mgmt_phy_mod_pwr_attr )
796
- module_id_info = sx_mgmt_module_id_info_t ()
797
- module_id_info .slot_id = slot_id
798
- module_id_info .module_id = sdk_index
799
- try :
800
- rc = sx_mgmt_phy_module_pwr_attr_set (sdk_handle , SX_ACCESS_CMD_SET , module_id_info , sx_mgmt_phy_mod_pwr_attr_p )
801
- if SX_STATUS_SUCCESS != rc :
802
- logger .log_error ("Error occurred when setting power mode for SFP module {}, slot {}, error code {}" .format (sdk_index , slot_id , rc ))
803
- result = False
804
- else :
805
- result = True
806
- finally :
807
- delete_sx_mgmt_phy_mod_pwr_attr_t_p (sx_mgmt_phy_mod_pwr_attr_p )
808
-
809
- return result
810
-
811
-
812
- @classmethod
813
- def _set_lpmode_raw (cls , sdk_handle , sdk_index , slot_id , ports , attr_type , power_mode ):
814
- result = False
815
- # Check if the module already works in the same mode
816
- admin_pwr_mode , oper_pwr_mode = cls .mgmt_phy_mod_pwr_attr_get (attr_type , sdk_handle , sdk_index , slot_id )
817
- if (power_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E and oper_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_LOW_E ) \
818
- or (power_mode == SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E and admin_pwr_mode == SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E ):
819
- return True
820
- try :
821
- # Bring the port down
822
- for port in ports :
823
- cls .set_port_admin_status_by_log_port (sdk_handle , port , SX_PORT_ADMIN_STATUS_DOWN )
824
- # Set the desired power mode
825
- result = cls .mgmt_phy_mod_pwr_attr_set (sdk_handle , sdk_index , slot_id , attr_type , power_mode )
826
- finally :
827
- # Bring the port up
828
- for port in ports :
829
- cls .set_port_admin_status_by_log_port (sdk_handle , port , SX_PORT_ADMIN_STATUS_UP )
830
-
831
- return result
832
-
833
-
834
604
def set_lpmode (self , lpmode ):
835
605
"""
836
606
Sets the lpmode (low power mode) of SFP
@@ -856,47 +626,16 @@ def set_lpmode(self, lpmode):
856
626
# If at some point get_lpmode=desired_lpmode, it will return true.
857
627
# If after timeout ends, lpmode will not be desired_lpmode, it will return false.
858
628
return utils .wait_until (check_lpmode , 2 , 1 , api = api , lpmode = lpmode )
859
- elif DeviceDataManager .is_module_host_management_mode ():
860
- # FW control under CMIS host management mode.
861
- # Currently, we don't support set LPM under this mode.
862
- # Just return False to indicate set Fail
863
- return False
864
629
except Exception as e :
865
630
print (e )
866
631
return False
867
632
868
- if utils .is_host ():
869
- # To avoid performance issue,
870
- # call class level method to avoid initialize the whole sonic platform API
871
- set_lpmode_code = 'from sonic_platform import sfp;\n ' \
872
- 'with sfp.SdkHandleContext() as sdk_handle:' \
873
- 'print(sfp.SFP._set_lpmode({}, sdk_handle, {}, {}))' \
874
- .format ('True' if lpmode else 'False' , self .sdk_index , self .slot_id )
875
- lpm_cmd = ["docker" , "exec" , "pmon" , "python3" , "-c" , set_lpmode_code ]
876
-
877
- # Set LPM
878
- try :
879
- output = subprocess .check_output (lpm_cmd , universal_newlines = True )
880
- return 'True' in output
881
- except subprocess .CalledProcessError as e :
882
- print ("Error! Unable to set LPM for {}, rc = {}, err msg: {}" .format (self .sdk_index , e .returncode , e .output ))
883
- return False
884
- else :
885
- return self ._set_lpmode (lpmode , self .sdk_handle , self .sdk_index , self .slot_id )
886
-
887
-
888
- @classmethod
889
- def _set_lpmode (cls , lpmode , sdk_handle , sdk_index , slot_id ):
890
- log_port_list = cls .get_logical_ports (sdk_handle , sdk_index , slot_id )
891
- sdk_lpmode = SX_MGMT_PHY_MOD_PWR_MODE_LOW_E if lpmode else SX_MGMT_PHY_MOD_PWR_MODE_AUTO_E
892
- cls ._set_lpmode_raw (sdk_handle ,
893
- sdk_index ,
894
- slot_id ,
895
- log_port_list ,
896
- SX_MGMT_PHY_MOD_PWR_ATTR_PWR_MODE_E ,
897
- sdk_lpmode )
898
- logger .log_info ("{} low power mode for module {}, slot {}" .format ("Enabled" if lpmode else "Disabled" , sdk_index , slot_id ))
899
- return True
633
+ file_path = SFP_SDK_MODULE_SYSFS_ROOT_TEMPLATE .format (self .sdk_index ) + SFP_SYSFS_POWER_MODE_POLICY
634
+ target_admin_mode = POWER_MODE_POLICY_LOW if lpmode else POWER_MODE_POLICY_HIGH
635
+ current_admin_mode = utils .read_int_from_file (file_path )
636
+ if current_admin_mode == target_admin_mode :
637
+ return True
638
+ return utils .write_file (file_path , str (target_admin_mode ))
900
639
901
640
def is_replaceable (self ):
902
641
"""
0 commit comments